From df3fcec296799b07ba1d292c8f63db036e1b4e6f Mon Sep 17 00:00:00 2001 From: Marc Guasch Date: Thu, 18 Nov 2021 09:27:51 +0100 Subject: [PATCH 001/172] [filebeat][s3] Add custom parsing script for S3 notifications (#28946) * Add custom parsing script for S3 notifications * Remove unnecessary custom jsmapstr type. It can be used as a regular JS map since its only purpose is to be read. * add docs and changelog entry * Remove commented code * Document script options restriction * Better error if Records are missing in notification * Fix test * Pass notification as string and add xml parsing options for the scripts --- CHANGELOG.next.asciidoc | 2 + .../docs/inputs/input-aws-s3.asciidoc | 255 ++++++++++++++ x-pack/filebeat/input/awss3/config.go | 31 ++ x-pack/filebeat/input/awss3/input.go | 6 +- .../input/awss3/input_benchmark_test.go | 2 +- x-pack/filebeat/input/awss3/script.go | 150 +++++++++ .../input/awss3/script_jss3event_v2.go | 69 ++++ .../input/awss3/script_jss3event_v2_test.go | 60 ++++ x-pack/filebeat/input/awss3/script_session.go | 217 ++++++++++++ .../input/awss3/script_session_test.go | 317 ++++++++++++++++++ x-pack/filebeat/input/awss3/sqs_s3_event.go | 16 +- .../filebeat/input/awss3/sqs_s3_event_test.go | 34 +- 12 files changed, 1148 insertions(+), 11 deletions(-) create mode 100644 x-pack/filebeat/input/awss3/script.go create mode 100644 x-pack/filebeat/input/awss3/script_jss3event_v2.go create mode 100644 x-pack/filebeat/input/awss3/script_jss3event_v2_test.go create mode 100644 x-pack/filebeat/input/awss3/script_session.go create mode 100644 x-pack/filebeat/input/awss3/script_session_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index dcd03b0ee705..bd473812131c 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -336,6 +336,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support for '/var/log/pods/' path for add_kubernetes_metadata processor with `resource_type: pod`. {pull}28868[28868] - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support in aws-s3 input for s3 notification from SNS to SQS. {pull}28800[28800] +- Add support in aws-s3 input for custom script parsing of s3 notifications. {pull}28946[28946] +- Improve error handling in aws-s3 input for malformed s3 notifications. {issue}28828[28828] {pull}28946[28946] *Heartbeat* diff --git a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc index 696a7368e3f8..ec7a16cd67b3 100644 --- a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc @@ -282,6 +282,90 @@ attribute. The default value is 5. If you have configured a dead letter queue then you can set this value to `-1` to disable deletion on failure. +[float] +==== `sqs.notification_parsing_script.source` + +Inline Javascript source code. + +[source,yaml] +---- +sqs.notification_parsing_script.source: > + function parse(notification) { + var evts = []; + var evt = new S3EventV2(); + evt.SetS3BucketName(notification.bucket); + evt.SetS3ObjectKey(notification.path); + evts.push(evt); + return evts; + } +---- + +[float] +==== `sqs.notification_parsing_script.file` + +Path to a script file to load. Relative paths are interpreted as +relative to the `path.config` directory. Globs are expanded. + +This loads `filter.js` from disk. + +[source,yaml] +---- +sqs.notification_parsing_script.file: ${path.config}/filter.js +---- + +[float] +==== `sqs.notification_parsing_script.files` + +List of script files to load. The scripts are concatenated together. +Relative paths are interpreted as relative to the `path.config` directory. +And globs are expanded. + +[float] +==== `sqs.notification_parsing_script.params` + +A dictionary of parameters that are passed to the `register` of the +script. + +Parameters can be passed to the script by adding `params` to the config. +This allows for a script to be made reusable. When using `params` the +code must define a `register(params)` function to receive the parameters. + +[source,yaml] +---- +sqs.notification_parsing_script: + params: + provider: aws:s3 + source: > + var params = {provider: ""}; + function register(scriptParams) { + params = scriptParams; + } + function parse(notification) { + var evts = []; + var evt = new S3EventV2(); + evt.SetS3BucketName(notification.bucket); + evt.SetS3ObjectKey(notification.path); + evt.SetProvider(params.provider); + evts.push(evt); + return evts; + } +---- + +[float] +==== `sqs.notification_parsing_script.timeout` + +This sets an execution timeout for the `process` function. When +the `process` function takes longer than the `timeout` period the function +is interrupted. You can set this option to prevent a script from running for +too long (like preventing an infinite `while` loop). By default there is no +timeout. + +[float] +==== `sqs.notification_parsing_script.max_cached_sessions` + +This sets the maximum number of Javascript VM sessions +that will be cached to avoid reallocation. + [float] ==== `sqs.wait_time` @@ -426,6 +510,177 @@ Therefore, when using the polling list of S3 bucket objects method, scaling shou vertical, with a single bigger {beatname_uc} instance and higher `number_of_workers` config value. +[float] +=== SQS Custom Notification Parsing Script + +Under some circumstances you might want to listen to events that are not following +the standard SQS notifications format. To be able to parse them, it is possible to +define a custom script that will take care of processing them and generating the +required list of S3 Events used to download the files. + +The `sqs.notification_parsing_script` executes Javascript code to process an event. +It uses a pure Go implementation of ECMAScript 5.1 and has no external dependencies. + +It can be configured by embedding Javascript in your configuration file or by pointing +the processor at external file(s). Only one of the options `sqs.notification_parsing_script.source`, `sqs.notification_parsing_script.file`, and `sqs.notification_parsing_script.files` +can be set at the same time. + +The script requires a `parse(notification)` function that receives the notification as +a raw string and returns a list of `S3EventV2` objects. This raw string can then be +processed as needed, e.g.: `JSON.parse(n)` or the provided helper for XML `new XMLDecoder(n)`. + +If the script defines a `test()` function it will be invoked when it is loaded. Any exceptions thrown will cause the processor to fail to load. This can be used to make assertions about the behavior of the script. + +[source,javascript] +---- +function parse(n) { + var m = JSON.parse(n); + var evts = []; + var files = m.files; + var bucket = m.bucket; + + if (!Array.isArray(files) || (files.length == 0) || bucket == null || bucket == "") { + return evts; + } + + files.forEach(function(f){ + var evt = new S3EventV2(); + evt.SetS3BucketName(bucket); + evt.SetS3ObjectKey(f.path); + evts.push(evt); + }); + + return evts; +} + +function test() { + var events = parse({bucket: "aBucket", files: [{path: "path/to/file"}]}); + if (events.length !== 1) { + throw "expecting one event"; + } + if (events[0].S3.Bucket.Name === "aBucket") { + throw "expected bucket === aBucket"; + } + if (events[0].S3.Object.Key === "path/to/file") { + throw "expected bucket === path/to/file"; + } +} +---- + +[float] +==== S3EventV2 API + +The `S3EventV2` object returned by the `parse` method. + +[frame="topbot",options="header"] +|=== +|Method |Description + +|`new S3EventV2()` +|Returns a new `S3EventV2` object. + +*Example*: `var evt = new S3EventV2();` + +|`SetAWSRegion(string)` +|Sets the AWS region. + +*Example*: `evt.SetAWSRegion("us-east-1");` + +|`SetProvider(string)` +|Sets the provider. + +*Example*: `evt.SetProvider("provider");` + +|`SetEventName(string)` +|Sets the event name. + +*Example*: `evt.SetEventName("event-type");` + +|`SetEventSource(string)` +|Sets the event surce. + +*Example*: `evt.SetEventSource("aws:s3");` + +|`SetS3BucketName(string)` +|Sets the bucket name. + +*Example*: `evt.SetS3BucketName("bucket-name");` + +|`SetS3BucketARN(string)` +|Sets the bucket ARN. + +*Example*: `evt.SetS3BucketARN("bucket-ARN");` + +|`SetS3ObjectKey(string)` +|Sets the object key. + +*Example*: `evt.SetS3ObjectKey("path/to/object");` + +|=== + +In order to be able to retrieve an S3 object successfully, at least `S3.Object.Key` +and `S3.Bucket.Name` properties must be set (using the provided setters). The other +properties will be used as metadata in the resulting event when available. + +[float] +==== XMLDecoder API + +To help with XML decoding, an `XMLDecoder` class is provided. + +Example XML input: + +[source,xml] +------------------------------------------------------------------------------- + + + William H. Gaddis + The Recognitions + One of the great seminal American novels of the 20th century. + + +------------------------------------------------------------------------------- + +Will produce the following output: + +[source,json] +------------------------------------------------------------------------------- +{ + "catalog": { + "book": { + "author": "William H. Gaddis", + "review": "One of the great seminal American novels of the 20th century.", + "seq": "1", + "title": "The Recognitions" + } + } +} +------------------------------------------------------------------------------- + +[frame="topbot",options="header"] +|=== +|Method |Description + +|`new XMLDecoder(string)` +|Returns a new `XMLDecoder` object to decode the provided `string`. + +*Example*: `var dec = new XMLDecoder(n);` + +|`PrependHyphenToAttr()` +|Causes the Decoder to prepend a hyphen (`-`) to to all XML attribute names. + +*Example*: `dec.PrependHyphenToAttr();` + +|`LowercaseKeys()` +|Causes the Decoder to transform all key name to lowercase. + +*Example*: `dec.LowercaseKeys();` + +|`Decode()` +|Reads the XML string and return a map containing the data. + +*Example*: `var m = dec.Decode();` + +|=== [float] === Metrics diff --git a/x-pack/filebeat/input/awss3/config.go b/x-pack/filebeat/input/awss3/config.go index 5b8308d1771e..d25b99a69bdf 100644 --- a/x-pack/filebeat/input/awss3/config.go +++ b/x-pack/filebeat/input/awss3/config.go @@ -24,6 +24,7 @@ type config struct { VisibilityTimeout time.Duration `config:"visibility_timeout"` SQSWaitTime time.Duration `config:"sqs.wait_time"` // The max duration for which the SQS ReceiveMessage call waits for a message to arrive in the queue before returning. SQSMaxReceiveCount int `config:"sqs.max_receive_count"` // The max number of times a message should be received (retried) before deleting it. + SQSScript *scriptConfig `config:"sqs.notification_parsing_script"` FIPSEnabled bool `config:"fips_enabled"` MaxNumberOfMessages int `config:"max_number_of_messages"` QueueURL string `config:"queue_url"` @@ -151,6 +152,36 @@ func (rc *readerConfig) Validate() error { return nil } +type scriptConfig struct { + Source string `config:"source"` // Inline script to execute. + File string `config:"file"` // Source file. + Files []string `config:"files"` // Multiple source files. + Params map[string]interface{} `config:"params"` // Parameters to pass to script. + Timeout time.Duration `config:"timeout" validate:"min=0"` // Execution timeout. + MaxCachedSessions int `config:"max_cached_sessions" validate:"min=0"` // Max. number of cached VM sessions. +} + +// Validate returns an error if one (and only one) option is not set. +func (c scriptConfig) Validate() error { + numConfigured := 0 + for _, set := range []bool{c.Source != "", c.File != "", len(c.Files) > 0} { + if set { + numConfigured++ + } + } + + switch { + case numConfigured == 0: + return errors.New("javascript must be defined via 'file', " + + "'files', or inline as 'source'") + case numConfigured > 1: + return errors.New("javascript can be defined in only one of " + + "'file', 'files', or inline as 'source'") + } + + return nil +} + func (rc *readerConfig) InitDefaults() { rc.BufferSize = 16 * humanize.KiByte rc.MaxBytes = 10 * humanize.MiByte diff --git a/x-pack/filebeat/input/awss3/input.go b/x-pack/filebeat/input/awss3/input.go index edd146b6a23e..bf3f8cf28b24 100644 --- a/x-pack/filebeat/input/awss3/input.go +++ b/x-pack/filebeat/input/awss3/input.go @@ -186,8 +186,12 @@ func (in *s3Input) createSQSReceiver(ctx v2.Context, client beat.Client) (*sqsRe if len(in.config.FileSelectors) == 0 { fileSelectors = []fileSelectorConfig{{ReaderConfig: in.config.ReaderConfig}} } + script, err := newScriptFromConfig(log.Named("sqs_script"), in.config.SQSScript) + if err != nil { + return nil, err + } s3EventHandlerFactory := newS3ObjectProcessorFactory(log.Named("s3"), metrics, s3API, client, fileSelectors) - sqsMessageHandler := newSQSS3EventProcessor(log.Named("sqs_s3_event"), metrics, sqsAPI, in.config.VisibilityTimeout, in.config.SQSMaxReceiveCount, s3EventHandlerFactory) + sqsMessageHandler := newSQSS3EventProcessor(log.Named("sqs_s3_event"), metrics, sqsAPI, script, in.config.VisibilityTimeout, in.config.SQSMaxReceiveCount, s3EventHandlerFactory) sqsReader := newSQSReader(log.Named("sqs"), metrics, sqsAPI, in.config.MaxNumberOfMessages, sqsMessageHandler) return sqsReader, nil diff --git a/x-pack/filebeat/input/awss3/input_benchmark_test.go b/x-pack/filebeat/input/awss3/input_benchmark_test.go index aabb86b1a6c8..ecdc1756ce4a 100644 --- a/x-pack/filebeat/input/awss3/input_benchmark_test.go +++ b/x-pack/filebeat/input/awss3/input_benchmark_test.go @@ -166,7 +166,7 @@ func benchmarkInputSQS(t *testing.T, maxMessagesInflight int) testing.BenchmarkR conf := makeBenchmarkConfig(t) s3EventHandlerFactory := newS3ObjectProcessorFactory(log.Named("s3"), metrics, s3API, client, conf.FileSelectors) - sqsMessageHandler := newSQSS3EventProcessor(log.Named("sqs_s3_event"), metrics, sqsAPI, time.Minute, 5, s3EventHandlerFactory) + sqsMessageHandler := newSQSS3EventProcessor(log.Named("sqs_s3_event"), metrics, sqsAPI, nil, time.Minute, 5, s3EventHandlerFactory) sqsReader := newSQSReader(log.Named("sqs"), metrics, sqsAPI, maxMessagesInflight, sqsMessageHandler) go func() { diff --git a/x-pack/filebeat/input/awss3/script.go b/x-pack/filebeat/input/awss3/script.go new file mode 100644 index 000000000000..812fbe65dc59 --- /dev/null +++ b/x-pack/filebeat/input/awss3/script.go @@ -0,0 +1,150 @@ +// 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 awss3 + +import ( + "bytes" + "io" + "os" + "path/filepath" + "runtime" + "strings" + + "github.com/dop251/goja" + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/paths" +) + +type script struct { + scriptConfig + sessionPool *sessionPool + sourceProg *goja.Program + sourceFile string +} + +// newScriptFromConfig constructs a new Javascript script from the given config +// object. It loads the sources, compiles them, and validates the entry point. +func newScriptFromConfig(log *logp.Logger, c *scriptConfig) (*script, error) { + if c == nil { + return nil, nil + } + err := c.Validate() + if err != nil { + return nil, err + } + + var sourceFile string + var sourceCode []byte + + switch { + case c.Source != "": + sourceFile = "inline.js" + sourceCode = []byte(c.Source) + case c.File != "": + sourceFile, sourceCode, err = loadSources(c.File) + case len(c.Files) > 0: + sourceFile, sourceCode, err = loadSources(c.Files...) + } + if err != nil { + return nil, err + } + + // Validate processor source code. + prog, err := goja.Compile(sourceFile, string(sourceCode), true) + if err != nil { + return nil, err + } + + pool, err := newSessionPool(prog, *c) + if err != nil { + return nil, err + } + + return &script{ + scriptConfig: *c, + sessionPool: pool, + sourceProg: prog, + sourceFile: sourceFile, + }, nil +} + +// loadSources loads javascript source from files. +func loadSources(files ...string) (string, []byte, error) { + var sources []string + buf := new(bytes.Buffer) + + readFile := func(path string) error { + if common.IsStrictPerms() { + if err := common.OwnerHasExclusiveWritePerms(path); err != nil { + return err + } + } + + f, err := os.Open(path) + if err != nil { + return errors.Wrapf(err, "failed to open file %v", path) + } + defer f.Close() + + if _, err = io.Copy(buf, f); err != nil { + return errors.Wrapf(err, "failed to read file %v", path) + } + return nil + } + + for _, filePath := range files { + filePath = paths.Resolve(paths.Config, filePath) + + if hasMeta(filePath) { + matches, err := filepath.Glob(filePath) + if err != nil { + return "", nil, err + } + sources = append(sources, matches...) + } else { + sources = append(sources, filePath) + } + } + + if len(sources) == 0 { + return "", nil, errors.Errorf("no sources were found in %v", + strings.Join(files, ", ")) + } + + for _, name := range sources { + if err := readFile(name); err != nil { + return "", nil, err + } + } + + return strings.Join(sources, ";"), buf.Bytes(), nil +} + +// run runs the parse function. It receives a raw notification +// as a string and returns a list of S3 Events describing +// which files are going to be downloaded. +func (p *script) run(n string) ([]s3EventV2, error) { + s := p.sessionPool.Get() + defer p.sessionPool.Put(s) + + return s.runParseFunc(n) +} + +func (p *script) String() string { + return "script=[type=javascript, sources=" + p.sourceFile + "]" +} + +// hasMeta reports whether path contains any of the magic characters +// recognized by Match/Glob. +func hasMeta(path string) bool { + magicChars := `*?[` + if runtime.GOOS != "windows" { + magicChars = `*?[\` + } + return strings.ContainsAny(path, magicChars) +} diff --git a/x-pack/filebeat/input/awss3/script_jss3event_v2.go b/x-pack/filebeat/input/awss3/script_jss3event_v2.go new file mode 100644 index 000000000000..04cea00a08ba --- /dev/null +++ b/x-pack/filebeat/input/awss3/script_jss3event_v2.go @@ -0,0 +1,69 @@ +// 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 awss3 + +import ( + "strings" + + "github.com/dop251/goja" + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common/encoding/xml" +) + +func newJSS3EventV2Constructor(s *session) func(call goja.ConstructorCall) *goja.Object { + return func(call goja.ConstructorCall) *goja.Object { + if len(call.Arguments) != 0 { + panic(errors.New("Event constructor don't accept arguments")) + } + return s.vm.ToValue(&s3EventV2{}).(*goja.Object) + } +} + +func (e *s3EventV2) SetAWSRegion(v string) { + e.AWSRegion = v +} + +func (e *s3EventV2) SetProvider(v string) { + e.Provider = v +} + +func (e *s3EventV2) SetEventName(v string) { + e.EventName = v +} + +func (e *s3EventV2) SetEventSource(v string) { + e.EventSource = v +} + +func (e *s3EventV2) SetS3BucketName(v string) { + e.S3.Bucket.Name = v +} + +func (e *s3EventV2) SetS3BucketARN(v string) { + e.S3.Bucket.ARN = v +} + +func (e *s3EventV2) SetS3ObjectKey(v string) { + e.S3.Object.Key = v +} + +func newXMLDecoderConstructor(s *session) func(call goja.ConstructorCall) *goja.Object { + return func(call goja.ConstructorCall) *goja.Object { + if len(call.Arguments) != 1 { + panic(errors.New("Event constructor requires one argument")) + } + + a0 := call.Argument(0).Export() + s0, ok := a0.(string) + + if !ok { + panic(errors.Errorf("Event constructor requires a "+ + "string argument but got %T", a0)) + } + + return s.vm.ToValue(xml.NewDecoder(strings.NewReader(s0))).(*goja.Object) + } +} diff --git a/x-pack/filebeat/input/awss3/script_jss3event_v2_test.go b/x-pack/filebeat/input/awss3/script_jss3event_v2_test.go new file mode 100644 index 000000000000..dc387d95e335 --- /dev/null +++ b/x-pack/filebeat/input/awss3/script_jss3event_v2_test.go @@ -0,0 +1,60 @@ +// 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 awss3 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/elastic/beats/v7/libbeat/logp" +) + +const ( + header = `function parse(n) {` + footer = `}` +) + +var log = logp.NewLogger("test") + +func TestJSS3EventV2(t *testing.T) { + logp.TestingSetup() + + source := ` + var evts = []; + var evt = new S3EventV2(); + evt.SetAWSRegion("region"); + evt.SetProvider("provider"); + evt.SetEventName("name"); + evt.SetEventSource("source"); + evt.SetS3BucketName("bucket"); + evt.SetS3BucketARN("arn"); + evt.SetS3ObjectKey("key"); + evts.push(evt); + return evts; + ` + + p, err := newScriptFromConfig(log, &scriptConfig{Source: header + source + footer}) + if err != nil { + t.Fatal(err) + } + + evts, err := p.run(`{}`) + require.NoError(t, err) + require.Equal(t, 1, len(evts)) + + exp := s3EventV2{ + AWSRegion: "region", + Provider: "provider", + EventName: "name", + EventSource: "source", + } + exp.S3.Bucket.Name = "bucket" + exp.S3.Bucket.ARN = "arn" + exp.S3.Object.Key = "key" + + assert.EqualValues(t, exp, evts[0]) +} diff --git a/x-pack/filebeat/input/awss3/script_session.go b/x-pack/filebeat/input/awss3/script_session.go new file mode 100644 index 000000000000..aad0539665ed --- /dev/null +++ b/x-pack/filebeat/input/awss3/script_session.go @@ -0,0 +1,217 @@ +// 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 awss3 + +import ( + "fmt" + "reflect" + "time" + + "github.com/dop251/goja" + "github.com/pkg/errors" + "go.uber.org/zap" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/logp" +) + +const ( + logName = "awss3.script" + + entryPointFunction = "parse" + registerFunction = "register" + testFunction = "test" + + timeoutError = "javascript parser execution timeout" +) + +// session is a javascript runtime environment used throughout the life of +// the input instance. +type session struct { + vm *goja.Runtime + log *logp.Logger + parseFunc goja.Callable + timeout time.Duration +} + +func newSession(p *goja.Program, conf scriptConfig, test bool) (*session, error) { + // Create a logger + logger := logp.NewLogger(logName) + + // Setup JS runtime. + s := &session{ + vm: goja.New(), + log: logger, + timeout: conf.Timeout, + } + + // Register common.MapStr as being a simple map[string]interface{} for + // treatment within the JS VM. + s.vm.RegisterSimpleMapType(reflect.TypeOf(common.MapStr(nil)), + func(i interface{}) map[string]interface{} { + return map[string]interface{}(i.(common.MapStr)) + }, + ) + + // Register constructors for 'new S3EventV2' to enable creating them from the JS code. + s.vm.Set("S3EventV2", newJSS3EventV2Constructor(s)) + s.vm.Set("XMLDecoder", newXMLDecoderConstructor(s)) + + if _, err := s.vm.RunProgram(p); err != nil { + return nil, err + } + + if err := s.setParseFunction(); err != nil { + return nil, err + } + + if len(conf.Params) > 0 { + if err := s.registerScriptParams(conf.Params); err != nil { + return nil, err + } + } + + if test { + if err := s.executeTestFunction(); err != nil { + return nil, err + } + } + + return s, nil +} + +// setParseFunction validates that the parse() function exists and stores +// the handle. +func (s *session) setParseFunction() error { + parseFunc := s.vm.Get(entryPointFunction) + if parseFunc == nil { + return errors.New("parse function not found") + } + if parseFunc.ExportType().Kind() != reflect.Func { + return errors.New("parse is not a function") + } + if err := s.vm.ExportTo(parseFunc, &s.parseFunc); err != nil { + return errors.Wrap(err, "failed to export parse function") + } + return nil +} + +// registerScriptParams calls the register() function and passes the params. +func (s *session) registerScriptParams(params map[string]interface{}) error { + registerFunc := s.vm.Get(registerFunction) + if registerFunc == nil { + return errors.New("params were provided but no register function was found") + } + if registerFunc.ExportType().Kind() != reflect.Func { + return errors.New("register is not a function") + } + var register goja.Callable + if err := s.vm.ExportTo(registerFunc, ®ister); err != nil { + return errors.Wrap(err, "failed to export register function") + } + if _, err := register(goja.Undefined(), s.vm.ToValue(params)); err != nil { + return errors.Wrap(err, "failed to register script_params") + } + s.log.Debug("Registered params with script") + return nil +} + +// executeTestFunction executes the test() function if it exists. Any exceptions +// will cause the script to fail to load. +func (s *session) executeTestFunction() error { + if testFunc := s.vm.Get(testFunction); testFunc != nil { + if testFunc.ExportType().Kind() != reflect.Func { + return errors.New("test is not a function") + } + var test goja.Callable + if err := s.vm.ExportTo(testFunc, &test); err != nil { + return errors.Wrap(err, "failed to export test function") + } + _, err := test(goja.Undefined(), nil) + if err != nil { + return errors.Wrap(err, "failed in test() function") + } + s.log.Debugf("Successful test() execution for script.") + } + return nil +} + +// runParseFunc executes parse() from the JS script. +func (s *session) runParseFunc(n string) (out []s3EventV2, err error) { + defer func() { + if r := recover(); r != nil { + s.log.Errorw("The javascript script caused an unexpected panic "+ + "while parsing a notification. Recovering, but please report this.", + "notification", common.MapStr{"original": n}, + "panic", r, + zap.Stack("stack")) + err = fmt.Errorf("unexpected panic in javascript script: %v", r) + } + }() + + // Interrupt the JS code if execution exceeds timeout. + if s.timeout > 0 { + t := time.AfterFunc(s.timeout, func() { + s.vm.Interrupt(timeoutError) + }) + defer t.Stop() + } + + v, err := s.parseFunc(goja.Undefined(), s.vm.ToValue(n)) + if err != nil { + return nil, fmt.Errorf("failed in parse function: %w", err) + } + + if v.Equals(goja.Undefined()) { + return out, nil + } + + if err := s.vm.ExportTo(v, &out); err != nil { + return nil, fmt.Errorf("can't export returned value: %w", err) + } + + return out, nil +} + +type sessionPool struct { + New func() *session + C chan *session +} + +func newSessionPool(p *goja.Program, c scriptConfig) (*sessionPool, error) { + s, err := newSession(p, c, true) + if err != nil { + return nil, err + } + + pool := sessionPool{ + New: func() *session { + s, _ := newSession(p, c, false) + return s + }, + C: make(chan *session, c.MaxCachedSessions), + } + pool.Put(s) + + return &pool, nil +} + +func (p *sessionPool) Get() *session { + select { + case s := <-p.C: + return s + default: + return p.New() + } +} + +func (p *sessionPool) Put(s *session) { + if s != nil { + select { + case p.C <- s: + default: + } + } +} diff --git a/x-pack/filebeat/input/awss3/script_session_test.go b/x-pack/filebeat/input/awss3/script_session_test.go new file mode 100644 index 000000000000..4cad65b03fda --- /dev/null +++ b/x-pack/filebeat/input/awss3/script_session_test.go @@ -0,0 +1,317 @@ +// 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 awss3 + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/elastic/beats/v7/libbeat/logp" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSessionScriptParams(t *testing.T) { + logp.TestingSetup() + + t.Run("register method is optional", func(t *testing.T) { + _, err := newScriptFromConfig(log, &scriptConfig{Source: header + footer}) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("register required for params", func(t *testing.T) { + _, err := newScriptFromConfig(log, &scriptConfig{Source: header + footer, Params: map[string]interface{}{ + "p1": 42, + }, + }) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "params were provided") + } + }) + + t.Run("register params", func(t *testing.T) { + const script = ` + function register(params) { + if (params["p1"] !== 42) { + throw "invalid p1"; + } + } + + function parse(n) {} + ` + _, err := newScriptFromConfig(log, &scriptConfig{ + Source: script, + Params: map[string]interface{}{ + "p1": 42, + }, + }) + assert.NoError(t, err) + }) +} + +func TestSessionTestFunction(t *testing.T) { + logp.TestingSetup() + + const script = ` + var fail = false; + + function register(params) { + fail = params["fail"]; + } + + function parse(n) { + if (fail) { + throw "intentional failure"; + } + var m = JSON.parse(n); + var e = new S3EventV2(); + e.SetS3ObjectKey(m["hello"]); + return [e]; + } + + function test() { + var n = "{\"hello\": \"earth\"}"; + var evts = parse(n); + + if (evts[0].S3.Object.Key !== "earth") { + throw "invalid key value"; + } + } + ` + + t.Run("test method is optional", func(t *testing.T) { + _, err := newScriptFromConfig(log, &scriptConfig{ + Source: header + footer, + }) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("test success", func(t *testing.T) { + _, err := newScriptFromConfig(log, &scriptConfig{ + Source: script, + Params: map[string]interface{}{ + "fail": false, + }, + }) + assert.NoError(t, err) + }) + + t.Run("test failure", func(t *testing.T) { + _, err := newScriptFromConfig(log, &scriptConfig{ + Source: script, + Params: map[string]interface{}{ + "fail": true, + }, + }) + assert.Error(t, err) + }) +} + +func TestSessionTimeout(t *testing.T) { + logp.TestingSetup() + + const runawayLoop = ` + var m = JSON.parse(n); + while (!m.stop) { + m.hello = "world"; + } + ` + + p, err := newScriptFromConfig(log, &scriptConfig{ + Source: header + runawayLoop + footer, + Timeout: 100 * time.Millisecond, + }) + if err != nil { + t.Fatal(err) + } + + n := `{"stop": false}` + + // Execute and expect a timeout. + _, err = p.run(n) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), timeoutError) + } + + // Verify that any internal runtime interrupt state has been cleared. + n = `{"stop": true}` + _, err = p.run(n) + assert.NoError(t, err) +} + +func TestSessionParallel(t *testing.T) { + logp.TestingSetup() + + const script = ` + var m = JSON.parse(n); + var evt = new S3EventV2(); + evt.SetS3ObjectKey(m.hello.world); + return [evt]; + ` + + p, err := newScriptFromConfig(log, &scriptConfig{ + Source: header + script + footer, + }) + if err != nil { + t.Fatal(err) + } + + const goroutines = 10 + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var wg sync.WaitGroup + wg.Add(goroutines) + for i := 0; i < goroutines; i++ { + go func() { + defer wg.Done() + for ctx.Err() == nil { + n := `{"hello":{"world": "hello"}}` + evts, err := p.run(n) + require.NoError(t, err) + require.Equal(t, 1, len(evts)) + assert.Equal(t, "hello", evts[0].S3.Object.Key) + } + }() + } + + time.AfterFunc(time.Second, cancel) + wg.Wait() +} + +func TestCreateS3EventsFromNotification(t *testing.T) { + logp.TestingSetup() + + n := `{ + "cid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "timestamp": 1492726639222, + "fileCount": 4, + "totalSize": 349986221, + "bucket": "bucketNNNN", + "pathPrefix": "logs/aaaa-bbbb-cccc-dddd-eeee-ffff", + "files": [ + { + "path": "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00000.gz", + "size": 90506437, + "checksum": "ffffffffffffffffffff" + }, + { + "path": "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00001.gz", + "size": 86467594, + "checksum": "ffffffffffffffffffff" + }, + { + "path": "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00002.gz", + "size": 83893710, + "checksum": "ffffffffffffffffffff" + }, + { + "path": "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00003.gz", + "size": 89118480, + "checksum": "ffffffffffffffffffff" + } + ] + }` + + const script = ` + function parse(n) { + var m = JSON.parse(n); + var evts = []; + var files = m.files; + var bucket = m.bucket; + + if (!Array.isArray(files) || (files.length == 0) || bucket == null || bucket == "") { + return evts; + } + + files.forEach(function(f){ + var evt = new S3EventV2(); + evt.SetS3BucketName(bucket); + evt.SetS3ObjectKey(f.path); + evts.push(evt); + }); + + return evts; + } +` + s, err := newScriptFromConfig(log, &scriptConfig{Source: script}) + require.NoError(t, err) + + evts, err := s.run(n) + require.NoError(t, err) + require.Equal(t, 4, len(evts)) + + const expectedBucket = "bucketNNNN" + expectedObjectKeys := []string{ + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00000.gz", + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00001.gz", + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00002.gz", + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00003.gz", + } + + for i, e := range expectedObjectKeys { + assert.Equal(t, expectedBucket, evts[i].S3.Bucket.Name) + assert.Equal(t, e, evts[i].S3.Object.Key) + } +} + +func TestParseXML(t *testing.T) { + logp.TestingSetup() + + n := ` + bucketNNNN + + logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00000.gz + logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00001.gz + + ` + + const script = ` + function parse(n) { + var dec = new XMLDecoder(n); + var m = dec.Decode(); + var evts = []; + var files = m.record.files.file; + var bucket = m.record.bucket; + + if (!Array.isArray(files) || (files.length == 0) || bucket == null || bucket == "") { + return evts; + } + + files.forEach(function(f){ + var evt = new S3EventV2(); + evt.SetS3BucketName(bucket); + evt.SetS3ObjectKey(f.path); + evts.push(evt); + }); + + return evts; + } +` + s, err := newScriptFromConfig(log, &scriptConfig{Source: script}) + require.NoError(t, err) + + evts, err := s.run(n) + require.NoError(t, err) + require.Equal(t, 2, len(evts)) + + const expectedBucket = "bucketNNNN" + expectedObjectKeys := []string{ + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00000.gz", + "logs/aaaa-bbbb-cccc-dddd-eeee-ffff/part-00001.gz", + } + + for i, e := range expectedObjectKeys { + assert.Equal(t, expectedBucket, evts[i].S3.Bucket.Name) + assert.Equal(t, e, evts[i].S3.Object.Key) + } +} diff --git a/x-pack/filebeat/input/awss3/sqs_s3_event.go b/x-pack/filebeat/input/awss3/sqs_s3_event.go index a89aad7fc127..c906c74fa9e0 100644 --- a/x-pack/filebeat/input/awss3/sqs_s3_event.go +++ b/x-pack/filebeat/input/awss3/sqs_s3_event.go @@ -86,9 +86,10 @@ type sqsS3EventProcessor struct { log *logp.Logger warnOnce sync.Once metrics *inputMetrics + script *script } -func newSQSS3EventProcessor(log *logp.Logger, metrics *inputMetrics, sqs sqsAPI, sqsVisibilityTimeout time.Duration, maxReceiveCount int, s3 s3ObjectHandlerFactory) *sqsS3EventProcessor { +func newSQSS3EventProcessor(log *logp.Logger, metrics *inputMetrics, sqs sqsAPI, script *script, sqsVisibilityTimeout time.Duration, maxReceiveCount int, s3 s3ObjectHandlerFactory) *sqsS3EventProcessor { if metrics == nil { metrics = newInputMetrics(monitoring.NewRegistry(), "") } @@ -99,6 +100,7 @@ func newSQSS3EventProcessor(log *logp.Logger, metrics *inputMetrics, sqs sqsAPI, sqs: sqs, log: log, metrics: metrics, + script: script, } } @@ -185,6 +187,12 @@ func (p *sqsS3EventProcessor) keepalive(ctx context.Context, log *logp.Logger, w } func (p *sqsS3EventProcessor) getS3Notifications(body string) ([]s3EventV2, error) { + // Check if a parsing script is defined. If so, it takes precedence over + // format autodetection. + if p.script != nil { + return p.script.run(body) + } + // NOTE: If AWS introduces a V3 schema this will need updated to handle that schema. var events s3EventsV2 dec := json.NewDecoder(strings.NewReader(body)) @@ -201,6 +209,12 @@ func (p *sqsS3EventProcessor) getS3Notifications(body string) ([]s3EventV2, erro return nil, fmt.Errorf("failed to decode SQS message body as an S3 notification: %w", err) } } + + if events.Records == nil { + p.log.Debugw("Invalid SQS message body: missing Records field", "sqs_message_body", body) + return nil, errors.New("the message is an invalid S3 notification: missing Records field") + } + return p.getS3Info(events) } diff --git a/x-pack/filebeat/input/awss3/sqs_s3_event_test.go b/x-pack/filebeat/input/awss3/sqs_s3_event_test.go index 9edd5ec4ed9d..ad6d30056d42 100644 --- a/x-pack/filebeat/input/awss3/sqs_s3_event_test.go +++ b/x-pack/filebeat/input/awss3/sqs_s3_event_test.go @@ -38,7 +38,7 @@ func TestSQSS3EventProcessor(t *testing.T) { mockAPI.EXPECT().DeleteMessage(gomock.Any(), gomock.Eq(&msg)).Return(nil), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, time.Minute, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, time.Minute, 5, mockS3HandlerFactory) require.NoError(t, p.ProcessSQS(ctx, &msg)) }) @@ -60,7 +60,7 @@ func TestSQSS3EventProcessor(t *testing.T) { mockAPI.EXPECT().DeleteMessage(gomock.Any(), gomock.Eq(&invalidBodyMsg)).Return(nil), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, time.Minute, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, time.Minute, 5, mockS3HandlerFactory) err := p.ProcessSQS(ctx, &invalidBodyMsg) require.Error(t, err) t.Log(err) @@ -75,13 +75,13 @@ func TestSQSS3EventProcessor(t *testing.T) { mockAPI := NewMockSQSAPI(ctrl) mockS3HandlerFactory := NewMockS3ObjectHandlerFactory(ctrl) - emptyRecordsMsg := newSQSMessage() + emptyRecordsMsg := newSQSMessage([]s3EventV2{}...) gomock.InOrder( mockAPI.EXPECT().DeleteMessage(gomock.Any(), gomock.Eq(&emptyRecordsMsg)).Return(nil), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, time.Minute, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, time.Minute, 5, mockS3HandlerFactory) require.NoError(t, p.ProcessSQS(ctx, &emptyRecordsMsg)) }) @@ -108,7 +108,7 @@ func TestSQSS3EventProcessor(t *testing.T) { mockAPI.EXPECT().DeleteMessage(gomock.Any(), gomock.Eq(&msg)).Return(nil), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, visibilityTimeout, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, visibilityTimeout, 5, mockS3HandlerFactory) require.NoError(t, p.ProcessSQS(ctx, &msg)) }) @@ -127,7 +127,7 @@ func TestSQSS3EventProcessor(t *testing.T) { mockS3Handler.EXPECT().ProcessS3Object().Return(errors.New("fake connectivity problem")), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, time.Minute, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, time.Minute, 5, mockS3HandlerFactory) err := p.ProcessSQS(ctx, &msg) t.Log(err) require.Error(t, err) @@ -154,7 +154,7 @@ func TestSQSS3EventProcessor(t *testing.T) { mockAPI.EXPECT().DeleteMessage(gomock.Any(), gomock.Eq(&msg)).Return(nil), ) - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, time.Minute, 5, mockS3HandlerFactory) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, time.Minute, 5, mockS3HandlerFactory) err := p.ProcessSQS(ctx, &msg) t.Log(err) require.Error(t, err) @@ -164,7 +164,7 @@ func TestSQSS3EventProcessor(t *testing.T) { func TestSqsProcessor_getS3Notifications(t *testing.T) { logp.TestingSetup() - p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, nil, time.Minute, 5, nil) + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, nil, nil, time.Minute, 5, nil) t.Run("s3 key is url unescaped", func(t *testing.T) { msg := newSQSMessage(newS3Event("Happy+Face.jpg")) @@ -194,6 +194,24 @@ func TestSqsProcessor_getS3Notifications(t *testing.T) { assert.Equal(t, "arn:aws:s3:::vpc-flow-logs-ks", events[0].S3.Bucket.ARN) assert.Equal(t, "vpc-flow-logs-ks", events[0].S3.Bucket.Name) }) + + t.Run("missing Records fail", func(t *testing.T) { + msg := `{"message":"missing records"}` + _, err := p.getS3Notifications(msg) + require.Error(t, err) + assert.EqualError(t, err, "the message is an invalid S3 notification: missing Records field") + msg = `{"message":"null records", "Records": null}` + _, err = p.getS3Notifications(msg) + require.Error(t, err) + assert.EqualError(t, err, "the message is an invalid S3 notification: missing Records field") + }) + + t.Run("empty Records does not fail", func(t *testing.T) { + msg := `{"Records":[]}` + events, err := p.getS3Notifications(msg) + require.NoError(t, err) + assert.Equal(t, 0, len(events)) + }) } func TestNonRecoverableError(t *testing.T) { From 3a75570ff1f29932465174d676a191addac99b10 Mon Sep 17 00:00:00 2001 From: Marc Guasch Date: Thu, 18 Nov 2021 10:54:01 +0100 Subject: [PATCH 002/172] [filebeat] Threat intel sync (#29014) * abusemalware changes * abuseurl changes * malwarebazaar changes * anomali changes * otx changes * threatq changes * misp changes * anomalithreatstream changes * recordedfuture changes * Change dashboards field names and fields files * Change base to '' in field definition * Add changelog entry * Add threat.feed.name and threat.feed.dashboard_id --- CHANGELOG.next.asciidoc | 2 + filebeat/docs/fields.asciidoc | 951 +-- filebeat/docs/modules/threatintel.asciidoc | 127 +- .../module/threatintel/_meta/docs.asciidoc | 127 +- .../module/threatintel/_meta/fields.yml | 387 +- .../021ba940-de96-11eb-8f2b-753caedf727d.json | 4 +- .../028175a0-ff74-11eb-acb2-2960a7069ed1.json | 4 +- .../037e2af0-df50-11eb-8f2b-753caedf727d.json | 4 +- .../06744e90-df52-11eb-8f2b-753caedf727d.json | 6 +- .../0db62ee0-72e6-11eb-a3e3-b3cc7c78a70f.json | 10 +- .../1136ceb0-de95-11eb-8f2b-753caedf727d.json | 4 +- .../139c7da0-df51-11eb-8f2b-753caedf727d.json | 4 +- .../36f61650-de96-11eb-8f2b-753caedf727d.json | 4 +- .../3c40f4d0-de97-11eb-8f2b-753caedf727d.json | 4 +- .../3c996410-df52-11eb-8f2b-753caedf727d.json | 4 +- .../5e76ef90-df51-11eb-8f2b-753caedf727d.json | 4 +- .../5ef7b430-de94-11eb-8f2b-753caedf727d.json | 4 +- .../790cd040-df51-11eb-8f2b-753caedf727d.json | 4 +- .../7d9c70f0-de95-11eb-8f2b-753caedf727d.json | 4 +- .../7ec83f60-de98-11eb-8f2b-753caedf727d.json | 4 +- .../8a6f7b20-de94-11eb-8f2b-753caedf727d.json | 4 +- .../8fb01a00-df51-11eb-8f2b-753caedf727d.json | 4 +- .../9282afc0-72d9-11eb-a3e3-b3cc7c78a70f.json | 10 +- .../949bc180-df52-11eb-8f2b-753caedf727d.json | 4 +- .../976620a0-de98-11eb-8f2b-753caedf727d.json | 4 +- .../9c78ade0-de95-11eb-8f2b-753caedf727d.json | 4 +- .../a0a31740-df51-11eb-8f2b-753caedf727d.json | 4 +- .../aac00bc0-de98-11eb-8f2b-753caedf727d.json | 4 +- .../ae5934e0-de94-11eb-8f2b-753caedf727d.json | 4 +- .../b0837690-df52-11eb-8f2b-753caedf727d.json | 4 +- .../bd28cb00-de96-11eb-8f2b-753caedf727d.json | 4 +- .../bfd2bfe0-de97-11eb-8f2b-753caedf727d.json | 4 +- .../c2a5c180-df51-11eb-8f2b-753caedf727d.json | 6 +- .../c91fcd10-de95-11eb-8f2b-753caedf727d.json | 4 +- .../cf4b4e40-ff69-11eb-acb2-2960a7069ed1.json | 6 +- .../d991e510-de96-11eb-8f2b-753caedf727d.json | 4 +- .../dd4a3da0-df50-11eb-8f2b-753caedf727d.json | 4 +- .../e5f07800-de94-11eb-8f2b-753caedf727d.json | 4 +- .../f37f8350-df50-11eb-8f2b-753caedf727d.json | 4 +- .../f52a9720-de93-11eb-8f2b-753caedf727d.json | 4 +- .../f5f18940-de96-11eb-8f2b-753caedf727d.json | 4 +- .../63365b50-82aa-11eb-ac13-d5ca87cb8fa2.json | 4 +- .../ec5aa090-df42-11eb-8f2b-753caedf727d.json | 10 +- .../01c261b0-7aa9-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../02294f80-73c7-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../0ccdda50-76ce-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../142fb6c0-82a8-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../1a0d5250-72e5-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../1a1c60c0-72d5-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../1adff580-72ee-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../1c969990-73c7-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../1d8002d0-82a7-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../21ff17c0-82a6-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../302cd5b0-76cd-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../302d0850-ff7b-11eb-acb2-2960a7069ed1.json | 4 +- .../346136f0-76d5-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../40d61ab0-72e6-11eb-a3e3-b3cc7c78a70f.json | 4 +- .../41100be0-72e5-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../49f0c060-76cd-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../4e5d25c0-76ce-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../57faae10-73c5-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../5b4877b0-82a6-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../5d395d80-ff71-11eb-acb2-2960a7069ed1.json | 4 +- .../5eb61d00-ff72-11eb-acb2-2960a7069ed1.json | 6 +- .../6077fd00-76d5-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../62f6daa0-72ee-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../7546ac40-82a6-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../7582b030-73c6-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../786546d0-82a5-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../79da77d0-72e5-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../7c7d3750-73c3-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../7cbe5900-82ab-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../87980f70-72ec-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../8b2a64a0-82a8-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../9047e8b0-72de-11eb-a3e3-b3cc7c78a70f.json | 4 +- .../9109e490-76cd-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../92961600-7621-11eb-a3e3-b3cc7c78a70f.json | 6 +- .../95f384b0-76d8-11eb-a3e3-b3cc7c78a70f.json | 4 +- .../98d42ee0-76b6-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../a09329d0-73c6-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../a1616dd0-72eb-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../a7b6e910-72ed-11eb-a3e3-b3cc7c78a70f.json | 10 +- .../a911a8b0-ff77-11eb-acb2-2960a7069ed1.json | 4 +- .../ad55b1e0-73c8-11eb-a3e3-b3cc7c78a70f.json | 6 +- .../aebde030-72d2-11eb-a3e3-b3cc7c78a70f.json | 10 +- .../b9533f50-72e5-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../bc4790b0-82aa-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../bf3dfde0-73c3-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../c102b0f0-73c6-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../c7d5db50-82a8-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../c813c5d0-72dd-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../d22c1090-82a5-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../d5d76c60-72ee-11eb-a3e3-b3cc7c78a70f.json | 6 +- .../dbd199d0-82aa-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../ea5879c0-72eb-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../eba4ec60-72ea-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../ec68c4a0-73c6-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../ecf74b10-72ec-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../f33125b0-76d8-11eb-a3e3-b3cc7c78a70f.json | 8 +- .../f91e9620-82a8-11eb-ac13-d5ca87cb8fa2.json | 8 +- .../f9c6ba80-72e5-11eb-a3e3-b3cc7c78a70f.json | 14 +- .../threatintel/abusemalware/_meta/fields.yml | 4 +- .../abusemalware/config/config.yml | 28 +- .../abusemalware/ingest/pipeline.yml | 101 +- .../threatintel/abusemalware/manifest.yml | 3 + .../abusechmalware.ndjson.log-expected.json | 518 +- .../threatintel/abuseurl/_meta/fields.yml | 2 +- .../threatintel/abuseurl/config/config.yml | 25 +- .../threatintel/abuseurl/ingest/pipeline.yml | 68 +- .../module/threatintel/abuseurl/manifest.yml | 2 + .../test/abusechurl.ndjson.log-expected.json | 4226 ++++++------- .../threatintel/anomali/_meta/fields.yml | 4 +- .../threatintel/anomali/config/config.yml | 23 +- .../threatintel/anomali/ingest/pipeline.yml | 86 +- .../module/threatintel/anomali/manifest.yml | 4 +- .../anomali_limo.ndjson.log-expected.json | 4190 ++++++------- .../anomalithreatstream/_meta/fields.yml | 2 +- .../anomalithreatstream/config/config.yml | 41 +- .../anomalithreatstream/ingest/pipeline.yml | 169 +- .../anomalithreatstream/manifest.yml | 6 +- .../test/generated.log-expected.json | 5302 +++++++++-------- x-pack/filebeat/module/threatintel/fields.go | 2 +- .../malwarebazaar/_meta/fields.yml | 2 +- .../malwarebazaar/config/config.yml | 28 +- .../malwarebazaar/ingest/pipeline.yml | 191 +- .../threatintel/malwarebazaar/manifest.yml | 2 + .../malwarebazaar.ndjson.log-expected.json | 412 +- .../module/threatintel/misp/config/config.yml | 52 +- .../threatintel/misp/ingest/pipeline.yml | 298 +- .../module/threatintel/misp/manifest.yml | 2 + .../test/misp_sample.ndjson.log-expected.json | 1192 ++-- ...th_ext_attributes.ndjson.log-expected.json | 2382 ++++---- .../module/threatintel/otx/config/config.yml | 21 +- .../threatintel/otx/ingest/pipeline.yml | 128 +- .../module/threatintel/otx/manifest.yml | 2 + .../test/otx_sample.ndjson.log-expected.json | 628 +- .../recordedfuture/config/config.yml | 31 +- .../recordedfuture/ingest/pipeline.yml | 119 +- .../threatintel/recordedfuture/manifest.yml | 2 + .../test/domain.ndjson.log-expected.json | 320 +- .../test/hash.ndjson.log-expected.json | 460 +- .../test/ip.ndjson.log-expected.json | 462 +- .../test/url.ndjson.log-expected.json | 500 +- .../threatintel/threatq/config/config.yml | 27 +- .../threatintel/threatq/ingest/pipeline.yml | 240 +- .../module/threatintel/threatq/manifest.yml | 4 +- .../threatq_sample.ndjson.log-expected.json | 320 +- 147 files changed, 12593 insertions(+), 12280 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index bd473812131c..6bb189ee3016 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -62,6 +62,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - All modules: Replace usages of deprecated ECS fields `process.ppid` and `log.original` with `process.parent.pid` and `event.original`. {pull}28620[28620] - Replace usages of `host.user.*` fields with `user.*` in `cisco`, `microsoft` and `oracle` modules. {pull}28620[28620] - Remove `docker` input. Please use `filestream` input with `container` parser or `container` input. {pull}28817[28817] +- Change `threatintel` module to use new `threat.*` ECS fields. {pull}29014[29014] *Heartbeat* @@ -183,6 +184,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Upgrade azure-eventhub sdk reference, contains potential checkpoint fixes. {pull}28919[28919] - Revert usageDetails api version to 2019-01-01. {pull}28995[28995] - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] +- Fix `threatintel.misp` filters configuration. {issue}27970[27970] *Heartbeat* diff --git a/filebeat/docs/fields.asciidoc b/filebeat/docs/fields.asciidoc index d89839516fec..34b05a0fd246 100644 --- a/filebeat/docs/fields.asciidoc +++ b/filebeat/docs/fields.asciidoc @@ -150641,385 +150641,8 @@ Threat intelligence Filebeat Module. -[float] -=== threatintel - -Fields from the threatintel Filebeat module. - - - -*`threatintel.indicator.first_seen`*:: -+ --- -The date and time when intelligence source first reported sighting this indicator. - - -type: date - --- - -*`threatintel.indicator.last_seen`*:: -+ --- -The date and time when intelligence source last reported sighting this indicator. - - -type: date - --- - -*`threatintel.indicator.sightings`*:: -+ --- -Number of times this indicator was observed conducting threat activity. - - -type: long - --- - -*`threatintel.indicator.type`*:: -+ --- -Type of indicator as represented by Cyber Observable in STIX 2.0. Expected values - * autonomous-system - * artifact - * directory - * domain-name - * email-addr - * file - * ipv4-addr - * ipv6-addr - * mac-addr - * mutex - * process - * software - * url - * user-account - * windows-registry-key - * x-509-certificate - - -type: keyword - --- - -*`threatintel.indicator.description`*:: -+ --- -Describes the type of action conducted by the threat. - - -type: keyword - --- - -*`threatintel.indicator.scanner_stats`*:: -+ --- -Count of AV/EDR vendors that successfully detected malicious file or URL. - - -type: long - --- - -*`threatintel.indicator.provider`*:: -+ --- -Identifies the name of the intelligence provider. - - -type: keyword - --- - -*`threatintel.indicator.confidence`*:: -+ --- -Identifies the confidence rating assigned by the provider using STIX confidence scales. Expected values - * Not Specified, None, Low, Medium, High - * 0-10 - * Admirality Scale (1-6) - * DNI Scale (5-95) - * WEP Scale (Impossible - Certain) - - -type: keyword - --- - -*`threatintel.indicator.module`*:: -+ --- -Identifies the name of specific module this data is coming from. - - -type: keyword - --- - -*`threatintel.indicator.dataset`*:: -+ --- -Identifies the name of specific dataset from the intelligence source. - - -type: keyword - --- - -*`threatintel.indicator.reference`*:: -+ --- -Reference URL linking to additional information about this indicator. - - -type: keyword - --- - -*`threatintel.indicator.ip`*:: -+ --- -Identifies a threat indicator as an IP address (irrespective of direction). - - -type: ip - --- - -*`threatintel.indicator.port`*:: -+ --- -Identifies a threat indicator as a port number (irrespective of direction). - - -type: long - --- - -*`threatintel.indicator.email.address`*:: -+ --- -Identifies a threat indicator as an email address (irrespective of direction). - - -type: keyword - --- - -*`threatintel.indicator.marking.tlp`*:: -+ --- -Traffic Light Protocol sharing markings. Expected values are: - * White - * Green - * Amber - * Red - - -type: keyword - --- - - -*`threatintel.indicator.matched.atomic`*:: -+ --- -Identifies the atomic indicator that matched a local environment endpoint or network event. - - -type: keyword - --- - -*`threatintel.indicator.matched.field`*:: -+ --- -Identifies the field of the atomic indicator that matched a local environment endpoint or network event. - - -type: keyword - --- - -*`threatintel.indicator.matched.type`*:: -+ --- -Identifies the type of the atomic indicator that matched a local environment endpoint or network event. - - -type: keyword - --- - - -*`threatintel.indicator.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`threatintel.indicator.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`threatintel.indicator.as.organization.name.text`*:: -+ --- -type: text - --- - - -*`threatintel.indicator.registry.data.strings`*:: -+ --- -Content when writing string types. Populated as an array when writing string data to the registry. For single string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with one string. For sequences of string with REG_MULTI_SZ, this array will be variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should be populated with the decimal representation (e.g `"1"`). - - -type: keyword - -example: ["C:\rta\red_ttp\bin\myapp.exe"] - --- - -*`threatintel.indicator.registry.path`*:: -+ --- -Full path, including hive, key and value - -type: keyword - -example: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe\Debugger - --- - -*`threatintel.indicator.registry.value`*:: -+ --- -Name of the value written. - -type: keyword - -example: Debugger - --- - -*`threatintel.indicator.registry.key`*:: -+ --- -Registry key value - -type: keyword - --- - - -*`threatintel.indicator.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`threatintel.indicator.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`threatintel.indicator.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`threatintel.indicator.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`threatintel.indicator.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`threatintel.indicator.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`threatintel.indicator.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`threatintel.indicator.file.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - - -*`threatintel.indicator.file.hash.tlsh`*:: +*`threat.indicator.file.hash.tlsh`*:: + -- The file's import tlsh, if available. @@ -151029,47 +150652,7 @@ type: keyword -- -*`threatintel.indicator.file.hash.ssdeep`*:: -+ --- -The file's ssdeep hash, if available. - - -type: keyword - --- - -*`threatintel.indicator.file.hash.md5`*:: -+ --- -The file's md5 hash, if available. - - -type: keyword - --- - -*`threatintel.indicator.file.hash.sha1`*:: -+ --- -The file's sha1 hash, if available. - - -type: keyword - --- - -*`threatintel.indicator.file.hash.sha256`*:: -+ --- -The file's sha256 hash, if available. - - -type: keyword - --- - -*`threatintel.indicator.file.hash.sha384`*:: +*`threat.indicator.file.hash.sha384`*:: + -- The file's sha384 hash, if available. @@ -151079,272 +150662,28 @@ type: keyword -- -*`threatintel.indicator.file.hash.sha512`*:: -+ --- -The file's sha512 hash, if available. - - -type: keyword - --- - -*`threatintel.indicator.file.type`*:: -+ --- -The file type. - - -type: keyword - --- - -*`threatintel.indicator.file.size`*:: -+ --- -The file's total size. - - -type: long - --- - -*`threatintel.indicator.file.name`*:: -+ --- -The file's name. - - -type: keyword - --- - -*`threatintel.indicator.file.extension`*:: -+ --- -The file's extension. - - -type: keyword - --- - -*`threatintel.indicator.file.mime_type`*:: -+ --- -The file's MIME type. - - -type: keyword - --- - - -*`threatintel.indicator.url.domain`*:: -+ --- -Domain of the url, such as "www.elastic.co". - - -type: keyword - --- - -*`threatintel.indicator.url.extension`*:: -+ --- -The field contains the file extension from the original request - - -type: keyword - --- - -*`threatintel.indicator.url.fragment`*:: -+ --- -Portion of the url after the `#`, such as "top". - - -type: keyword - --- - -*`threatintel.indicator.url.full`*:: -+ --- -If full URLs are important to your use case, they should be stored in `url.full`, whether this field is reconstructed or present in the event source. - - -type: keyword - --- - -*`threatintel.indicator.url.original`*:: -+ --- -Unmodified original url as seen in the event source. Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. - - -type: keyword - --- - -*`threatintel.indicator.url.password`*:: -+ --- -Password of the request. - - -type: keyword - --- - -*`threatintel.indicator.url.path`*:: -+ --- -Path of the request, such as "/search". - - -type: keyword - --- - -*`threatintel.indicator.url.port`*:: -+ --- -Port of the request, such as 443. - - -type: long - -format: string - --- - -*`threatintel.indicator.url.query`*:: -+ --- -The query field describes the query string of the request, such as "q=elasticsearch". The `?` is excluded from the query string. If a URL contains no `?`, there is no query field. If there is a `?` but no query, the query field exists with an empty string. The `exists` query can be used to differentiate between the two cases. - - -type: keyword - --- - -*`threatintel.indicator.url.registered_domain`*:: -+ --- -The highest registered url domain, stripped of the subdomain. For example, the registered domain for "foo.example.com" is "example.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - - -type: keyword - --- - -*`threatintel.indicator.url.scheme`*:: -+ --- -Scheme of the request, such as "https". - - -type: keyword - --- - -*`threatintel.indicator.url.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - - -type: keyword - --- - -*`threatintel.indicator.url.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - - -type: keyword - --- - -*`threatintel.indicator.url.username`*:: -+ --- -Username of the request. - - -type: keyword - --- - - -*`threatintel.indicator.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`threatintel.indicator.x509.issuer`*:: -+ --- -Name of issuing certificate authority. Could be either Distinguished Name (DN) or Common Name (CN), depending on source. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`threatintel.indicator.x509.subject`*:: -+ --- -Name of the certificate subject entity. Could be either Distinguished Name (DN) or Common Name (CN), depending on source. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`threatintel.indicator.x509.alternative_names`*:: +*`threat.feed.name`*:: + -- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - type: keyword -example: *.elastic.co - -- -*`threatintel.indicator.signature`*:: +*`threat.feed.dashboard_id`*:: + -- -Malware family of sample (if available). - - type: keyword -- [float] -=== abusemalware +=== abusech.malware Fields for AbuseCH Malware Threat Intel -*`threatintel.abusemalware.file_type`*:: +*`abusech.malware.file_type`*:: + -- File type guessed by URLhaus. @@ -151354,7 +150693,7 @@ type: keyword -- -*`threatintel.abusemalware.signature`*:: +*`abusech.malware.signature`*:: + -- Malware familiy. @@ -151364,7 +150703,7 @@ type: keyword -- -*`threatintel.abusemalware.urlhaus_download`*:: +*`abusech.malware.urlhaus_download`*:: + -- Location (URL) where you can download a copy of this file. @@ -151374,7 +150713,7 @@ type: keyword -- -*`threatintel.abusemalware.virustotal.result`*:: +*`abusech.malware.virustotal.result`*:: + -- AV detection ration. @@ -151384,7 +150723,7 @@ type: keyword -- -*`threatintel.abusemalware.virustotal.percent`*:: +*`abusech.malware.virustotal.percent`*:: + -- AV detection in percent. @@ -151394,7 +150733,7 @@ type: float -- -*`threatintel.abusemalware.virustotal.link`*:: +*`abusech.malware.virustotal.link`*:: + -- Link to the Virustotal report. @@ -151405,13 +150744,13 @@ type: keyword -- [float] -=== abuseurl +=== abusech.url Fields for AbuseCH Malware Threat Intel -*`threatintel.abuseurl.id`*:: +*`abusech.url.id`*:: + -- The ID of the url. @@ -151421,7 +150760,7 @@ type: keyword -- -*`threatintel.abuseurl.urlhaus_reference`*:: +*`abusech.url.urlhaus_reference`*:: + -- Link to URLhaus entry. @@ -151431,7 +150770,7 @@ type: keyword -- -*`threatintel.abuseurl.url_status`*:: +*`abusech.url.url_status`*:: + -- The current status of the URL. Possible values are: online, offline and unknown. @@ -151441,7 +150780,7 @@ type: keyword -- -*`threatintel.abuseurl.threat`*:: +*`abusech.url.threat`*:: + -- The threat corresponding to this malware URL. @@ -151451,7 +150790,7 @@ type: keyword -- -*`threatintel.abuseurl.blacklists.surbl`*:: +*`abusech.url.blacklists.surbl`*:: + -- SURBL blacklist status. Possible values are: listed and not_listed @@ -151461,7 +150800,7 @@ type: keyword -- -*`threatintel.abuseurl.blacklists.spamhaus_dbl`*:: +*`abusech.url.blacklists.spamhaus_dbl`*:: + -- Spamhaus DBL blacklist status. @@ -151471,7 +150810,7 @@ type: keyword -- -*`threatintel.abuseurl.reporter`*:: +*`abusech.url.reporter`*:: + -- The Twitter handle of the reporter that has reported this malware URL (or anonymous). @@ -151481,7 +150820,7 @@ type: keyword -- -*`threatintel.abuseurl.larted`*:: +*`abusech.url.larted`*:: + -- Indicates whether the malware URL has been reported to the hosting provider (true or false) @@ -151491,7 +150830,7 @@ type: boolean -- -*`threatintel.abuseurl.tags`*:: +*`abusech.url.tags`*:: + -- A list of tags associated with the queried malware URL @@ -151502,13 +150841,13 @@ type: keyword -- [float] -=== anomali +=== anomali.limo Fields for Anomali Threat Intel -*`threatintel.anomali.id`*:: +*`anomali.limo.id`*:: + -- The ID of the indicator. @@ -151518,7 +150857,7 @@ type: keyword -- -*`threatintel.anomali.name`*:: +*`anomali.limo.name`*:: + -- The name of the indicator. @@ -151528,7 +150867,7 @@ type: keyword -- -*`threatintel.anomali.pattern`*:: +*`anomali.limo.pattern`*:: + -- The pattern ID of the indicator. @@ -151538,7 +150877,7 @@ type: keyword -- -*`threatintel.anomali.valid_from`*:: +*`anomali.limo.valid_from`*:: + -- When the indicator was first found or is considered valid. @@ -151548,7 +150887,7 @@ type: date -- -*`threatintel.anomali.modified`*:: +*`anomali.limo.modified`*:: + -- When the indicator was last modified @@ -151558,7 +150897,7 @@ type: date -- -*`threatintel.anomali.labels`*:: +*`anomali.limo.labels`*:: + -- The labels related to the indicator @@ -151568,7 +150907,7 @@ type: keyword -- -*`threatintel.anomali.indicator`*:: +*`anomali.limo.indicator`*:: + -- The value of the indicator, for example if the type is domain, this would be the value. @@ -151578,7 +150917,7 @@ type: keyword -- -*`threatintel.anomali.description`*:: +*`anomali.limo.description`*:: + -- A description of the indicator. @@ -151588,7 +150927,7 @@ type: keyword -- -*`threatintel.anomali.title`*:: +*`anomali.limo.title`*:: + -- Title describing the indicator. @@ -151598,7 +150937,7 @@ type: keyword -- -*`threatintel.anomali.content`*:: +*`anomali.limo.content`*:: + -- Extra text or descriptive content related to the indicator. @@ -151608,7 +150947,7 @@ type: keyword -- -*`threatintel.anomali.type`*:: +*`anomali.limo.type`*:: + -- The indicator type, can for example be "domain, email, FileHash-SHA256". @@ -151618,7 +150957,7 @@ type: keyword -- -*`threatintel.anomali.object_marking_refs`*:: +*`anomali.limo.object_marking_refs`*:: + -- The STIX reference object. @@ -151629,13 +150968,13 @@ type: keyword -- [float] -=== anomalithreatstream +=== anomali.threatstream Fields for Anomali ThreatStream -*`threatintel.anomalithreatstream.classification`*:: +*`anomali.threatstream.classification`*:: + -- Indicates whether an indicator is private or from a public feed and available publicly. Possible values: private, public. @@ -151647,7 +150986,7 @@ example: private -- -*`threatintel.anomalithreatstream.confidence`*:: +*`anomali.threatstream.confidence`*:: + -- The measure of the accuracy (from 0 to 100) assigned by ThreatStream's predictive analytics technology to indicators. @@ -151657,7 +150996,7 @@ type: short -- -*`threatintel.anomalithreatstream.detail2`*:: +*`anomali.threatstream.detail2`*:: + -- Detail text for indicator. @@ -151669,7 +151008,7 @@ example: Imported by user 42. -- -*`threatintel.anomalithreatstream.id`*:: +*`anomali.threatstream.id`*:: + -- The ID of the indicator. @@ -151679,7 +151018,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.import_session_id`*:: +*`anomali.threatstream.import_session_id`*:: + -- ID of the import session that created the indicator on ThreatStream. @@ -151689,7 +151028,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.itype`*:: +*`anomali.threatstream.itype`*:: + -- Indicator type. Possible values: "apt_domain", "apt_email", "apt_ip", "apt_url", "bot_ip", "c2_domain", "c2_ip", "c2_url", "i2p_ip", "mal_domain", "mal_email", "mal_ip", "mal_md5", "mal_url", "parked_ip", "phish_email", "phish_ip", "phish_url", "scan_ip", "spam_domain", "ssh_ip", "suspicious_domain", "tor_ip" and "torrent_tracker_url". @@ -151699,7 +151038,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.maltype`*:: +*`anomali.threatstream.maltype`*:: + -- Information regarding a malware family, a CVE ID, or another attack or threat, associated with the indicator. @@ -151709,7 +151048,7 @@ type: wildcard -- -*`threatintel.anomalithreatstream.md5`*:: +*`anomali.threatstream.md5`*:: + -- Hash for the indicator. @@ -151719,7 +151058,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.resource_uri`*:: +*`anomali.threatstream.resource_uri`*:: + -- Relative URI for the indicator details. @@ -151729,7 +151068,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.severity`*:: +*`anomali.threatstream.severity`*:: + -- Criticality associated with the threat feed that supplied the indicator. Possible values: low, medium, high, very-high. @@ -151739,7 +151078,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.source`*:: +*`anomali.threatstream.source`*:: + -- Source for the indicator. @@ -151751,7 +151090,7 @@ example: Analyst -- -*`threatintel.anomalithreatstream.source_feed_id`*:: +*`anomali.threatstream.source_feed_id`*:: + -- ID for the integrator source. @@ -151761,7 +151100,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.state`*:: +*`anomali.threatstream.state`*:: + -- State for this indicator. @@ -151773,7 +151112,7 @@ example: active -- -*`threatintel.anomalithreatstream.trusted_circle_ids`*:: +*`anomali.threatstream.trusted_circle_ids`*:: + -- ID of the trusted circle that imported the indicator. @@ -151783,7 +151122,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.update_id`*:: +*`anomali.threatstream.update_id`*:: + -- Update ID. @@ -151793,7 +151132,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.url`*:: +*`anomali.threatstream.url`*:: + -- URL for the indicator. @@ -151803,7 +151142,7 @@ type: keyword -- -*`threatintel.anomalithreatstream.value_type`*:: +*`anomali.threatstream.value_type`*:: + -- Data type of the indicator. Possible values: ip, domain, url, email, md5. @@ -151814,13 +151153,13 @@ type: keyword -- [float] -=== malwarebazaar +=== abusech.malwarebazaar Fields for Malware Bazaar Threat Intel -*`threatintel.malwarebazaar.file_type`*:: +*`abusech.malwarebazaar.file_type`*:: + -- File type guessed by Malware Bazaar. @@ -151830,7 +151169,7 @@ type: keyword -- -*`threatintel.malwarebazaar.signature`*:: +*`abusech.malwarebazaar.signature`*:: + -- Malware familiy. @@ -151840,7 +151179,7 @@ type: keyword -- -*`threatintel.malwarebazaar.tags`*:: +*`abusech.malwarebazaar.tags`*:: + -- A list of tags associated with the queried malware sample. @@ -151851,7 +151190,7 @@ type: keyword -- -*`threatintel.malwarebazaar.intelligence.downloads`*:: +*`abusech.malwarebazaar.intelligence.downloads`*:: + -- Number of downloads from MalwareBazaar. @@ -151861,7 +151200,7 @@ type: long -- -*`threatintel.malwarebazaar.intelligence.uploads`*:: +*`abusech.malwarebazaar.intelligence.uploads`*:: + -- Number of uploads from MalwareBazaar. @@ -151872,7 +151211,7 @@ type: long -- -*`threatintel.malwarebazaar.intelligence.mail.Generic`*:: +*`abusech.malwarebazaar.intelligence.mail.Generic`*:: + -- Malware seen in generic spam traffic. @@ -151882,7 +151221,7 @@ type: keyword -- -*`threatintel.malwarebazaar.intelligence.mail.IT`*:: +*`abusech.malwarebazaar.intelligence.mail.IT`*:: + -- Malware seen in IT spam traffic. @@ -151892,7 +151231,7 @@ type: keyword -- -*`threatintel.malwarebazaar.anonymous`*:: +*`abusech.malwarebazaar.anonymous`*:: + -- Identifies if the sample was submitted anonymously. @@ -151902,7 +151241,7 @@ type: long -- -*`threatintel.malwarebazaar.code_sign`*:: +*`abusech.malwarebazaar.code_sign`*:: + -- Code signing information for the sample. @@ -151919,7 +151258,7 @@ Fields for MISP Threat Intel -*`threatintel.misp.id`*:: +*`misp.id`*:: + -- Attribute ID. @@ -151929,7 +151268,7 @@ type: keyword -- -*`threatintel.misp.orgc_id`*:: +*`misp.orgc_id`*:: + -- Organization Community ID of the event. @@ -151939,7 +151278,7 @@ type: keyword -- -*`threatintel.misp.org_id`*:: +*`misp.org_id`*:: + -- Organization ID of the event. @@ -151949,7 +151288,7 @@ type: keyword -- -*`threatintel.misp.threat_level_id`*:: +*`misp.threat_level_id`*:: + -- Threat level from 5 to 1, where 1 is the most critical. @@ -151959,7 +151298,7 @@ type: long -- -*`threatintel.misp.info`*:: +*`misp.info`*:: + -- Additional text or information related to the event. @@ -151969,7 +151308,7 @@ type: keyword -- -*`threatintel.misp.published`*:: +*`misp.published`*:: + -- When the event was published. @@ -151979,7 +151318,7 @@ type: boolean -- -*`threatintel.misp.uuid`*:: +*`misp.uuid`*:: + -- The UUID of the event object. @@ -151989,7 +151328,7 @@ type: keyword -- -*`threatintel.misp.date`*:: +*`misp.date`*:: + -- The date of when the event object was created. @@ -151999,7 +151338,7 @@ type: date -- -*`threatintel.misp.attribute_count`*:: +*`misp.attribute_count`*:: + -- How many attributes are included in a single event object. @@ -152009,7 +151348,7 @@ type: long -- -*`threatintel.misp.timestamp`*:: +*`misp.timestamp`*:: + -- The timestamp of when the event object was created. @@ -152019,7 +151358,7 @@ type: date -- -*`threatintel.misp.distribution`*:: +*`misp.distribution`*:: + -- Distribution type related to MISP. @@ -152029,7 +151368,7 @@ type: keyword -- -*`threatintel.misp.proposal_email_lock`*:: +*`misp.proposal_email_lock`*:: + -- Settings configured on MISP for email lock on this event object. @@ -152039,7 +151378,7 @@ type: boolean -- -*`threatintel.misp.locked`*:: +*`misp.locked`*:: + -- If the current MISP event object is locked or not. @@ -152049,7 +151388,7 @@ type: boolean -- -*`threatintel.misp.publish_timestamp`*:: +*`misp.publish_timestamp`*:: + -- At what time the event object was published @@ -152059,7 +151398,7 @@ type: date -- -*`threatintel.misp.sharing_group_id`*:: +*`misp.sharing_group_id`*:: + -- The ID of the grouped events or sources of the event. @@ -152069,7 +151408,7 @@ type: keyword -- -*`threatintel.misp.disable_correlation`*:: +*`misp.disable_correlation`*:: + -- If correlation is disabled on the MISP event object. @@ -152079,7 +151418,7 @@ type: boolean -- -*`threatintel.misp.extends_uuid`*:: +*`misp.extends_uuid`*:: + -- The UUID of the event object it might extend. @@ -152089,7 +151428,7 @@ type: keyword -- -*`threatintel.misp.org.id`*:: +*`misp.org.id`*:: + -- The organization ID related to the event object. @@ -152099,7 +151438,7 @@ type: keyword -- -*`threatintel.misp.org.name`*:: +*`misp.org.name`*:: + -- The organization name related to the event object. @@ -152109,7 +151448,7 @@ type: keyword -- -*`threatintel.misp.org.uuid`*:: +*`misp.org.uuid`*:: + -- The UUID of the organization related to the event object. @@ -152119,7 +151458,7 @@ type: keyword -- -*`threatintel.misp.org.local`*:: +*`misp.org.local`*:: + -- If the event object is local or from a remote source. @@ -152129,7 +151468,7 @@ type: boolean -- -*`threatintel.misp.orgc.id`*:: +*`misp.orgc.id`*:: + -- The Organization Community ID in which the event object was reported from. @@ -152139,7 +151478,7 @@ type: keyword -- -*`threatintel.misp.orgc.name`*:: +*`misp.orgc.name`*:: + -- The Organization Community name in which the event object was reported from. @@ -152149,7 +151488,7 @@ type: keyword -- -*`threatintel.misp.orgc.uuid`*:: +*`misp.orgc.uuid`*:: + -- The Organization Community UUID in which the event object was reported from. @@ -152159,7 +151498,7 @@ type: keyword -- -*`threatintel.misp.orgc.local`*:: +*`misp.orgc.local`*:: + -- If the Organization Community was local or synced from a remote source. @@ -152169,7 +151508,7 @@ type: boolean -- -*`threatintel.misp.attribute.id`*:: +*`misp.attribute.id`*:: + -- The ID of the attribute related to the event object. @@ -152179,7 +151518,7 @@ type: keyword -- -*`threatintel.misp.attribute.type`*:: +*`misp.attribute.type`*:: + -- The type of the attribute related to the event object. For example email, ipv4, sha1 and such. @@ -152189,7 +151528,7 @@ type: keyword -- -*`threatintel.misp.attribute.category`*:: +*`misp.attribute.category`*:: + -- The category of the attribute related to the event object. For example "Network Activity". @@ -152199,7 +151538,7 @@ type: keyword -- -*`threatintel.misp.attribute.to_ids`*:: +*`misp.attribute.to_ids`*:: + -- If the attribute should be automatically synced with an IDS. @@ -152209,7 +151548,7 @@ type: boolean -- -*`threatintel.misp.attribute.uuid`*:: +*`misp.attribute.uuid`*:: + -- The UUID of the attribute related to the event. @@ -152219,7 +151558,7 @@ type: keyword -- -*`threatintel.misp.attribute.event_id`*:: +*`misp.attribute.event_id`*:: + -- The local event ID of the attribute related to the event. @@ -152229,7 +151568,7 @@ type: keyword -- -*`threatintel.misp.attribute.distribution`*:: +*`misp.attribute.distribution`*:: + -- How the attribute has been distributed, represented by integer numbers. @@ -152239,7 +151578,7 @@ type: long -- -*`threatintel.misp.attribute.timestamp`*:: +*`misp.attribute.timestamp`*:: + -- The timestamp in which the attribute was attached to the event object. @@ -152249,7 +151588,7 @@ type: date -- -*`threatintel.misp.attribute.comment`*:: +*`misp.attribute.comment`*:: + -- Comments made to the attribute itself. @@ -152259,7 +151598,7 @@ type: keyword -- -*`threatintel.misp.attribute.sharing_group_id`*:: +*`misp.attribute.sharing_group_id`*:: + -- The group ID of the sharing group related to the specific attribute. @@ -152269,7 +151608,7 @@ type: keyword -- -*`threatintel.misp.attribute.deleted`*:: +*`misp.attribute.deleted`*:: + -- If the attribute has been removed from the event object. @@ -152279,7 +151618,7 @@ type: boolean -- -*`threatintel.misp.attribute.disable_correlation`*:: +*`misp.attribute.disable_correlation`*:: + -- If correlation has been enabled on the attribute related to the event object. @@ -152289,7 +151628,7 @@ type: boolean -- -*`threatintel.misp.attribute.object_id`*:: +*`misp.attribute.object_id`*:: + -- The ID of the Object in which the attribute is attached. @@ -152299,7 +151638,7 @@ type: keyword -- -*`threatintel.misp.attribute.object_relation`*:: +*`misp.attribute.object_relation`*:: + -- The type of relation the attribute has with the event object itself. @@ -152309,7 +151648,7 @@ type: keyword -- -*`threatintel.misp.attribute.value`*:: +*`misp.attribute.value`*:: + -- The value of the attribute, depending on the type like "url, sha1, email-src". @@ -152319,7 +151658,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.id`*:: +*`misp.context.attribute.id`*:: + -- The ID of the secondary attribute related to the event object. @@ -152329,7 +151668,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.type`*:: +*`misp.context.attribute.type`*:: + -- The type of the secondary attribute related to the event object. For example email, ipv4, sha1 and such. @@ -152339,7 +151678,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.category`*:: +*`misp.context.attribute.category`*:: + -- The category of the secondary attribute related to the event object. For example "Network Activity". @@ -152349,7 +151688,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.to_ids`*:: +*`misp.context.attribute.to_ids`*:: + -- If the secondary attribute should be automatically synced with an IDS. @@ -152359,7 +151698,7 @@ type: boolean -- -*`threatintel.misp.context.attribute.uuid`*:: +*`misp.context.attribute.uuid`*:: + -- The UUID of the secondary attribute related to the event. @@ -152369,7 +151708,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.event_id`*:: +*`misp.context.attribute.event_id`*:: + -- The local event ID of the secondary attribute related to the event. @@ -152379,7 +151718,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.distribution`*:: +*`misp.context.attribute.distribution`*:: + -- How the secondary attribute has been distributed, represented by integer numbers. @@ -152389,7 +151728,7 @@ type: long -- -*`threatintel.misp.context.attribute.timestamp`*:: +*`misp.context.attribute.timestamp`*:: + -- The timestamp in which the secondary attribute was attached to the event object. @@ -152399,7 +151738,7 @@ type: date -- -*`threatintel.misp.context.attribute.comment`*:: +*`misp.context.attribute.comment`*:: + -- Comments made to the secondary attribute itself. @@ -152409,7 +151748,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.sharing_group_id`*:: +*`misp.context.attribute.sharing_group_id`*:: + -- The group ID of the sharing group related to the specific secondary attribute. @@ -152419,7 +151758,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.deleted`*:: +*`misp.context.attribute.deleted`*:: + -- If the secondary attribute has been removed from the event object. @@ -152429,7 +151768,7 @@ type: boolean -- -*`threatintel.misp.context.attribute.disable_correlation`*:: +*`misp.context.attribute.disable_correlation`*:: + -- If correlation has been enabled on the secondary attribute related to the event object. @@ -152439,7 +151778,7 @@ type: boolean -- -*`threatintel.misp.context.attribute.object_id`*:: +*`misp.context.attribute.object_id`*:: + -- The ID of the Object in which the secondary attribute is attached. @@ -152449,7 +151788,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.object_relation`*:: +*`misp.context.attribute.object_relation`*:: + -- The type of relation the secondary attribute has with the event object itself. @@ -152459,7 +151798,7 @@ type: keyword -- -*`threatintel.misp.context.attribute.value`*:: +*`misp.context.attribute.value`*:: + -- The value of the attribute, depending on the type like "url, sha1, email-src". @@ -152476,7 +151815,7 @@ Fields for OTX Threat Intel -*`threatintel.otx.id`*:: +*`otx.id`*:: + -- The ID of the indicator. @@ -152486,7 +151825,7 @@ type: keyword -- -*`threatintel.otx.indicator`*:: +*`otx.indicator`*:: + -- The value of the indicator, for example if the type is domain, this would be the value. @@ -152496,7 +151835,7 @@ type: keyword -- -*`threatintel.otx.description`*:: +*`otx.description`*:: + -- A description of the indicator. @@ -152506,7 +151845,7 @@ type: keyword -- -*`threatintel.otx.title`*:: +*`otx.title`*:: + -- Title describing the indicator. @@ -152516,7 +151855,7 @@ type: keyword -- -*`threatintel.otx.content`*:: +*`otx.content`*:: + -- Extra text or descriptive content related to the indicator. @@ -152526,7 +151865,7 @@ type: keyword -- -*`threatintel.otx.type`*:: +*`otx.type`*:: + -- The indicator type, can for example be "domain, email, FileHash-SHA256". @@ -152550,7 +151889,7 @@ Entity that represents a threat. -*`threatintel.recordedfuture.entity.id`*:: +*`recordedfuture.entity.id`*:: + -- Entity ID. @@ -152562,7 +151901,7 @@ example: ip:192.0.2.13 -- -*`threatintel.recordedfuture.entity.name`*:: +*`recordedfuture.entity.name`*:: + -- Entity name. Value for the entity. @@ -152574,7 +151913,7 @@ example: 192.0.2.13 -- -*`threatintel.recordedfuture.entity.type`*:: +*`recordedfuture.entity.type`*:: + -- Entity type. @@ -152586,7 +151925,7 @@ example: IpAddress -- -*`threatintel.recordedfuture.intelCard`*:: +*`recordedfuture.intelCard`*:: + -- Link to the Recorded Future Intelligence Card for to this indicator. @@ -152596,7 +151935,7 @@ type: keyword -- -*`threatintel.recordedfuture.ip_range`*:: +*`recordedfuture.ip_range`*:: + -- Range of IPs for this indicator. @@ -152615,7 +151954,7 @@ Risk fields. -*`threatintel.recordedfuture.risk.criticality`*:: +*`recordedfuture.risk.criticality`*:: + -- Risk criticality (0-4). @@ -152625,7 +151964,7 @@ type: byte -- -*`threatintel.recordedfuture.risk.criticalityLabel`*:: +*`recordedfuture.risk.criticalityLabel`*:: + -- Risk criticality label. One of None, Unusual, Suspicious, Malicious, Very Malicious. @@ -152635,7 +151974,7 @@ type: keyword -- -*`threatintel.recordedfuture.risk.evidenceDetails`*:: +*`recordedfuture.risk.evidenceDetails`*:: + -- Risk's evidence details. @@ -152645,7 +151984,7 @@ type: flattened -- -*`threatintel.recordedfuture.risk.score`*:: +*`recordedfuture.risk.score`*:: + -- Risk score (0-99). @@ -152655,7 +151994,7 @@ type: short -- -*`threatintel.recordedfuture.risk.riskString`*:: +*`recordedfuture.risk.riskString`*:: + -- Number of Risk Rules observed as a factor of total number of rules. @@ -152667,7 +152006,7 @@ example: 1/54 -- -*`threatintel.recordedfuture.risk.riskSummary`*:: +*`recordedfuture.risk.riskSummary`*:: + -- Risk summary. @@ -152679,14 +152018,14 @@ example: 1 of 54 Risk Rules currently observed. -- -*`threatintel.recordedfuture.risk.riskSummary.text`*:: +*`recordedfuture.risk.riskSummary.text`*:: + -- type: text -- -*`threatintel.recordedfuture.risk.rules`*:: +*`recordedfuture.risk.rules`*:: + -- Number of rules observed. @@ -152703,7 +152042,7 @@ Fields for ThreatQ Threat Library -*`threatintel.threatq.updated_at`*:: +*`threatq.updated_at`*:: + -- Last modification time @@ -152713,7 +152052,7 @@ type: date -- -*`threatintel.threatq.created_at`*:: +*`threatq.created_at`*:: + -- Object creation time @@ -152723,7 +152062,7 @@ type: date -- -*`threatintel.threatq.expires_at`*:: +*`threatq.expires_at`*:: + -- Expiration time @@ -152733,7 +152072,7 @@ type: date -- -*`threatintel.threatq.expires_calculated_at`*:: +*`threatq.expires_calculated_at`*:: + -- Expiration calculation time @@ -152743,7 +152082,7 @@ type: date -- -*`threatintel.threatq.published_at`*:: +*`threatq.published_at`*:: + -- Object publication time @@ -152753,7 +152092,7 @@ type: date -- -*`threatintel.threatq.status`*:: +*`threatq.status`*:: + -- Object status within the Threat Library @@ -152763,7 +152102,7 @@ type: keyword -- -*`threatintel.threatq.indicator_value`*:: +*`threatq.indicator_value`*:: + -- Original indicator value @@ -152773,7 +152112,7 @@ type: keyword -- -*`threatintel.threatq.adversaries`*:: +*`threatq.adversaries`*:: + -- Adversaries that are linked to the object @@ -152783,7 +152122,7 @@ type: keyword -- -*`threatintel.threatq.attributes`*:: +*`threatq.attributes`*:: + -- These provide additional context about an object diff --git a/filebeat/docs/modules/threatintel.asciidoc b/filebeat/docs/modules/threatintel.asciidoc index a05384ff4462..b8b5b6f950db 100644 --- a/filebeat/docs/modules/threatintel.asciidoc +++ b/filebeat/docs/modules/threatintel.asciidoc @@ -17,7 +17,7 @@ https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-ind Match rules], but is also compatible with other features like https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html[Enrich Processors]. The related threat intel attribute that is meant to be used for -matching incoming source data is stored under the `threatintel.indicator.*` +matching incoming source data is stored under the `threat.indicator.*` fields. The available filesets are: @@ -73,9 +73,9 @@ Abuse.ch URL Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================== | URL Threat Intel Fields | ECS Fields -| url | threatintel.indicator.url.full +| url | threat.indicator.url.full | date_added | @timestamp -| host | threatintel.indicator.ip/domain +| host | threat.indicator.ip/domain |============================================================== [[abusemalware]] @@ -117,9 +117,9 @@ Abuse.ch Malware Threat Intel is mapped to the following ECS fields. [options="header"] |================================================================ | Malware Threat IntelFields | ECS Fields -| md5_hash | threatintel.indicator.file.hash.md5 -| sha256_hash | threatintel.indicator.file.hash.sha256 -| file_size | threatintel.indicator.file.size +| md5_hash | threat.indicator.file.hash.md5 +| sha256_hash | threat.indicator.file.hash.sha256 +| file_size | threat.indicator.file.size |================================================================ [[malwarebazaar]] @@ -161,24 +161,25 @@ Malware Bazaar Threat Intel is mapped to the following ECS fields. [options="header"] |================================================================ | Malware Threat IntelFields | ECS Fields -| md5_hash | threatintel.indicator.file.hash.md5 -| sha256_hash | threatintel.indicator.file.hash.sha256 -| tlsh | threatintel.indicator.file.hash.tlsh -| ssdeep | threatintel.indicator.file.hash.ssdeep -| imphash | threatintel.indicator.file.pe.imphash -| file_size | threatintel.indicator.file.size -| file_name | threatintel.indicator.file.name -| file_type_mime | threatintel.indicator.file.mime_type -| file_type | threatintel.indicator.file.type -| reporter | threatintel.indicator.provider -| origin_country | threatintel.indicator.geo.country_iso_code -| signature | threatintel.indicator.signature -| code_sign.subject_cn | threatintel.indicator.file.x509.subject.common_name -| code_sign.issuer_cn | threatintel.indicator.file.x509.issuer.common_name -| code_sign.algorithm | threatintel.indicator.file.x509.public_key_algorithm -| code_sign.valid_from | threatintel.indicator.file.x509.not_before -| code_sign.valid_to | threatintel.indicator.file.x509.not_after -| code_sign.serial_number | threatintel.indicator.file.x509.serial_number +| md5_hash | threat.indicator.file.hash.md5 +| sha256_hash | threat.indicator.file.hash.sha256 +| sha384_hash | threat.indicator.file.hash.sha384 +| tlsh | threat.indicator.file.hash.tlsh +| ssdeep | threat.indicator.file.hash.ssdeep +| imphash | threat.indicator.file.pe.imphash +| file_size | threat.indicator.file.size +| file_name | threat.indicator.file.name +| file_type_mime | threat.indicator.file.mime_type +| file_type | threat.indicator.file.type +| reporter | threat.indicator.provider +| origin_country | threat.indicator.geo.country_iso_code +| signature | threat.indicator.signature +| code_sign.subject_cn | threat.indicator.file.x509.subject.common_name +| code_sign.issuer_cn | threat.indicator.file.x509.issuer.common_name +| code_sign.algorithm | threat.indicator.file.x509.public_key_algorithm +| code_sign.valid_from | threat.indicator.file.x509.not_before +| code_sign.valid_to | threat.indicator.file.x509.not_after +| code_sign.serial_number | threat.indicator.file.x509.serial_number |================================================================ [[misp]] @@ -255,10 +256,10 @@ MISP Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================== | Malware Threat IntelFields | ECS Fields -| misp.first_seen | threatintel.indicator.first_seen -| misp.last_seen | threatintel.indicator.last_seen +| misp.first_seen | threat.indicator.first_seen +| misp.last_seen | threat.indicator.last_seen | misp.tag | tag -| misp.value | threatintel.indicator.* +| misp.value | threat.indicator.* |============================================================== `misp.value` is mapped to the appropriate field dependent on attribute type. @@ -336,9 +337,9 @@ OTX Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================ | Malware Threat Intel Fields | ECS Fields -| otx.type | threatintel.indicator.type -| otx.description | threatintel.indicator.description -| otx.indicator | threatintel.indicator.* +| otx.type | threat.indicator.type +| otx.description | threat.indicator.description +| otx.indicator | threat.indicator.* |============================================================ `otx.indicator` is mapped to the appropriate field dependent on attribute type. @@ -420,10 +421,10 @@ Anomali Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================= | Malware Threat Intel Fields | ECS Fields -| anomali.description | threatintel.indicator.description -| anomali.created | threatintel.indicator.first_seen -| anomali.modified | threatintel.indicator.last_seen -| anomali.pattern | threatintel.indicator.* +| anomali.description | threat.indicator.description +| anomali.created | threat.indicator.first_seen +| anomali.modified | threat.indicator.last_seen +| anomali.pattern | threat.indicator.* | anomali.labels | tags |============================================================= @@ -491,24 +492,24 @@ Anomali ThreatStream fields are mapped to the following ECS fields: [options="header"] |============================================================= | ThreatStream fields | ECS Fields -| asn | threatintel.indicator.as.number -| classification<> | threatintel.indicator.marking.tlp -| confidence<> | threatintel.indicator.confidence -| country | threatintel.indicator.geo.country_iso_code -| date_first | threatintel.indicator.first_seen -| date_last | threatintel.indicator.last_seen +| asn | threat.indicator.as.number +| classification<> | threat.indicator.marking.tlp +| confidence<> | threat.indicator.confidence +| country | threat.indicator.geo.country_iso_code +| date_first | threat.indicator.first_seen +| date_last | threat.indicator.last_seen | detail | tags -| domain | threatintel.indicator.url.domain -| email | threatintel.indicator.email.address -| itype<> | threatintel.indicator.type -| lat | threatintel.indicator.geo.location.lat -| lon | threatintel.indicator.geo.location.lon -| md5 | threatintel.indicator.file.hash -| org | threatintel.indicator.as.organization.name +| domain | threat.indicator.url.domain +| email | threat.indicator.email.address +| itype<> | threat.indicator.type +| lat | threat.indicator.geo.location.lat +| lon | threat.indicator.geo.location.lon +| md5 | threat.indicator.file.hash +| org | threat.indicator.as.organization.name | severity<> | event.severity -| source | threatintel.indicator.provider -| srcip | threatintel.indicator.ip -| url | threatintel.indicator.url.original +| source | threat.indicator.provider +| srcip | threat.indicator.ip +| url | threat.indicator.url.original |============================================================= [[a]] @@ -590,16 +591,16 @@ Recorded Future fields are mapped to the following ECS fields: [options="header"] |============================================================= | Recorded Future fields | ECS Fields -| entity.name | threatintel.indicator.{url,ip,domain,file.hash} -| entity.type | threatintel.indicator.type -| fileHashes | threatintel.indicator.file.hash +| entity.name | threat.indicator.{url,ip,domain,file.hash} +| entity.type | threat.indicator.type +| fileHashes | threat.indicator.file.hash | intelCard | event.reference -| location.asn | threatintel.indicator.as.number -| location.location | threatintel.indicator.geo -| location.organization | threatintel.indicator.as.organization.name +| location.asn | threat.indicator.as.number +| location.location | threat.indicator.geo +| location.organization | threat.indicator.as.organization.name | risk.score | event.risk_score -| timestamps.firstSeen | threatintel.indicator.first_seen -| timestamps.lastSeen | threatintel.indicator.last_seen +| timestamps.firstSeen | threat.indicator.first_seen +| timestamps.lastSeen | threat.indicator.last_seen |============================================================= :has-dashboards!: @@ -707,11 +708,11 @@ Recorded Future fields are mapped to the following ECS fields: [options="header"] |============================================================= | ThreatQ fields | ECS Fields -| type.name | threatintel.indicator.type -| description | threatintel.indicator.description -| score | threatintel.indicator.confidence -| value | threatintel.indicator.{url,ip,domain,file.hash} -| sources | threatintel.indicator.provider +| type.name | threat.indicator.type +| description | threat.indicator.description +| score | threat.indicator.confidence +| value | threat.indicator.{url,ip,domain,file.hash} +| sources | threat.indicator.provider |============================================================= :has-dashboards!: diff --git a/x-pack/filebeat/module/threatintel/_meta/docs.asciidoc b/x-pack/filebeat/module/threatintel/_meta/docs.asciidoc index a7acdb5f4bd3..18c8d57e169d 100644 --- a/x-pack/filebeat/module/threatintel/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/threatintel/_meta/docs.asciidoc @@ -12,7 +12,7 @@ https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-ind Match rules], but is also compatible with other features like https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html[Enrich Processors]. The related threat intel attribute that is meant to be used for -matching incoming source data is stored under the `threatintel.indicator.*` +matching incoming source data is stored under the `threat.indicator.*` fields. The available filesets are: @@ -68,9 +68,9 @@ Abuse.ch URL Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================== | URL Threat Intel Fields | ECS Fields -| url | threatintel.indicator.url.full +| url | threat.indicator.url.full | date_added | @timestamp -| host | threatintel.indicator.ip/domain +| host | threat.indicator.ip/domain |============================================================== [[abusemalware]] @@ -112,9 +112,9 @@ Abuse.ch Malware Threat Intel is mapped to the following ECS fields. [options="header"] |================================================================ | Malware Threat IntelFields | ECS Fields -| md5_hash | threatintel.indicator.file.hash.md5 -| sha256_hash | threatintel.indicator.file.hash.sha256 -| file_size | threatintel.indicator.file.size +| md5_hash | threat.indicator.file.hash.md5 +| sha256_hash | threat.indicator.file.hash.sha256 +| file_size | threat.indicator.file.size |================================================================ [[malwarebazaar]] @@ -156,24 +156,25 @@ Malware Bazaar Threat Intel is mapped to the following ECS fields. [options="header"] |================================================================ | Malware Threat IntelFields | ECS Fields -| md5_hash | threatintel.indicator.file.hash.md5 -| sha256_hash | threatintel.indicator.file.hash.sha256 -| tlsh | threatintel.indicator.file.hash.tlsh -| ssdeep | threatintel.indicator.file.hash.ssdeep -| imphash | threatintel.indicator.file.pe.imphash -| file_size | threatintel.indicator.file.size -| file_name | threatintel.indicator.file.name -| file_type_mime | threatintel.indicator.file.mime_type -| file_type | threatintel.indicator.file.type -| reporter | threatintel.indicator.provider -| origin_country | threatintel.indicator.geo.country_iso_code -| signature | threatintel.indicator.signature -| code_sign.subject_cn | threatintel.indicator.file.x509.subject.common_name -| code_sign.issuer_cn | threatintel.indicator.file.x509.issuer.common_name -| code_sign.algorithm | threatintel.indicator.file.x509.public_key_algorithm -| code_sign.valid_from | threatintel.indicator.file.x509.not_before -| code_sign.valid_to | threatintel.indicator.file.x509.not_after -| code_sign.serial_number | threatintel.indicator.file.x509.serial_number +| md5_hash | threat.indicator.file.hash.md5 +| sha256_hash | threat.indicator.file.hash.sha256 +| sha384_hash | threat.indicator.file.hash.sha384 +| tlsh | threat.indicator.file.hash.tlsh +| ssdeep | threat.indicator.file.hash.ssdeep +| imphash | threat.indicator.file.pe.imphash +| file_size | threat.indicator.file.size +| file_name | threat.indicator.file.name +| file_type_mime | threat.indicator.file.mime_type +| file_type | threat.indicator.file.type +| reporter | threat.indicator.provider +| origin_country | threat.indicator.geo.country_iso_code +| signature | threat.indicator.signature +| code_sign.subject_cn | threat.indicator.file.x509.subject.common_name +| code_sign.issuer_cn | threat.indicator.file.x509.issuer.common_name +| code_sign.algorithm | threat.indicator.file.x509.public_key_algorithm +| code_sign.valid_from | threat.indicator.file.x509.not_before +| code_sign.valid_to | threat.indicator.file.x509.not_after +| code_sign.serial_number | threat.indicator.file.x509.serial_number |================================================================ [[misp]] @@ -250,10 +251,10 @@ MISP Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================== | Malware Threat IntelFields | ECS Fields -| misp.first_seen | threatintel.indicator.first_seen -| misp.last_seen | threatintel.indicator.last_seen +| misp.first_seen | threat.indicator.first_seen +| misp.last_seen | threat.indicator.last_seen | misp.tag | tag -| misp.value | threatintel.indicator.* +| misp.value | threat.indicator.* |============================================================== `misp.value` is mapped to the appropriate field dependent on attribute type. @@ -331,9 +332,9 @@ OTX Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================ | Malware Threat Intel Fields | ECS Fields -| otx.type | threatintel.indicator.type -| otx.description | threatintel.indicator.description -| otx.indicator | threatintel.indicator.* +| otx.type | threat.indicator.type +| otx.description | threat.indicator.description +| otx.indicator | threat.indicator.* |============================================================ `otx.indicator` is mapped to the appropriate field dependent on attribute type. @@ -415,10 +416,10 @@ Anomali Threat Intel is mapped to the following ECS fields. [options="header"] |============================================================= | Malware Threat Intel Fields | ECS Fields -| anomali.description | threatintel.indicator.description -| anomali.created | threatintel.indicator.first_seen -| anomali.modified | threatintel.indicator.last_seen -| anomali.pattern | threatintel.indicator.* +| anomali.description | threat.indicator.description +| anomali.created | threat.indicator.first_seen +| anomali.modified | threat.indicator.last_seen +| anomali.pattern | threat.indicator.* | anomali.labels | tags |============================================================= @@ -486,24 +487,24 @@ Anomali ThreatStream fields are mapped to the following ECS fields: [options="header"] |============================================================= | ThreatStream fields | ECS Fields -| asn | threatintel.indicator.as.number -| classification<> | threatintel.indicator.marking.tlp -| confidence<> | threatintel.indicator.confidence -| country | threatintel.indicator.geo.country_iso_code -| date_first | threatintel.indicator.first_seen -| date_last | threatintel.indicator.last_seen +| asn | threat.indicator.as.number +| classification<> | threat.indicator.marking.tlp +| confidence<> | threat.indicator.confidence +| country | threat.indicator.geo.country_iso_code +| date_first | threat.indicator.first_seen +| date_last | threat.indicator.last_seen | detail | tags -| domain | threatintel.indicator.url.domain -| email | threatintel.indicator.email.address -| itype<> | threatintel.indicator.type -| lat | threatintel.indicator.geo.location.lat -| lon | threatintel.indicator.geo.location.lon -| md5 | threatintel.indicator.file.hash -| org | threatintel.indicator.as.organization.name +| domain | threat.indicator.url.domain +| email | threat.indicator.email.address +| itype<> | threat.indicator.type +| lat | threat.indicator.geo.location.lat +| lon | threat.indicator.geo.location.lon +| md5 | threat.indicator.file.hash +| org | threat.indicator.as.organization.name | severity<> | event.severity -| source | threatintel.indicator.provider -| srcip | threatintel.indicator.ip -| url | threatintel.indicator.url.original +| source | threat.indicator.provider +| srcip | threat.indicator.ip +| url | threat.indicator.url.original |============================================================= [[a]] @@ -585,16 +586,16 @@ Recorded Future fields are mapped to the following ECS fields: [options="header"] |============================================================= | Recorded Future fields | ECS Fields -| entity.name | threatintel.indicator.{url,ip,domain,file.hash} -| entity.type | threatintel.indicator.type -| fileHashes | threatintel.indicator.file.hash +| entity.name | threat.indicator.{url,ip,domain,file.hash} +| entity.type | threat.indicator.type +| fileHashes | threat.indicator.file.hash | intelCard | event.reference -| location.asn | threatintel.indicator.as.number -| location.location | threatintel.indicator.geo -| location.organization | threatintel.indicator.as.organization.name +| location.asn | threat.indicator.as.number +| location.location | threat.indicator.geo +| location.organization | threat.indicator.as.organization.name | risk.score | event.risk_score -| timestamps.firstSeen | threatintel.indicator.first_seen -| timestamps.lastSeen | threatintel.indicator.last_seen +| timestamps.firstSeen | threat.indicator.first_seen +| timestamps.lastSeen | threat.indicator.last_seen |============================================================= :has-dashboards!: @@ -702,11 +703,11 @@ Recorded Future fields are mapped to the following ECS fields: [options="header"] |============================================================= | ThreatQ fields | ECS Fields -| type.name | threatintel.indicator.type -| description | threatintel.indicator.description -| score | threatintel.indicator.confidence -| value | threatintel.indicator.{url,ip,domain,file.hash} -| sources | threatintel.indicator.provider +| type.name | threat.indicator.type +| description | threat.indicator.description +| score | threat.indicator.confidence +| value | threat.indicator.{url,ip,domain,file.hash} +| sources | threat.indicator.provider |============================================================= :has-dashboards!: diff --git a/x-pack/filebeat/module/threatintel/_meta/fields.yml b/x-pack/filebeat/module/threatintel/_meta/fields.yml index ee199daa6aa2..5fb56abc40ae 100644 --- a/x-pack/filebeat/module/threatintel/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/_meta/fields.yml @@ -4,388 +4,21 @@ description: > Threat intelligence Filebeat Module. fields: - - name: threatintel + - name: "" type: group - description: > - Fields from the threatintel Filebeat module. fields: - - name: indicator.first_seen - type: date - description: > - The date and time when intelligence source first reported sighting this indicator. - - name: indicator.last_seen - type: date - description: > - The date and time when intelligence source last reported sighting this indicator. - - name: indicator.sightings - type: long - description: > - Number of times this indicator was observed conducting threat activity. - - name: indicator.type + - name: threat.indicator.file.hash.tlsh type: keyword description: > - Type of indicator as represented by Cyber Observable in STIX 2.0. - Expected values - * autonomous-system - * artifact - * directory - * domain-name - * email-addr - * file - * ipv4-addr - * ipv6-addr - * mac-addr - * mutex - * process - * software - * url - * user-account - * windows-registry-key - * x-509-certificate - - name: indicator.description - type: keyword - description: > - Describes the type of action conducted by the threat. - - name: indicator.scanner_stats - type: long - description: > - Count of AV/EDR vendors that successfully detected malicious file or URL. - - name: indicator.provider + The file's import tlsh, if available. + + - name: threat.indicator.file.hash.sha384 type: keyword description: > - Identifies the name of the intelligence provider. - - name: indicator.confidence + The file's sha384 hash, if available. + + - name: threat.feed.name type: keyword - description: > - Identifies the confidence rating assigned by the provider using STIX confidence scales. - Expected values - * Not Specified, None, Low, Medium, High - * 0-10 - * Admirality Scale (1-6) - * DNI Scale (5-95) - * WEP Scale (Impossible - Certain) - - name: indicator.module - type: keyword - description: > - Identifies the name of specific module this data is coming from. - - name: indicator.dataset - type: keyword - description: > - Identifies the name of specific dataset from the intelligence source. - - name: indicator.reference + + - name: threat.feed.dashboard_id type: keyword - description: > - Reference URL linking to additional information about this indicator. - - name: indicator.ip - type: ip - description: > - Identifies a threat indicator as an IP address (irrespective of direction). - - name: indicator.port - type: long - description: > - Identifies a threat indicator as a port number (irrespective of direction). - - name: indicator.email.address - type: keyword - description: > - Identifies a threat indicator as an email address (irrespective of direction). - - name: indicator.marking.tlp - type: keyword - description: > - Traffic Light Protocol sharing markings. - Expected values are: - * White - * Green - * Amber - * Red - - name: indicator.matched - type: group - fields: - - name: atomic - type: keyword - description: > - Identifies the atomic indicator that matched a local environment endpoint or network event. - - name: field - type: keyword - description: > - Identifies the field of the atomic indicator that matched a local environment endpoint or network event. - - name: type - type: keyword - description: > - Identifies the type of the atomic indicator that matched a local environment endpoint or network event. - - name: indicator.as - type: group - fields: - - name: number - type: long - description: - Unique number allocated to the autonomous system. The autonomous system number (ASN) - uniquely identifies each network on the Internet. - example: 15169 - - name: organization.name - type: keyword - ignore_above: 1024 - multi_fields: - - name: text - type: text - norms: false - description: Organization name. - example: Google LLC - - name: indicator.registry - type: group - fields: - - name: data.strings - type: keyword - ignore_above: 1024 - description: > - Content when writing string types. - Populated as an array when writing string data to the registry. For single - string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with - one string. For sequences of string with REG_MULTI_SZ, this array will be - variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should - be populated with the decimal representation (e.g `"1"`). - example: '["C:\rta\red_ttp\bin\myapp.exe"]' - - name: path - type: keyword - ignore_above: 1024 - description: Full path, including hive, key and value - example: - HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution - Options\winword.exe\Debugger - - name: value - type: keyword - ignore_above: 1024 - description: Name of the value written. - example: Debugger - - name: key - type: keyword - ignore_above: 1024 - description: Registry key value - - name: indicator.geo - type: group - fields: - - name: city_name - type: keyword - ignore_above: 1024 - description: City name. - example: Montreal - - name: continent_name - type: keyword - ignore_above: 1024 - description: Name of the continent. - example: North America - - name: country_iso_code - type: keyword - ignore_above: 1024 - description: Country ISO code. - example: CA - - name: country_name - type: keyword - ignore_above: 1024 - description: Country name. - example: Canada - - name: location - type: geo_point - description: Longitude and latitude. - example: '{ "lon": -73.614830, "lat": 45.505918 }' - - name: region_iso_code - type: keyword - ignore_above: 1024 - description: Region ISO code. - example: CA-QC - - name: region_name - type: keyword - ignore_above: 1024 - description: Region name. - example: Quebec - - name: indicator.file.pe.imphash - type: keyword - ignore_above: 1024 - description: - "A hash of the imports in a PE file. An imphash -- or import hash - -- can be used to fingerprint binaries even after recompilation or other code-level - transformations have occurred, which would change more traditional hash values. - Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html." - example: 0c6803c4e922103c4dca5963aad36ddf - - name: indicator.file - type: group - fields: - - name: hash - type: group - fields: - - name: tlsh - type: keyword - description: > - The file's import tlsh, if available. - - name: ssdeep - type: keyword - description: > - The file's ssdeep hash, if available. - - name: md5 - type: keyword - description: > - The file's md5 hash, if available. - - name: sha1 - type: keyword - description: > - The file's sha1 hash, if available. - - name: sha256 - type: keyword - description: > - The file's sha256 hash, if available. - - name: sha384 - type: keyword - description: > - The file's sha384 hash, if available. - - name: sha512 - type: keyword - description: > - The file's sha512 hash, if available. - - name: type - type: keyword - ignore_above: 1024 - description: > - The file type. - - name: size - type: long - description: > - The file's total size. - - name: name - type: keyword - description: > - The file's name. - - name: extension - type: keyword - description: > - The file's extension. - - name: mime_type - type: keyword - description: > - The file's MIME type. - - name: indicator.url - type: group - fields: - - name: domain - type: keyword - description: > - Domain of the url, such as "www.elastic.co". - - name: extension - type: keyword - ignore_above: 1024 - description: > - The field contains the file extension from the original request - - name: fragment - type: keyword - ignore_above: 1024 - description: > - Portion of the url after the `#`, such as "top". - - name: full - type: keyword - description: > - If full URLs are important to your use case, they should be stored - in `url.full`, whether this field is reconstructed or present in the event - source. - - name: original - type: keyword - description: > - Unmodified original url as seen in the event source. - Note that in network monitoring, the observed URL may be a full URL, whereas - in access logs, the URL is often just represented as a path. - This field is meant to represent the URL as it was observed, complete or not. - - name: password - type: keyword - ignore_above: 1024 - description: > - Password of the request. - - name: path - type: keyword - description: > - Path of the request, such as "/search". - - name: port - type: long - format: string - description: > - Port of the request, such as 443. - - name: query - type: keyword - ignore_above: 1024 - description: > - The query field describes the query string of the request, such - as "q=elasticsearch". - The `?` is excluded from the query string. If a URL contains no `?`, there - is no query field. If there is a `?` but no query, the query field exists - with an empty string. The `exists` query can be used to differentiate between - the two cases. - - name: registered_domain - type: keyword - description: > - The highest registered url domain, stripped of the subdomain. - For example, the registered domain for "foo.example.com" is "example.com". - This value can be determined precisely with a list like the public suffix - list (http://publicsuffix.org). Trying to approximate this by simply taking - the last two labels will not work well for TLDs such as "co.uk". - - name: scheme - type: keyword - ignore_above: 1024 - description: > - Scheme of the request, such as "https". - - name: subdomain - type: keyword - ignore_above: 1024 - description: > - The subdomain portion of a fully qualified domain name includes - all of the names except the host name under the registered_domain. In a partially - qualified domain, or if the the qualification level of the full name cannot - be determined, subdomain contains all of the names below the registered domain. - For example the subdomain portion of "www.east.mydomain.co.uk" is "east". - If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", - the subdomain field should contain "sub2.sub1", with no trailing period. - - name: top_level_domain - type: keyword - ignore_above: 1024 - description: > - The effective top level domain (eTLD), also known as the domain - suffix, is the last part of the domain name. For example, the top level domain - for example.com is "com". - This value can be determined precisely with a list like the public suffix - list (http://publicsuffix.org). Trying to approximate this by simply taking - the last label will not work well for effective TLDs such as "co.uk". - - name: username - type: keyword - ignore_above: 1024 - description: > - Username of the request. - - name: indicator.x509 - type: group - fields: - - name: serial_number - type: keyword - ignore_above: 1024 - description: - Unique serial number issued by the certificate authority. For consistency, - if this value is alphanumeric, it should be formatted without colons and uppercase - characters. - example: 55FBB9C7DEBF09809D12CCAA - - name: issuer - type: keyword - ignore_above: 1024 - description: Name of issuing certificate authority. Could be either Distinguished Name (DN) or Common Name (CN), depending on source. - example: - C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance - Server CA - - name: subject - type: keyword - ignore_above: 1024 - description: Name of the certificate subject entity. Could be either Distinguished Name (DN) or Common Name (CN), depending on source. - example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - - name: alternative_names - type: keyword - ignore_above: 1024 - description: - List of subject alternative names (SAN). Name types vary by certificate - authority and certificate type but commonly contain IP addresses, DNS names - (and wildcards), and email addresses. - example: "*.elastic.co" - - name: indicator.signature - type: keyword - description: > - Malware family of sample (if available). diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/021ba940-de96-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/021ba940-de96-11eb-8f2b-753caedf727d.json index 993d2edcccec..91a5cc790189 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/021ba940-de96-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/021ba940-de96-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.type" + "sourceField": "threat.indicator.type" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -96,4 +96,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/028175a0-ff74-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/028175a0-ff74-11eb-acb2-2960a7069ed1.json index 147220191069..c6ef974933ed 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/028175a0-ff74-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/028175a0-ff74-11eb-acb2-2960a7069ed1.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.provider" + "sourceField": "threat.indicator.provider" }, "11576d1f-5400-4a71-bf04-681099e755d5": { "dataType": "number", @@ -95,4 +95,4 @@ "type": "lens", "updated_at": "2021-10-11T08:02:55.512Z", "version": "WzUyOSwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/037e2af0-df50-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/037e2af0-df50-11eb-8f2b-753caedf727d.json index 5be6f447603d..0c6776687197 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/037e2af0-df50-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/037e2af0-df50-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.type" + "sourceField": "threat.indicator.type" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -96,4 +96,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NjIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/06744e90-df52-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/06744e90-df52-11eb-8f2b-753caedf727d.json index b427db18d513..38b8c85420ee 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/06744e90-df52-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/06744e90-df52-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.ip" + "sourceField": "threat.indicator.ip" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -47,7 +47,7 @@ "filters": [], "query": { "language": "kuery", - "query": "event.dataset:\"threatintel.recordedfuture\" and threatintel.indicator.type:ipv6-addr" + "query": "event.dataset:\"threatintel.recordedfuture\" and threat.indicator.type:ipv6-addr" }, "visualization": { "columns": [ @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/0db62ee0-72e6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/0db62ee0-72e6-11eb-a3e3-b3cc7c78a70f.json index a053c190ada5..b4182474c234 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/0db62ee0-72e6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/0db62ee0-72e6-11eb-a3e3-b3cc7c78a70f.json @@ -14,7 +14,7 @@ "959db113-1ce6-46fc-97c3-dbf5fd5abb9a": { "dataType": "string", "isBucketed": true, - "label": "Top values of threatintel.abusemalware.signature", + "label": "Top values of abusech.malware.signature", "operationType": "terms", "params": { "missingBucket": false, @@ -27,7 +27,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.abusemalware.signature" + "sourceField": "abusech.malware.signature" }, "de396547-655b-4db2-8a21-e9850acff0b0": { "dataType": "number", @@ -91,13 +91,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abusemalware.signature" + "field": "abusech.malware.signature" }, "meta": { "alias": null, "disabled": false, "indexRefName": "filter-index-pattern-2", - "key": "threatintel.abusemalware.signature", + "key": "abusech.malware.signature", "negate": false, "type": "exists", "value": "exists" @@ -168,4 +168,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/1136ceb0-de95-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/1136ceb0-de95-11eb-8f2b-753caedf727d.json index 05d17760abc8..c771588f9243 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/1136ceb0-de95-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/1136ceb0-de95-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.resource_uri" + "sourceField": "anomali.threatstream.resource_uri" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/139c7da0-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/139c7da0-df51-11eb-8f2b-753caedf727d.json index d8abec34b65a..e2269eea6d9f 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/139c7da0-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/139c7da0-df51-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.sha256" + "sourceField": "threat.indicator.file.hash.sha256" } }, "incompleteColumns": {} @@ -90,4 +90,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/36f61650-de96-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/36f61650-de96-11eb-8f2b-753caedf727d.json index e48267b1fd83..86507728c607 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/36f61650-de96-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/36f61650-de96-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.classification" + "sourceField": "anomali.threatstream.classification" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -94,4 +94,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c40f4d0-de97-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c40f4d0-de97-11eb-8f2b-753caedf727d.json index 4f33f959e3a8..bdfbd6b5096f 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c40f4d0-de97-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c40f4d0-de97-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.itype" + "sourceField": "anomali.threatstream.itype" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -94,4 +94,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c996410-df52-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c996410-df52-11eb-8f2b-753caedf727d.json index 88c19ed280d8..da5e6785b5ae 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c996410-df52-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/3c996410-df52-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.domain" + "sourceField": "threat.indicator.url.domain" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5e76ef90-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5e76ef90-df51-11eb-8f2b-753caedf727d.json index 03bafd193b3e..a6fde56bd64e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5e76ef90-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5e76ef90-df51-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.domain" + "sourceField": "threat.indicator.url.domain" } }, "incompleteColumns": {} @@ -90,4 +90,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5ef7b430-de94-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5ef7b430-de94-11eb-8f2b-753caedf727d.json index 88642bb872e3..27fee210ffd6 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5ef7b430-de94-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/5ef7b430-de94-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.ip" + "sourceField": "threat.indicator.ip" } }, "incompleteColumns": {} @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/790cd040-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/790cd040-df51-11eb-8f2b-753caedf727d.json index 2abc0bb73163..781a6a42a396 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/790cd040-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/790cd040-df51-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.original" + "sourceField": "threat.indicator.url.original" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7d9c70f0-de95-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7d9c70f0-de95-11eb-8f2b-753caedf727d.json index dbdc1f05605e..741a17e6b105 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7d9c70f0-de95-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7d9c70f0-de95-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.anomali.name" + "sourceField": "anomali.limo.name" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7ec83f60-de98-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7ec83f60-de98-11eb-8f2b-753caedf727d.json index b321f95bae85..e1b1dfc2fc88 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7ec83f60-de98-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/7ec83f60-de98-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.sha256" + "sourceField": "threat.indicator.file.hash.sha256" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8a6f7b20-de94-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8a6f7b20-de94-11eb-8f2b-753caedf727d.json index 86e2c9697734..16f93c3473bd 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8a6f7b20-de94-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8a6f7b20-de94-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.original" + "sourceField": "threat.indicator.url.original" } }, "incompleteColumns": {} @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8fb01a00-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8fb01a00-df51-11eb-8f2b-753caedf727d.json index be51533efa40..b8cc9578146e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8fb01a00-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/8fb01a00-df51-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.path" + "sourceField": "threat.indicator.url.path" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9282afc0-72d9-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9282afc0-72d9-11eb-a3e3-b3cc7c78a70f.json index 42d14abd0ecb..09935680d662 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9282afc0-72d9-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9282afc0-72d9-11eb-a3e3-b3cc7c78a70f.json @@ -22,7 +22,7 @@ "a6319ec8-2ec8-4d3a-bc54-efe0a306786f": { "dataType": "string", "isBucketed": true, - "label": "Top values of threatintel.indicator.type", + "label": "Top values of threat.indicator.type", "operationType": "terms", "params": { "missingBucket": false, @@ -35,7 +35,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.type" + "sourceField": "threat.indicator.type" } }, "incompleteColumns": {} @@ -70,13 +70,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "filter-index-pattern-1", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -147,4 +147,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NTMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/949bc180-df52-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/949bc180-df52-11eb-8f2b-753caedf727d.json index b4784339ef28..ec09008e580e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/949bc180-df52-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/949bc180-df52-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.recordedfuture.risk.riskSummary" + "sourceField": "recordedfuture.risk.riskSummary" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NjYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/976620a0-de98-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/976620a0-de98-11eb-8f2b-753caedf727d.json index b9d9b336d1e5..7bfea0d313ee 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/976620a0-de98-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/976620a0-de98-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.md5" + "sourceField": "threat.indicator.file.hash.md5" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9c78ade0-de95-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9c78ade0-de95-11eb-8f2b-753caedf727d.json index cb82ae74ba56..b6a60ae06c2e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9c78ade0-de95-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/9c78ade0-de95-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.anomali.description" + "sourceField": "anomali.limo.description" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/a0a31740-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/a0a31740-df51-11eb-8f2b-753caedf727d.json index ce6d74b37635..7a4ccbec7ff2 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/a0a31740-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/a0a31740-df51-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.scheme" + "sourceField": "threat.indicator.url.scheme" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/aac00bc0-de98-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/aac00bc0-de98-11eb-8f2b-753caedf727d.json index 2e80121c2e46..062ccc359f7b 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/aac00bc0-de98-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/aac00bc0-de98-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.sha1" + "sourceField": "threat.indicator.file.hash.sha1" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/ae5934e0-de94-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/ae5934e0-de94-11eb-8f2b-753caedf727d.json index 02719d9dcb0d..17f6d2ccc213 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/ae5934e0-de94-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/ae5934e0-de94-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.url.domain" + "sourceField": "threat.indicator.url.domain" } }, "incompleteColumns": {} @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/b0837690-df52-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/b0837690-df52-11eb-8f2b-753caedf727d.json index c75878031077..2ee5c4b1a2ad 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/b0837690-df52-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/b0837690-df52-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.recordedfuture.risk.criticalityLabel" + "sourceField": "recordedfuture.risk.criticalityLabel" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -94,4 +94,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NjMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bd28cb00-de96-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bd28cb00-de96-11eb-8f2b-753caedf727d.json index ed51bcc85fb6..5f95d44b92dc 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bd28cb00-de96-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bd28cb00-de96-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 3 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.severity" + "sourceField": "anomali.threatstream.severity" } }, "incompleteColumns": {} @@ -98,4 +98,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bfd2bfe0-de97-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bfd2bfe0-de97-11eb-8f2b-753caedf727d.json index 0850075db5bd..c1110d8d6119 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bfd2bfe0-de97-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/bfd2bfe0-de97-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.confidence" + "sourceField": "threat.indicator.confidence" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -94,4 +94,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1NzgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c2a5c180-df51-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c2a5c180-df51-11eb-8f2b-753caedf727d.json index 5915a46aca56..6163c46e0b03 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c2a5c180-df51-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c2a5c180-df51-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.ip" + "sourceField": "threat.indicator.ip" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -47,7 +47,7 @@ "filters": [], "query": { "language": "kuery", - "query": "event.dataset:\"threatintel.recordedfuture\" and threatintel.indicator.type:ipv4-addr" + "query": "event.dataset:\"threatintel.recordedfuture\" and threat.indicator.type:ipv4-addr" }, "visualization": { "columns": [ @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NjksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c91fcd10-de95-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c91fcd10-de95-11eb-8f2b-753caedf727d.json index 63c9a1eebdec..9eecce1a1c33 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c91fcd10-de95-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/c91fcd10-de95-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.provider" + "sourceField": "threat.indicator.provider" } }, "incompleteColumns": {} @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/cf4b4e40-ff69-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/cf4b4e40-ff69-11eb-acb2-2960a7069ed1.json index 0d2bc89d4419..ddb2717dd0e2 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/cf4b4e40-ff69-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/cf4b4e40-ff69-11eb-acb2-2960a7069ed1.json @@ -15,7 +15,7 @@ "73cdbb81-57ca-4474-a86c-bca60a527d29": { "dataType": "string", "isBucketed": true, - "label": "Top values of threatintel.indicator.type", + "label": "Top values of threat.indicator.type", "operationType": "terms", "params": { "missingBucket": false, @@ -28,7 +28,7 @@ "size": 15 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.type" + "sourceField": "threat.indicator.type" }, "89f18519-9360-4d37-ae52-134604ac6cfc": { "customLabel": true, @@ -118,4 +118,4 @@ "type": "lens", "updated_at": "2021-10-11T08:02:55.512Z", "version": "WzUyOCwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/d991e510-de96-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/d991e510-de96-11eb-8f2b-753caedf727d.json index f630743094ff..e718c0983606 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/d991e510-de96-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/d991e510-de96-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.state" + "sourceField": "anomali.threatstream.state" } }, "incompleteColumns": {} @@ -112,4 +112,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/dd4a3da0-df50-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/dd4a3da0-df50-11eb-8f2b-753caedf727d.json index b9b2341c0b1c..4a25b4df0ef6 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/dd4a3da0-df50-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/dd4a3da0-df50-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.md5" + "sourceField": "threat.indicator.file.hash.md5" } }, "incompleteColumns": {} @@ -90,4 +90,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/e5f07800-de94-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/e5f07800-de94-11eb-8f2b-753caedf727d.json index 1985a7273804..03d75c58b2ff 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/e5f07800-de94-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/e5f07800-de94-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.anomalithreatstream.id" + "sourceField": "anomali.threatstream.id" } }, "incompleteColumns": {} @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1OTgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f37f8350-df50-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f37f8350-df50-11eb-8f2b-753caedf727d.json index 45745f96eb07..f4c84cc7426c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f37f8350-df50-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f37f8350-df50-11eb-8f2b-753caedf727d.json @@ -36,7 +36,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.file.hash.sha1" + "sourceField": "threat.indicator.file.hash.sha1" } }, "incompleteColumns": {} @@ -90,4 +90,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:33.127Z", "version": "WzQ2NzIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f52a9720-de93-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f52a9720-de93-11eb-8f2b-753caedf727d.json index a3740f838db9..7e2446f1e8d7 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f52a9720-de93-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f52a9720-de93-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.email.address" + "sourceField": "threat.indicator.email.address" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -91,4 +91,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f5f18940-de96-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f5f18940-de96-11eb-8f2b-753caedf727d.json index c5c7c021b28a..9b281bf47694 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f5f18940-de96-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/lens/f5f18940-de96-11eb-8f2b-753caedf727d.json @@ -28,7 +28,7 @@ "size": 5 }, "scale": "ordinal", - "sourceField": "threatintel.indicator.marking.tlp" + "sourceField": "threat.indicator.marking.tlp" }, "9afb1b09-0f20-488c-9242-a94f7d11800b": { "dataType": "number", @@ -112,4 +112,4 @@ "type": "lens", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/63365b50-82aa-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/63365b50-82aa-11eb-ac13-d5ca87cb8fa2.json index 63e7825a56bc..b37986b02ebb 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/63365b50-82aa-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/63365b50-82aa-11eb-ac13-d5ca87cb8fa2.json @@ -35,7 +35,7 @@ "type": "count" } ], - "term": "threatintel.indicator.geo.country_iso_code", + "term": "threat.indicator.geo.country_iso_code", "type": "ES_TERM_SOURCE" } } @@ -205,4 +205,4 @@ "type": "map", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MTksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/ec5aa090-df42-11eb-8f2b-753caedf727d.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/ec5aa090-df42-11eb-8f2b-753caedf727d.json index 8100b60e6b3d..e5e947525664 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/ec5aa090-df42-11eb-8f2b-753caedf727d.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/map/ec5aa090-df42-11eb-8f2b-753caedf727d.json @@ -29,16 +29,16 @@ "applyGlobalQuery": true, "applyGlobalTime": true, "filterByMapBounds": true, - "geoField": "threatintel.indicator.geo.location", + "geoField": "threat.indicator.geo.location", "id": "a3ecc6af-0299-4cb9-a29c-0b70f666b011", "indexPatternRefName": "layer_1_source_index_pattern", "scalingType": "LIMIT", "sortField": "", "sortOrder": "desc", "tooltipProperties": [ - "threatintel.indicator.as.number", - "threatintel.indicator.as.organization.name", - "threatintel.indicator.geo.country_iso_code" + "threat.indicator.as.number", + "threat.indicator.as.organization.name", + "threat.indicator.geo.country_iso_code" ], "topHitsSize": 1, "topHitsSplitField": "", @@ -195,4 +195,4 @@ "type": "map", "updated_at": "2021-08-04T16:34:28.102Z", "version": "WzQ1ODgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/01c261b0-7aa9-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/01c261b0-7aa9-11eb-ac13-d5ca87cb8fa2.json index 93d283d07e01..3bc7559fbf62 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/01c261b0-7aa9-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/01c261b0-7aa9-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.otx.title" + "field": "otx.title" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.otx.title", + "key": "otx.title", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX Indicator Title", - "field": "threatintel.otx.title", + "field": "otx.title", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NzQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/02294f80-73c7-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/02294f80-73c7-11eb-a3e3-b3cc7c78a70f.json index 822c006ccc2c..ff5c6b0b875e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/02294f80-73c7-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/02294f80-73c7-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha1" + "field": "threat.indicator.file.hash.sha1" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha1", + "key": "threat.indicator.file.hash.sha1", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP SHA1 Hash Indicator", - "field": "threatintel.indicator.file.hash.sha1", + "field": "threat.indicator.file.hash.sha1", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2NDEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/0ccdda50-76ce-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/0ccdda50-76ce-11eb-a3e3-b3cc7c78a70f.json index 1197b8b4a7ea..44b6e23d5533 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/0ccdda50-76ce-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/0ccdda50-76ce-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.md5" + "field": "threat.indicator.file.hash.md5" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.md5", + "key": "threat.indicator.file.hash.md5", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX MD5 Hash Indicator", - "field": "threatintel.indicator.file.hash.md5", + "field": "threat.indicator.file.hash.md5", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NzMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/142fb6c0-82a8-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/142fb6c0-82a8-11eb-ac13-d5ca87cb8fa2.json index bf55ff3b2377..624dde62b61d 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/142fb6c0-82a8-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/142fb6c0-82a8-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha1" + "field": "threat.indicator.file.hash.sha1" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha1", + "key": "threat.indicator.file.hash.sha1", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "SHA1 Hash", - "field": "threatintel.indicator.file.hash.sha1", + "field": "threat.indicator.file.hash.sha1", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a0d5250-72e5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a0d5250-72e5-11eb-a3e3-b3cc7c78a70f.json index f9fc2390a2b3..f43232fe645c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a0d5250-72e5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a0d5250-72e5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha256" + "field": "threat.indicator.file.hash.sha256" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha256", + "key": "threat.indicator.file.hash.sha256", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -84,7 +84,7 @@ "id": "2", "params": { "customLabel": "SHA256 Hash", - "field": "threatintel.indicator.file.hash.sha256", + "field": "threat.indicator.file.hash.sha256", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -101,7 +101,7 @@ "id": "3", "params": { "customLabel": "File Type", - "field": "threatintel.indicator.file.type", + "field": "threat.indicator.file.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -162,4 +162,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a1c60c0-72d5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a1c60c0-72d5-11eb-a3e3-b3cc7c78a70f.json index b2e430cff4c5..e972911d995b 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a1c60c0-72d5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1a1c60c0-72d5-11eb-a3e3-b3cc7c78a70f.json @@ -26,13 +26,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "enabled": true, "id": "3", "params": { - "field": "threatintel.indicator.type", + "field": "threat.indicator.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -143,4 +143,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NDksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1adff580-72ee-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1adff580-72ee-11eb-a3e3-b3cc7c78a70f.json index 711442477602..550140b912fe 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1adff580-72ee-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1adff580-72ee-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.domain" + "field": "threat.indicator.url.domain" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.domain", + "key": "threat.indicator.url.domain", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "Threat Indicator Domain", - "field": "threatintel.indicator.domain", + "field": "threat.indicator.url.domain", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1c969990-73c7-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1c969990-73c7-11eb-a3e3-b3cc7c78a70f.json index e2f3d6fda091..e77a6cee76be 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1c969990-73c7-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1c969990-73c7-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha256" + "field": "threat.indicator.file.hash.sha256" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha256", + "key": "threat.indicator.file.hash.sha256", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP SHA256 Hash Indicator", - "field": "threatintel.indicator.file.hash.sha256", + "field": "threat.indicator.file.hash.sha256", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2NDIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1d8002d0-82a7-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1d8002d0-82a7-11eb-ac13-d5ca87cb8fa2.json index 328a64f0785b..57ca90543d38 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1d8002d0-82a7-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/1d8002d0-82a7-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.pe.imphash" + "field": "threat.indicator.file.pe.imphash" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.pe.imphash", + "key": "threat.indicator.file.pe.imphash", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "Imphash Hash", - "field": "threatintel.indicator.file.pe.imphash", + "field": "threat.indicator.file.pe.imphash", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/21ff17c0-82a6-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/21ff17c0-82a6-11eb-ac13-d5ca87cb8fa2.json index b3e12fb41934..4bec354e5368 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/21ff17c0-82a6-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/21ff17c0-82a6-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.md5" + "field": "threat.indicator.file.hash.md5" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.md5", + "key": "threat.indicator.file.hash.md5", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "MD5 Hash", - "field": "threatintel.indicator.file.hash.md5", + "field": "threat.indicator.file.hash.md5", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302cd5b0-76cd-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302cd5b0-76cd-11eb-a3e3-b3cc7c78a70f.json index 0e395ef24310..9bb6455feea9 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302cd5b0-76cd-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302cd5b0-76cd-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.ip" + "field": "threat.indicator.ip" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.ip", + "key": "threat.indicator.ip", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX IP Indicator", - "field": "threatintel.indicator.ip", + "field": "threat.indicator.ip", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NjcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302d0850-ff7b-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302d0850-ff7b-11eb-acb2-2960a7069ed1.json index f931164c8889..50f2a9cebc51 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302d0850-ff7b-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/302d0850-ff7b-11eb-acb2-2960a7069ed1.json @@ -28,7 +28,7 @@ "id": "2", "params": { "customLabel": "Confidence", - "field": "threatintel.indicator.confidence", + "field": "threat.indicator.confidence", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -148,4 +148,4 @@ "type": "visualization", "updated_at": "2021-10-11T08:02:55.512Z", "version": "WzUzMCwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/346136f0-76d5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/346136f0-76d5-11eb-a3e3-b3cc7c78a70f.json index 3edcd79c797f..bc86816afc39 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/346136f0-76d5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/346136f0-76d5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.original" + "field": "threat.indicator.url.original" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.original", + "key": "threat.indicator.url.original", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX URL Indicator", - "field": "threatintel.indicator.url.original", + "field": "threat.indicator.url.original", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NjksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/40d61ab0-72e6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/40d61ab0-72e6-11eb-a3e3-b3cc7c78a70f.json index f8d2e419a2b5..a3e2646eea24 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/40d61ab0-72e6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/40d61ab0-72e6-11eb-a3e3-b3cc7c78a70f.json @@ -27,7 +27,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.file.type", + "field": "threat.indicator.file.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -82,4 +82,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/41100be0-72e5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/41100be0-72e5-11eb-a3e3-b3cc7c78a70f.json index d1e07d3fbbbd..37aa10e1c045 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/41100be0-72e5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/41100be0-72e5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.ssdeep" + "field": "threat.indicator.file.hash.ssdeep" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.ssdeep", + "key": "threat.indicator.file.hash.ssdeep", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -84,7 +84,7 @@ "id": "2", "params": { "customLabel": "ssdeep Hash", - "field": "threatintel.indicator.file.hash.ssdeep", + "field": "threat.indicator.file.hash.ssdeep", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -101,7 +101,7 @@ "id": "3", "params": { "customLabel": "File Type", - "field": "threatintel.indicator.file.type", + "field": "threat.indicator.file.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -162,4 +162,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/49f0c060-76cd-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/49f0c060-76cd-11eb-a3e3-b3cc7c78a70f.json index 79f94d2a0466..65880a6f4bb3 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/49f0c060-76cd-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/49f0c060-76cd-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.domain" + "field": "threat.indicator.url.domain" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.domain", + "key": "threat.indicator.url.domain", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX IP Indicator", - "field": "threatintel.indicator.domain", + "field": "threat.indicator.url.domain", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NjgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/4e5d25c0-76ce-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/4e5d25c0-76ce-11eb-a3e3-b3cc7c78a70f.json index f44f7a32fa3b..324c632ab271 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/4e5d25c0-76ce-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/4e5d25c0-76ce-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha256" + "field": "threat.indicator.file.hash.sha256" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha256", + "key": "threat.indicator.file.hash.sha256", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX SHA256 Hash Indicator", - "field": "threatintel.indicator.file.hash.sha256", + "field": "threat.indicator.file.hash.sha256", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NzIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/57faae10-73c5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/57faae10-73c5-11eb-a3e3-b3cc7c78a70f.json index 927f457e351e..014612f2d3c2 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/57faae10-73c5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/57faae10-73c5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.provider" + "field": "threat.indicator.provider" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.provider", + "key": "threat.indicator.provider", "negate": false, "type": "exists", "value": "exists" @@ -72,7 +72,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.provider", + "field": "threat.indicator.provider", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -137,4 +137,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2NDMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5b4877b0-82a6-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5b4877b0-82a6-11eb-ac13-d5ca87cb8fa2.json index db8a7fcef7e3..ad4c74b01107 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5b4877b0-82a6-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5b4877b0-82a6-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.sha256" + "field": "threat.indicator.file.hash.sha256" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.sha256", + "key": "threat.indicator.file.hash.sha256", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "SHA256 Hash", - "field": "threatintel.indicator.file.hash.sha256", + "field": "threat.indicator.file.hash.sha256", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5d395d80-ff71-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5d395d80-ff71-11eb-acb2-2960a7069ed1.json index f559210728b0..b5fe450d2737 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5d395d80-ff71-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5d395d80-ff71-11eb-acb2-2960a7069ed1.json @@ -28,7 +28,7 @@ "id": "2", "params": { "customLabel": "Most Linked Adversaries", - "field": "threatintel.threatq.adversaries", + "field": "threatq.adversaries", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -74,4 +74,4 @@ "type": "visualization", "updated_at": "2021-10-11T08:02:55.512Z", "version": "WzUyNiwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5eb61d00-ff72-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5eb61d00-ff72-11eb-acb2-2960a7069ed1.json index fde00ab644d2..3626ee406b76 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5eb61d00-ff72-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/5eb61d00-ff72-11eb-acb2-2960a7069ed1.json @@ -31,7 +31,7 @@ "id": "2", "params": { "customLabel": "Indicator Type", - "field": "threatintel.indicator.type", + "field": "threat.indicator.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -48,7 +48,7 @@ "id": "3", "params": { "customLabel": "Indicator Value", - "field": "threatintel.threatq.indicator_value", + "field": "threatq.indicator_value", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -94,4 +94,4 @@ "type": "visualization", "updated_at": "2021-10-11T08:07:14.354Z", "version": "WzYxNCwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/6077fd00-76d5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/6077fd00-76d5-11eb-a3e3-b3cc7c78a70f.json index 4e9740c9a101..75b7601754b8 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/6077fd00-76d5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/6077fd00-76d5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.path" + "field": "threat.indicator.url.path" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.path", + "key": "threat.indicator.url.path", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX URI Indicator", - "field": "threatintel.indicator.url.path", + "field": "threat.indicator.url.path", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NzEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/62f6daa0-72ee-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/62f6daa0-72ee-11eb-a3e3-b3cc7c78a70f.json index c0879c8aff75..039e88b76777 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/62f6daa0-72ee-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/62f6daa0-72ee-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.full" + "field": "threat.indicator.url.full" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.full", + "key": "threat.indicator.url.full", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "Threat Indicator URL", - "field": "threatintel.indicator.url.full", + "field": "threat.indicator.url.full", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7546ac40-82a6-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7546ac40-82a6-11eb-ac13-d5ca87cb8fa2.json index 479d7e408e3c..4de8710a0e28 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7546ac40-82a6-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7546ac40-82a6-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.ssdeep" + "field": "threat.indicator.file.hash.ssdeep" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.ssdeep", + "key": "threat.indicator.file.hash.ssdeep", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "ssdeep Hash", - "field": "threatintel.indicator.file.hash.ssdeep", + "field": "threat.indicator.file.hash.ssdeep", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7582b030-73c6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7582b030-73c6-11eb-a3e3-b3cc7c78a70f.json index 6767b7e0d19f..e2833363e125 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7582b030-73c6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7582b030-73c6-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.domain" + "field": "threat.indicator.url.domain" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.domain", + "key": "threat.indicator.url.domain", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP Domain Indicator", - "field": "threatintel.indicator.domain", + "field": "threat.indicator.url.domain", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/786546d0-82a5-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/786546d0-82a5-11eb-ac13-d5ca87cb8fa2.json index bc70c5824daa..773a823e5145 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/786546d0-82a5-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/786546d0-82a5-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.tlsh" + "field": "threat.indicator.file.hash.tlsh" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.tlsh", + "key": "threat.indicator.file.hash.tlsh", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "2", "params": { "customLabel": "TLSH Hash", - "field": "threatintel.indicator.file.hash.tlsh", + "field": "threat.indicator.file.hash.tlsh", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/79da77d0-72e5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/79da77d0-72e5-11eb-a3e3-b3cc7c78a70f.json index 50bed6e06e48..0551a2e44289 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/79da77d0-72e5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/79da77d0-72e5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.tlsh" + "field": "threat.indicator.file.hash.tlsh" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.tlsh", + "key": "threat.indicator.file.hash.tlsh", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -84,7 +84,7 @@ "id": "2", "params": { "customLabel": "TLSH Hash", - "field": "threatintel.indicator.file.hash.tlsh", + "field": "threat.indicator.file.hash.tlsh", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -101,7 +101,7 @@ "id": "3", "params": { "customLabel": "File Type", - "field": "threatintel.indicator.file.type", + "field": "threat.indicator.file.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -162,4 +162,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7c7d3750-73c3-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7c7d3750-73c3-11eb-a3e3-b3cc7c78a70f.json index 6ca2835a167e..ffb99fa08381 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7c7d3750-73c3-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7c7d3750-73c3-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -66,7 +66,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.type", + "field": "threat.indicator.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -131,4 +131,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7cbe5900-82ab-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7cbe5900-82ab-11eb-ac13-d5ca87cb8fa2.json index 08ea90539c1e..75f21ca1a42c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7cbe5900-82ab-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/7cbe5900-82ab-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.first_seen" + "field": "threat.indicator.first_seen" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.first_seen", + "key": "threat.indicator.first_seen", "negate": false, "type": "exists", "value": "exists" @@ -76,7 +76,7 @@ "id": "2", "params": { "customLabel": "Indicator First Seen", - "field": "threatintel.indicator.first_seen", + "field": "threat.indicator.first_seen", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -132,4 +132,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/87980f70-72ec-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/87980f70-72ec-11eb-a3e3-b3cc7c78a70f.json index 3001eca60822..0b947ec09cdc 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/87980f70-72ec-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/87980f70-72ec-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.threat" + "field": "abusech.url.threat" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.threat", + "key": "abusech.url.threat", "negate": false, "type": "exists", "value": "exists" @@ -73,7 +73,7 @@ "id": "2", "params": { "customLabel": "Abuse URL Threat", - "field": "threatintel.abuseurl.threat", + "field": "abusech.url.threat", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -204,4 +204,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/8b2a64a0-82a8-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/8b2a64a0-82a8-11eb-ac13-d5ca87cb8fa2.json index 8fd2ef65b070..13aee45f317c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/8b2a64a0-82a8-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/8b2a64a0-82a8-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.extension" + "field": "threat.indicator.file.extension" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.extension", + "key": "threat.indicator.file.extension", "negate": false, "type": "exists", "value": "exists" @@ -66,7 +66,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.file.extension", + "field": "threat.indicator.file.extension", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -131,4 +131,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MTcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9047e8b0-72de-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9047e8b0-72de-11eb-a3e3-b3cc7c78a70f.json index cfa8fad37893..652e363bbf01 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9047e8b0-72de-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9047e8b0-72de-11eb-a3e3-b3cc7c78a70f.json @@ -34,7 +34,7 @@ "id": "2", "params": { "customLabel": "Threat Indicator Provider", - "field": "threatintel.indicator.provider", + "field": "threat.indicator.provider", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -156,4 +156,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NTUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9109e490-76cd-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9109e490-76cd-11eb-a3e3-b3cc7c78a70f.json index 3e1c8861cedf..9146d87144a0 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9109e490-76cd-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/9109e490-76cd-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.domain" + "field": "threat.indicator.url.domain" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.domain", + "key": "threat.indicator.url.domain", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "AlienVault OTX URL Domain Indicator", - "field": "threatintel.indicator.url.domain", + "field": "threat.indicator.url.domain", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NzAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/92961600-7621-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/92961600-7621-11eb-a3e3-b3cc7c78a70f.json index f9a63566f096..c6ec332aa22b 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/92961600-7621-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/92961600-7621-11eb-a3e3-b3cc7c78a70f.json @@ -33,7 +33,7 @@ "type": "list" }, { - "fieldName": "threatintel.indicator.provider", + "fieldName": "threat.indicator.provider", "id": "1614117093181", "indexPatternRefName": "control_1_index_pattern", "label": "Indicator Provider", @@ -48,7 +48,7 @@ "type": "list" }, { - "fieldName": "threatintel.indicator.type", + "fieldName": "threat.indicator.type", "id": "1614117117360", "indexPatternRefName": "control_2_index_pattern", "label": "Indicator Type", @@ -101,4 +101,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NDcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/95f384b0-76d8-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/95f384b0-76d8-11eb-a3e3-b3cc7c78a70f.json index a9c17ee0611b..b2f747547b3f 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/95f384b0-76d8-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/95f384b0-76d8-11eb-a3e3-b3cc7c78a70f.json @@ -35,7 +35,7 @@ "id": "2", "params": { "customLabel": "", - "field": "threatintel.indicator.url.scheme", + "field": "threat.indicator.url.scheme", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -156,4 +156,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NjQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/98d42ee0-76b6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/98d42ee0-76b6-11eb-a3e3-b3cc7c78a70f.json index 0c5102dfd149..03edc5edc0bc 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/98d42ee0-76b6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/98d42ee0-76b6-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.tags" + "field": "abusech.url.tags" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.tags", + "key": "abusech.url.tags", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "Abuse URL Tags", - "field": "threatintel.abuseurl.tags", + "field": "abusech.url.tags", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a09329d0-73c6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a09329d0-73c6-11eb-a3e3-b3cc7c78a70f.json index d81abd72e48e..d34f5079186c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a09329d0-73c6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a09329d0-73c6-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.ip" + "field": "threat.indicator.ip" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.ip", + "key": "threat.indicator.ip", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP IP Indicator", - "field": "threatintel.indicator.ip", + "field": "threat.indicator.ip", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a1616dd0-72eb-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a1616dd0-72eb-11eb-a3e3-b3cc7c78a70f.json index 419dcc323d14..ba4ce6e4ea7a 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a1616dd0-72eb-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a1616dd0-72eb-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.blacklists.spamhaus_dbl" + "field": "abusech.url.blacklists.spamhaus_dbl" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.blacklists.spamhaus_dbl", + "key": "abusech.url.blacklists.spamhaus_dbl", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.blacklists.surbl" + "field": "abusech.url.blacklists.surbl" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.abuseurl.blacklists.surbl", + "key": "abusech.url.blacklists.surbl", "negate": false, "type": "exists", "value": "exists" @@ -84,7 +84,7 @@ "id": "2", "params": { "customLabel": "Spamhaus DBL Blacklist Status", - "field": "threatintel.abuseurl.blacklists.spamhaus_dbl", + "field": "abusech.url.blacklists.spamhaus_dbl", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -101,7 +101,7 @@ "id": "3", "params": { "customLabel": "SURBL Blacklist Status", - "field": "threatintel.abuseurl.blacklists.surbl", + "field": "abusech.url.blacklists.surbl", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -162,4 +162,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NjAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a7b6e910-72ed-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a7b6e910-72ed-11eb-a3e3-b3cc7c78a70f.json index 007929c6d0aa..813400590127 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a7b6e910-72ed-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a7b6e910-72ed-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.scheme" + "field": "threat.indicator.url.scheme" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.scheme", + "key": "threat.indicator.url.scheme", "negate": false, "type": "exists", "value": "exists" @@ -74,7 +74,7 @@ "id": "2", "params": { "customLabel": "URL Scheme", - "field": "threatintel.indicator.url.scheme", + "field": "threat.indicator.url.scheme", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -90,7 +90,7 @@ "enabled": true, "id": "3", "params": { - "field": "threatintel.indicator.url.scheme", + "field": "threat.indicator.url.scheme", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -220,4 +220,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTIsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a911a8b0-ff77-11eb-acb2-2960a7069ed1.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a911a8b0-ff77-11eb-acb2-2960a7069ed1.json index 59f66be7644a..25929d8fef8f 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a911a8b0-ff77-11eb-acb2-2960a7069ed1.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/a911a8b0-ff77-11eb-acb2-2960a7069ed1.json @@ -27,7 +27,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.marking.tlp", + "field": "threat.indicator.marking.tlp", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -82,4 +82,4 @@ "type": "visualization", "updated_at": "2021-10-11T08:02:55.512Z", "version": "WzUyNSwxXQ==" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ad55b1e0-73c8-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ad55b1e0-73c8-11eb-a3e3-b3cc7c78a70f.json index a0719389fc87..0b6cc17dce5c 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ad55b1e0-73c8-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ad55b1e0-73c8-11eb-a3e3-b3cc7c78a70f.json @@ -35,7 +35,7 @@ "id": "2", "params": { "customLabel": "Indicator Marking TLP", - "field": "threatintel.indicator.marking.tlp", + "field": "threat.indicator.marking.tlp", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -51,7 +51,7 @@ "enabled": true, "id": "3", "params": { - "field": "threatintel.indicator.marking.tlp", + "field": "threat.indicator.marking.tlp", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -171,4 +171,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/aebde030-72d2-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/aebde030-72d2-11eb-a3e3-b3cc7c78a70f.json index 0d3c70a156f3..09bbd1da8a40 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/aebde030-72d2-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/aebde030-72d2-11eb-a3e3-b3cc7c78a70f.json @@ -9,13 +9,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.marking.tlp" + "field": "threat.indicator.marking.tlp" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", - "key": "threatintel.indicator.marking.tlp", + "key": "threat.indicator.marking.tlp", "negate": false, "type": "exists", "value": "exists" @@ -55,7 +55,7 @@ "id": "2", "params": { "customLabel": "Indicator Marking TLP", - "field": "threatintel.indicator.marking.tlp", + "field": "threat.indicator.marking.tlp", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -71,7 +71,7 @@ "enabled": true, "id": "3", "params": { - "field": "threatintel.indicator.marking.tlp", + "field": "threat.indicator.marking.tlp", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -196,4 +196,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NTcsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/b9533f50-72e5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/b9533f50-72e5-11eb-a3e3-b3cc7c78a70f.json index dd4771dced6a..6b53ad4b086a 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/b9533f50-72e5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/b9533f50-72e5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.pe.imphash" + "field": "threat.indicator.file.pe.imphash" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.pe.imphash", + "key": "threat.indicator.file.pe.imphash", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -84,7 +84,7 @@ "id": "2", "params": { "customLabel": "Imphash Hash", - "field": "threatintel.indicator.file.pe.imphash", + "field": "threat.indicator.file.pe.imphash", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -101,7 +101,7 @@ "id": "3", "params": { "customLabel": "File Type", - "field": "threatintel.indicator.file.type", + "field": "threat.indicator.file.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -162,4 +162,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MDUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bc4790b0-82aa-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bc4790b0-82aa-11eb-ac13-d5ca87cb8fa2.json index f1fc5472b6b2..395627036b14 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bc4790b0-82aa-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bc4790b0-82aa-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.malwarebazaar.intelligence.downloads" + "field": "abusech.malwarebazaar.intelligence.downloads" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.malwarebazaar.intelligence.downloads", + "key": "abusech.malwarebazaar.intelligence.downloads", "negate": false, "type": "exists", "value": "exists" @@ -76,7 +76,7 @@ "id": "2", "params": { "customLabel": "Malware Bazaar Downloads", - "field": "threatintel.malwarebazaar.intelligence.downloads", + "field": "abusech.malwarebazaar.intelligence.downloads", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -132,4 +132,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bf3dfde0-73c3-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bf3dfde0-73c3-11eb-a3e3-b3cc7c78a70f.json index f65bf82d5b37..f71bb2359224 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bf3dfde0-73c3-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/bf3dfde0-73c3-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.misp.published" + "field": "misp.published" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.misp.published", + "key": "misp.published", "negate": false, "type": "exists", "value": "exists" @@ -72,7 +72,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.misp.published", + "field": "misp.published", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -137,4 +137,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c102b0f0-73c6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c102b0f0-73c6-11eb-a3e3-b3cc7c78a70f.json index 4ee6602cf678..e992bfb85852 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c102b0f0-73c6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c102b0f0-73c6-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.full" + "field": "threat.indicator.url.full" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.full", + "key": "threat.indicator.url.full", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP URL Indicator", - "field": "threatintel.indicator.url.full", + "field": "threat.indicator.url.full", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2MzYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c7d5db50-82a8-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c7d5db50-82a8-11eb-ac13-d5ca87cb8fa2.json index 225ca993710b..ad6317b41015 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c7d5db50-82a8-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c7d5db50-82a8-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.provider" + "field": "threat.indicator.provider" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.provider", + "key": "threat.indicator.provider", "negate": false, "type": "exists", "value": "exists" @@ -73,7 +73,7 @@ "id": "2", "params": { "customLabel": "Indicator Provider", - "field": "threatintel.indicator.provider", + "field": "threat.indicator.provider", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -204,4 +204,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MTgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c813c5d0-72dd-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c813c5d0-72dd-11eb-a3e3-b3cc7c78a70f.json index 18539863d1ac..6619c3564fe5 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c813c5d0-72dd-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/c813c5d0-72dd-11eb-a3e3-b3cc7c78a70f.json @@ -9,13 +9,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "enabled": true, "id": "3", "params": { - "field": "threatintel.indicator.type", + "field": "threat.indicator.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -192,4 +192,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:32.145Z", "version": "WzQ2NTgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d22c1090-82a5-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d22c1090-82a5-11eb-ac13-d5ca87cb8fa2.json index 107bf321eacc..340bcc359c89 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d22c1090-82a5-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d22c1090-82a5-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.mime_type" + "field": "threat.indicator.file.mime_type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.mime_type", + "key": "threat.indicator.file.mime_type", "negate": false, "type": "exists", "value": "exists" @@ -78,7 +78,7 @@ "id": "3", "params": { "customLabel": "File MIME Type", - "field": "threatintel.indicator.file.mime_type", + "field": "threat.indicator.file.mime_type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -134,4 +134,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MTUsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d5d76c60-72ee-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d5d76c60-72ee-11eb-a3e3-b3cc7c78a70f.json index 26f577c28648..7450b3832911 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d5d76c60-72ee-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/d5d76c60-72ee-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.url.full" + "field": "threat.indicator.url.full" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.url.full", + "key": "threat.indicator.url.full", "negate": false, "type": "exists", "value": "exists" @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTgsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/dbd199d0-82aa-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/dbd199d0-82aa-11eb-ac13-d5ca87cb8fa2.json index bd6250bdc9b2..a3f14f00b0e7 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/dbd199d0-82aa-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/dbd199d0-82aa-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.malwarebazaar.intelligence.uploads" + "field": "abusech.malwarebazaar.intelligence.uploads" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.malwarebazaar.intelligence.uploads", + "key": "abusech.malwarebazaar.intelligence.uploads", "negate": false, "type": "exists", "value": "exists" @@ -76,7 +76,7 @@ "id": "2", "params": { "customLabel": "Malware Bazaar Uploads", - "field": "threatintel.malwarebazaar.intelligence.uploads", + "field": "abusech.malwarebazaar.intelligence.uploads", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -132,4 +132,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MjEsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ea5879c0-72eb-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ea5879c0-72eb-11eb-a3e3-b3cc7c78a70f.json index 3674297d1586..fa58d2934c7e 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ea5879c0-72eb-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ea5879c0-72eb-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.url_status" + "field": "abusech.url.url_status" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.url_status", + "key": "abusech.url.url_status", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "URL Status", - "field": "threatintel.abuseurl.url_status", + "field": "abusech.url.url_status", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTksMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/eba4ec60-72ea-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/eba4ec60-72ea-11eb-a3e3-b3cc7c78a70f.json index e05220ceeabd..8745f6c3ca3d 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/eba4ec60-72ea-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/eba4ec60-72ea-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.larted" + "field": "abusech.url.larted" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.larted", + "key": "abusech.url.larted", "negate": false, "type": "exists", "value": "exists" @@ -73,7 +73,7 @@ "id": "2", "params": { "customLabel": "Hosting Provider Notified", - "field": "threatintel.abuseurl.larted", + "field": "abusech.url.larted", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -138,4 +138,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTMsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ec68c4a0-73c6-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ec68c4a0-73c6-11eb-a3e3-b3cc7c78a70f.json index 4a7c4dfa7406..517fa9c84ce9 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ec68c4a0-73c6-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ec68c4a0-73c6-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.file.hash.md5" + "field": "threat.indicator.file.hash.md5" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.file.hash.md5", + "key": "threat.indicator.file.hash.md5", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "MISP MD5 Hash Indicator", - "field": "threatintel.indicator.file.hash.md5", + "field": "threat.indicator.file.hash.md5", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:31.083Z", "version": "WzQ2NDAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ecf74b10-72ec-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ecf74b10-72ec-11eb-a3e3-b3cc7c78a70f.json index ea0aef5cb860..16d083d87624 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ecf74b10-72ec-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/ecf74b10-72ec-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abuseurl.threat" + "field": "abusech.url.threat" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abuseurl.threat", + "key": "abusech.url.threat", "negate": false, "type": "exists", "value": "exists" @@ -72,7 +72,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.provider", + "field": "threat.indicator.provider", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -203,4 +203,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:25.974Z", "version": "WzQ1NTYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f33125b0-76d8-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f33125b0-76d8-11eb-a3e3-b3cc7c78a70f.json index 3d473b4e17de..41b0ecfa65b5 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f33125b0-76d8-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f33125b0-76d8-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.indicator.type" + "field": "threat.indicator.type" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.indicator.type", + "key": "threat.indicator.type", "negate": false, "type": "exists", "value": "exists" @@ -66,7 +66,7 @@ "enabled": true, "id": "2", "params": { - "field": "threatintel.indicator.type", + "field": "threat.indicator.type", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -131,4 +131,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:27.014Z", "version": "WzQ1NjYsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f91e9620-82a8-11eb-ac13-d5ca87cb8fa2.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f91e9620-82a8-11eb-ac13-d5ca87cb8fa2.json index 958c15dba69e..664816cccba4 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f91e9620-82a8-11eb-ac13-d5ca87cb8fa2.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f91e9620-82a8-11eb-ac13-d5ca87cb8fa2.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.malwarebazaar.tags" + "field": "abusech.malwarebazaar.tags" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.malwarebazaar.tags", + "key": "abusech.malwarebazaar.tags", "negate": false, "type": "exists", "value": "exists" @@ -67,7 +67,7 @@ "id": "2", "params": { "customLabel": "Malware Bazaar Tags", - "field": "threatintel.malwarebazaar.tags", + "field": "abusech.malwarebazaar.tags", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -123,4 +123,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:30.070Z", "version": "WzQ2MTQsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f9c6ba80-72e5-11eb-a3e3-b3cc7c78a70f.json b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f9c6ba80-72e5-11eb-a3e3-b3cc7c78a70f.json index 21660b248e40..516a572fb886 100644 --- a/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f9c6ba80-72e5-11eb-a3e3-b3cc7c78a70f.json +++ b/x-pack/filebeat/module/threatintel/_meta/kibana/7/visualization/f9c6ba80-72e5-11eb-a3e3-b3cc7c78a70f.json @@ -30,13 +30,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abusemalware.virustotal.link" + "field": "abusech.malware.virustotal.link" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", - "key": "threatintel.abusemalware.virustotal.link", + "key": "abusech.malware.virustotal.link", "negate": false, "type": "exists", "value": "exists" @@ -47,13 +47,13 @@ "store": "appState" }, "exists": { - "field": "threatintel.abusemalware.virustotal.result" + "field": "abusech.malware.virustotal.result" }, "meta": { "alias": null, "disabled": false, "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", - "key": "threatintel.abusemalware.virustotal.result", + "key": "abusech.malware.virustotal.result", "negate": false, "type": "exists", "value": "exists" @@ -95,7 +95,7 @@ "id": "2", "params": { "customLabel": "VirusTotal URL", - "field": "threatintel.abusemalware.virustotal.link", + "field": "abusech.malware.virustotal.link", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -112,7 +112,7 @@ "id": "3", "params": { "customLabel": "VirusTotal Result", - "field": "threatintel.abusemalware.virustotal.result", + "field": "abusech.malware.virustotal.result", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -173,4 +173,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:34:29.041Z", "version": "WzQ2MTAsMV0=" -} \ No newline at end of file +} diff --git a/x-pack/filebeat/module/threatintel/abusemalware/_meta/fields.yml b/x-pack/filebeat/module/threatintel/abusemalware/_meta/fields.yml index 55f8657bc6ec..73aae20e07ff 100644 --- a/x-pack/filebeat/module/threatintel/abusemalware/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/abusemalware/_meta/fields.yml @@ -1,4 +1,4 @@ -- name: abusemalware +- name: abusech.malware type: group description: > Fields for AbuseCH Malware Threat Intel @@ -31,4 +31,4 @@ - name: virustotal.link type: keyword description: > - Link to the Virustotal report. \ No newline at end of file + Link to the Virustotal report. diff --git a/x-pack/filebeat/module/threatintel/abusemalware/config/config.yml b/x-pack/filebeat/module/threatintel/abusemalware/config/config.yml index e7f4f8cc2649..b4365bd3e5bc 100644 --- a/x-pack/filebeat/module/threatintel/abusemalware/config/config.yml +++ b/x-pack/filebeat/module/threatintel/abusemalware/config/config.yml @@ -11,10 +11,9 @@ request.ssl: {{ .ssl | tojson }} request.proxy_url: {{ .proxy_url }} {{ end }} request.url: {{ .url }} -request.transforms: -- set: - target: header.Content-Type - value: application/json +{{ if .http_client_timeout }} +request.timeout: {{ .http_client_timeout }} +{{ end }} response.split: target: body.payloads @@ -30,17 +29,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: ["json.md5_hash"] - target_field: "@metadata._id" - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/abusemalware/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/abusemalware/ingest/pipeline.yml index 5e24b68c52ee..da0b365724fa 100644 --- a/x-pack/filebeat/module/threatintel/abusemalware/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/abusemalware/ingest/pipeline.yml @@ -1,4 +1,5 @@ -description: Pipeline for parsing Abuse.ch Malware Threat Intel +--- +description: Pipeline for parsing Abuse.ch URL Threat Intel processors: #################### # Event ECS fields # @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -20,92 +24,110 @@ processors: # General ECS fields # ###################### - rename: - field: json - target_field: threatintel.abusemalware + field: message + target_field: event.original ignore_missing: true + - json: + field: event.original + target_field: abusech.malware + - fingerprint: + fields: + - abusech.malware.md5_hash + - abusech.malware.sha256_hash + target_field: "_id" ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] AbuseCH Malware" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" - date: - field: threatintel.abusemalware.firstseen - target_field: threatintel.indicator.first_seen + field: abusech.malware.firstseen + target_field: threat.indicator.first_seen formats: - "yyyy-MM-dd HH:mm:ss z" - "yyyy-MM-dd HH:mm:ss Z" - "yyyy-MM-dd HH:mm:ss" - if: "ctx?.threatintel?.abusemalware.firstseen != null" + if: "ctx.abusech?.malware?.firstseen != null" - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - rename: - field: threatintel.abusemalware.file_size - target_field: threatintel.indicator.file.size + field: abusech.malware.file_size + target_field: threat.indicator.file.size ignore_missing: true - rename: - field: threatintel.abusemalware.file_type - target_field: threatintel.indicator.file.type + field: abusech.malware.file_type + target_field: threat.indicator.file.type ignore_missing: true # This includes a direct link to malicious files, we do not want them to appear in Kibana # in case they are accidently clicked. - remove: - field: threatintel.abusemalware.urlhaus_download + field: abusech.malware.urlhaus_download ignore_missing: true - convert: - field: threatintel.indicator.file.size + field: threat.indicator.file.size type: long ignore_missing: true + - convert: + field: abusech.malware.virustotal.percent + type: float + ignore_missing: true - rename: - field: threatintel.abusemalware.md5_hash - target_field: threatintel.indicator.file.hash.md5 + field: abusech.malware.md5_hash + target_field: threat.indicator.file.hash.md5 ignore_missing: true - rename: - field: threatintel.abusemalware.sha256_hash - target_field: threatintel.indicator.file.hash.sha256 + field: abusech.malware.sha256_hash + target_field: threat.indicator.file.hash.sha256 ignore_missing: true - rename: - field: threatintel.abusemalware.imphash - target_field: threatintel.indicator.file.pe.imphash + field: abusech.malware.imphash + target_field: threat.indicator.file.pe.imphash ignore_missing: true - rename: - field: threatintel.abusemalware.ssdeep - target_field: threatintel.indicator.file.hash.ssdeep + field: abusech.malware.ssdeep + target_field: threat.indicator.file.hash.ssdeep ignore_missing: true - rename: - field: threatintel.abusemalware.tlsh - target_field: threatintel.indicator.file.hash.tlsh + field: abusech.malware.tlsh + target_field: threat.indicator.file.hash.tlsh ignore_missing: true - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.md5 }}" - if: ctx?.threatintel?.indicator?.file?.hash?.md5 != null + value: "{{{threat.indicator.file.hash.md5}}}" + if: ctx?.threat?.indicator?.file?.hash?.md5 != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.sha256 }}" - if: ctx?.threatintel?.indicator?.file?.hash?.sha256 != null + value: "{{{threat.indicator.file.hash.sha256}}}" + if: ctx?.threat?.indicator?.file?.hash?.sha256 != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.ssdeep }}" - if: ctx?.threatintel?.indicator?.file?.hash?.ssdeep != null + value: "{{{threat.indicator.file.hash.ssdeep}}}" + if: ctx?.threat?.indicator?.file?.hash?.ssdeep != null - append: field: related.hash - value: "{{ threatintel.indicator.file.pe.imphash }}" - if: ctx?.threatintel?.indicator?.file?.pe?.imphash != null + value: "{{{threat.indicator.file.pe.imphash}}}" + if: ctx?.threat?.indicator?.file?.pe?.imphash != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.tlsh }}" - if: ctx?.threatintel?.indicator?.file?.hash?.tlsh != null + value: "{{{threat.indicator.file.hash.tlsh}}}" + if: ctx?.threat?.indicator?.file?.hash?.tlsh != null ###################### # Cleanup processors # ###################### - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx?.threat?.indicator?.type == null - script: lang: painless - if: ctx?.threatintel != null + if: ctx?.abusech != null source: | void handleMap(Map map) { for (def x : map.values()) { @@ -127,9 +149,14 @@ processors: } } handleMap(ctx); + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - remove: field: - - threatintel.abusemalware.firstseen + - abusech.malware.firstseen - message ignore_missing: true on_failure: diff --git a/x-pack/filebeat/module/threatintel/abusemalware/manifest.yml b/x-pack/filebeat/module/threatintel/abusemalware/manifest.yml index 5fe3a155180e..0d755b7b38d3 100644 --- a/x-pack/filebeat/module/threatintel/abusemalware/manifest.yml +++ b/x-pack/filebeat/module/threatintel/abusemalware/manifest.yml @@ -11,6 +11,9 @@ var: - name: tags default: [threatintel-abusemalware, forwarded] - name: proxy_url + - name: preserve_original_event + default: false + - name: http_client_timeout ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/abusemalware/test/abusechmalware.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/abusemalware/test/abusechmalware.ndjson.log-expected.json index 6c31b6f779c2..75a4d118ba36 100644 --- a/x-pack/filebeat/module/threatintel/abusemalware/test/abusechmalware.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/abusemalware/test/abusechmalware.ndjson.log-expected.json @@ -20,15 +20,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "7871286a8f1f68a14b18ae475683f724", - "threatintel.indicator.file.hash.sha256": "48a6aee18bcfe9058b35b1018832aef1c9efd8f50ac822f49abb484a5e2a4b1f", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG5:X5DpBw/KViMTB1MnEWk0115JW", - "threatintel.indicator.file.hash.tlsh": "1344D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:14:05.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "7871286a8f1f68a14b18ae475683f724", + "threat.indicator.file.hash.sha256": "48a6aee18bcfe9058b35b1018832aef1c9efd8f50ac822f49abb484a5e2a4b1f", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG5:X5DpBw/KViMTB1MnEWk0115JW", + "threat.indicator.file.hash.tlsh": "1344D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:14:05.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -51,17 +53,22 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "7b4c77dc293347b467fb860e34515163", - "threatintel.indicator.file.hash.sha256": "ec59538e8de8525b1674b3b8fe0c180ac822145350bcce054ad3fc6b95b1b5a4", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGY:X5DpBw/KViMTB1MnEWk0115Jr", - "threatintel.indicator.file.hash.tlsh": "4E44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:11:41.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "7b4c77dc293347b467fb860e34515163", + "threat.indicator.file.hash.sha256": "ec59538e8de8525b1674b3b8fe0c180ac822145350bcce054ad3fc6b95b1b5a4", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGY:X5DpBw/KViMTB1MnEWk0115Jr", + "threat.indicator.file.hash.tlsh": "4E44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:11:41.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.virustotal.link": "https://www.virustotal.com/gui/file/b0e914d1bbe19433cc9df64ea1ca07fe77f7b150b511b786e46e007941a62bd7/detection/f-b0e914d", + "abusech.malware.virustotal.percent": 37.88, + "abusech.malware.virustotal.result": "25 / 66", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -82,18 +89,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.virustotal.link": "https://www.virustotal.com/gui/file/b0e914d1bbe19433cc9df64ea1ca07fe77f7b150b511b786e46e007941a62bd7/detection/f-b0e914d", - "threatintel.abusemalware.virustotal.percent": "37.88", - "threatintel.abusemalware.virustotal.result": "25 / 66", - "threatintel.indicator.file.hash.md5": "373d34874d7bc89fd4cefa6272ee80bf", - "threatintel.indicator.file.hash.sha256": "b0e914d1bbe19433cc9df64ea1ca07fe77f7b150b511b786e46e007941a62bd7", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGG:X5DpBw/KViMTB1MnEWk0115Jd", - "threatintel.indicator.file.hash.tlsh": "7544D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:11:22.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "373d34874d7bc89fd4cefa6272ee80bf", + "threat.indicator.file.hash.sha256": "b0e914d1bbe19433cc9df64ea1ca07fe77f7b150b511b786e46e007941a62bd7", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGG:X5DpBw/KViMTB1MnEWk0115Jd", + "threat.indicator.file.hash.tlsh": "7544D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:11:22.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -116,15 +122,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "e2e02aae857488dbdbe6631c29abf3f8", - "threatintel.indicator.file.hash.sha256": "7483e834a73fb6817769596fe4c0fa01d28639f52bbbdc2b8a56c36d466dd7f8", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJ9:0h3eZgRQCcw+MN54dEq7kqRtoLZH", - "threatintel.indicator.file.hash.tlsh": "5554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:11:21.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "e2e02aae857488dbdbe6631c29abf3f8", + "threat.indicator.file.hash.sha256": "7483e834a73fb6817769596fe4c0fa01d28639f52bbbdc2b8a56c36d466dd7f8", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJ9:0h3eZgRQCcw+MN54dEq7kqRtoLZH", + "threat.indicator.file.hash.tlsh": "5554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:11:21.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -146,16 +154,21 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "3e988e32b0c3c230d534e286665b89a5", - "threatintel.indicator.file.hash.sha256": "760e729426fb115b967a41e5a6f2f42d7a52a5cee74ed99065a6dc39bf89f59b", - "threatintel.indicator.file.hash.ssdeep": "6:TE6ll8uXi0jIAv6BHvPuA7RKTmOQamsQMGvMQgTYbtsWsQ72hCqPZG/:TTll8uTo5uA7RKtQamsS0QJfsQ7mCR", - "threatintel.indicator.file.hash.tlsh": "3CE0C002AB26C036500D154C221655B3B871911503CA14E6A6824BEA765D4A3290D190", - "threatintel.indicator.file.size": 352, - "threatintel.indicator.file.type": "unknown", - "threatintel.indicator.first_seen": "2021-01-14T06:08:02.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "3e988e32b0c3c230d534e286665b89a5", + "threat.indicator.file.hash.sha256": "760e729426fb115b967a41e5a6f2f42d7a52a5cee74ed99065a6dc39bf89f59b", + "threat.indicator.file.hash.ssdeep": "6:TE6ll8uXi0jIAv6BHvPuA7RKTmOQamsQMGvMQgTYbtsWsQ72hCqPZG/:TTll8uTo5uA7RKtQamsS0QJfsQ7mCR", + "threat.indicator.file.hash.tlsh": "3CE0C002AB26C036500D154C221655B3B871911503CA14E6A6824BEA765D4A3290D190", + "threat.indicator.file.size": 352, + "threat.indicator.file.type": "unknown", + "threat.indicator.first_seen": "2021-01-14T06:08:02.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.virustotal.link": "https://www.virustotal.com/gui/file/86655c0bcf9b21b5efc682f58eb80f42811042ba152358e1bfbbb867315a60ac/detection/f-86655c0", + "abusech.malware.virustotal.percent": 39.13, + "abusech.malware.virustotal.result": "27 / 69", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -176,18 +189,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.virustotal.link": "https://www.virustotal.com/gui/file/86655c0bcf9b21b5efc682f58eb80f42811042ba152358e1bfbbb867315a60ac/detection/f-86655c0", - "threatintel.abusemalware.virustotal.percent": "39.13", - "threatintel.abusemalware.virustotal.result": "27 / 69", - "threatintel.indicator.file.hash.md5": "dcc20d534cdf29eab03d8148bf728857", - "threatintel.indicator.file.hash.sha256": "86655c0bcf9b21b5efc682f58eb80f42811042ba152358e1bfbbb867315a60ac", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGI:X5DpBw/KViMTB1MnEWk0115JH", - "threatintel.indicator.file.hash.tlsh": "0D44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:08:02.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "dcc20d534cdf29eab03d8148bf728857", + "threat.indicator.file.hash.sha256": "86655c0bcf9b21b5efc682f58eb80f42811042ba152358e1bfbbb867315a60ac", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGI:X5DpBw/KViMTB1MnEWk0115JH", + "threat.indicator.file.hash.tlsh": "0D44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:08:02.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -210,15 +222,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "f6facbf7a90b9e67a6de9f6634eb40ba", - "threatintel.indicator.file.hash.sha256": "e91c9e11d3ce4f55fabd7196279367482d2fabfa32df81e614b15fc53b4e26be", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJ1:0h3eZgRQCcw+MN54dEq7kqRtoLZL", - "threatintel.indicator.file.hash.tlsh": "2554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:53.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "f6facbf7a90b9e67a6de9f6634eb40ba", + "threat.indicator.file.hash.sha256": "e91c9e11d3ce4f55fabd7196279367482d2fabfa32df81e614b15fc53b4e26be", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJ1:0h3eZgRQCcw+MN54dEq7kqRtoLZL", + "threat.indicator.file.hash.tlsh": "2554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:53.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -241,17 +255,20 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "44325fd5bdda2e2cdea07c3a39953bb1", - "threatintel.indicator.file.hash.sha256": "beedbbcacfc34b5edd8c68e3e4acf364992ebbcd989548e09e38fa03c5659bac", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG/:X5DpBw/KViMTB1MnEWk0115Jg", - "threatintel.indicator.file.hash.tlsh": "A044D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:41.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "44325fd5bdda2e2cdea07c3a39953bb1", + "threat.indicator.file.hash.sha256": "beedbbcacfc34b5edd8c68e3e4acf364992ebbcd989548e09e38fa03c5659bac", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG/:X5DpBw/KViMTB1MnEWk0115Jg", + "threat.indicator.file.hash.tlsh": "A044D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:41.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.signature": "Heodo", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -272,16 +289,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.signature": "Heodo", - "threatintel.indicator.file.hash.md5": "4c549051950522a3f1b0814aa9b1f6d1", - "threatintel.indicator.file.hash.sha256": "7cba55da723c0e020267a02e6ffc83e03a83701757fc4ec65ea398618ad881cf", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG4:X5DpBw/KViMTB1MnEWk0115Jv", - "threatintel.indicator.file.hash.tlsh": "4544D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:31.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "4c549051950522a3f1b0814aa9b1f6d1", + "threat.indicator.file.hash.sha256": "7cba55da723c0e020267a02e6ffc83e03a83701757fc4ec65ea398618ad881cf", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG4:X5DpBw/KViMTB1MnEWk0115Jv", + "threat.indicator.file.hash.tlsh": "4544D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:31.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -304,15 +322,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "d7333113098d88b6a5dd5b8eb24f9b87", - "threatintel.indicator.file.hash.sha256": "426be5e085e6bbad8430223dc89d8d3ced497133f8d478fd00005bcbb73399d4", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJw:0h3eZgRQCcw+MN54dEq7kqRtoLZW", - "threatintel.indicator.file.hash.tlsh": "9454CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:07.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "d7333113098d88b6a5dd5b8eb24f9b87", + "threat.indicator.file.hash.sha256": "426be5e085e6bbad8430223dc89d8d3ced497133f8d478fd00005bcbb73399d4", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJw:0h3eZgRQCcw+MN54dEq7kqRtoLZW", + "threat.indicator.file.hash.tlsh": "9454CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:07.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -335,15 +355,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "c8dbb261c1f450534c3693da2f4b479f", - "threatintel.indicator.file.hash.sha256": "25093afdaeb3ea000743ab843360a6b64f58c0a1ab950072ba6528056735deb9", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGe:X5DpBw/KViMTB1MnEWk0115JR", - "threatintel.indicator.file.hash.tlsh": "F344D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:07.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "c8dbb261c1f450534c3693da2f4b479f", + "threat.indicator.file.hash.sha256": "25093afdaeb3ea000743ab843360a6b64f58c0a1ab950072ba6528056735deb9", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGe:X5DpBw/KViMTB1MnEWk0115JR", + "threat.indicator.file.hash.tlsh": "F344D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:07.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -366,15 +388,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "714953f1d0031a4bb2f0c44afd015931", - "threatintel.indicator.file.hash.sha256": "b3327a96280365e441057f490df6261c9a2400fd63719eb9a7a0c9db95beecc5", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGc:X5DpBw/KViMTB1MnEWk0115J7", - "threatintel.indicator.file.hash.tlsh": "F644D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:06.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "714953f1d0031a4bb2f0c44afd015931", + "threat.indicator.file.hash.sha256": "b3327a96280365e441057f490df6261c9a2400fd63719eb9a7a0c9db95beecc5", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGc:X5DpBw/KViMTB1MnEWk0115J7", + "threat.indicator.file.hash.tlsh": "F644D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:06.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -397,15 +421,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "20fd22742500d4cec123398afc3d3672", - "threatintel.indicator.file.hash.sha256": "e92b54904391c171238863b584355197ba4508f73320a8e89afbb5425fc2dc4b", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGc:X5DpBw/KViMTB1MnEWk0115JP", - "threatintel.indicator.file.hash.tlsh": "BE44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:07:00.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "20fd22742500d4cec123398afc3d3672", + "threat.indicator.file.hash.sha256": "e92b54904391c171238863b584355197ba4508f73320a8e89afbb5425fc2dc4b", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGc:X5DpBw/KViMTB1MnEWk0115JP", + "threat.indicator.file.hash.tlsh": "BE44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:07:00.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -428,17 +454,20 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "aa81ceea053797a6f8c38a0f2f9b80b0", - "threatintel.indicator.file.hash.sha256": "dd15e74b3cd3a4fdb5f47adefd6f90e27d5a20e01316cc791711f6dce7c0f52e", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGf:X5DpBw/KViMTB1MnEWk0115Jo", - "threatintel.indicator.file.hash.tlsh": "CC44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:06:36.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "aa81ceea053797a6f8c38a0f2f9b80b0", + "threat.indicator.file.hash.sha256": "dd15e74b3cd3a4fdb5f47adefd6f90e27d5a20e01316cc791711f6dce7c0f52e", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGf:X5DpBw/KViMTB1MnEWk0115Jo", + "threat.indicator.file.hash.tlsh": "CC44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:06:36.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.signature": "Heodo", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -459,16 +488,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.signature": "Heodo", - "threatintel.indicator.file.hash.md5": "a2ce6795664c0fa93b07fa54ba868991", - "threatintel.indicator.file.hash.sha256": "0fae1eeabc4f5e07bd16f7851aec5ab6032d407c7ff0270f2b6e85c2a3efebd1", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGD:X5DpBw/KViMTB1MnEWk0115JY", - "threatintel.indicator.file.hash.tlsh": "8C44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:06:13.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "a2ce6795664c0fa93b07fa54ba868991", + "threat.indicator.file.hash.sha256": "0fae1eeabc4f5e07bd16f7851aec5ab6032d407c7ff0270f2b6e85c2a3efebd1", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGD:X5DpBw/KViMTB1MnEWk0115JY", + "threat.indicator.file.hash.tlsh": "8C44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:06:13.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -491,15 +521,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "9b9bac158dacb9c2f5511e9c464a7de4", - "threatintel.indicator.file.hash.sha256": "07a9d84c0b2c8cf1fd90ab409b9399d06920ab4b6efb647b5a3b9bef1045ee7e", - "threatintel.indicator.file.hash.ssdeep": "6144:WlLMUG2gFWLDFO9vNa11y3NPcJufFFTXNZrjJTKk:W5MT4WNaHy9P1FjbrjlKk", - "threatintel.indicator.file.hash.tlsh": "6B54CF217A53C826F5E800FCA6E9878914167F346F44A4C773D40F6AA8759E2EF2B317", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 280064, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:52.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "9b9bac158dacb9c2f5511e9c464a7de4", + "threat.indicator.file.hash.sha256": "07a9d84c0b2c8cf1fd90ab409b9399d06920ab4b6efb647b5a3b9bef1045ee7e", + "threat.indicator.file.hash.ssdeep": "6144:WlLMUG2gFWLDFO9vNa11y3NPcJufFFTXNZrjJTKk:W5MT4WNaHy9P1FjbrjlKk", + "threat.indicator.file.hash.tlsh": "6B54CF217A53C826F5E800FCA6E9878914167F346F44A4C773D40F6AA8759E2EF2B317", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 280064, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:52.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -522,17 +554,20 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "e48e3fa5e0f7b21c1ecf1efc81ff91e8", - "threatintel.indicator.file.hash.sha256": "708c0193aec6354af6877f314d4b0e3864552bac77258bee9ee5bf886a116df5", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGo:X5DpBw/KViMTB1MnEWk0115Jj", - "threatintel.indicator.file.hash.tlsh": "6644D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:51.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "e48e3fa5e0f7b21c1ecf1efc81ff91e8", + "threat.indicator.file.hash.sha256": "708c0193aec6354af6877f314d4b0e3864552bac77258bee9ee5bf886a116df5", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGo:X5DpBw/KViMTB1MnEWk0115Jj", + "threat.indicator.file.hash.tlsh": "6644D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:51.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.signature": "Heodo", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -553,16 +588,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.signature": "Heodo", - "threatintel.indicator.file.hash.md5": "8957f5347633ab4b10c2ae4fb92c8572", - "threatintel.indicator.file.hash.sha256": "f70a3c016fe791eb30959961f0bcaa08ba7b738491b9ae61cb4a667cd1de8b37", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJy:0h3eZgRQCcw+MN54dEq7kqRtoLZM", - "threatintel.indicator.file.hash.tlsh": "0754CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:50.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "8957f5347633ab4b10c2ae4fb92c8572", + "threat.indicator.file.hash.sha256": "f70a3c016fe791eb30959961f0bcaa08ba7b738491b9ae61cb4a667cd1de8b37", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJy:0h3eZgRQCcw+MN54dEq7kqRtoLZM", + "threat.indicator.file.hash.tlsh": "0754CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:50.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -585,15 +621,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "09cc76b7077b4d5704e46e864575ff03", - "threatintel.indicator.file.hash.sha256": "94ca186561b13fa9b1bf15f7e66118debc686b40d2a62a5cf4b3c6ca6ee1c7a1", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG/:X5DpBw/KViMTB1MnEWk0115Js", - "threatintel.indicator.file.hash.tlsh": "BB44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:36.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "09cc76b7077b4d5704e46e864575ff03", + "threat.indicator.file.hash.sha256": "94ca186561b13fa9b1bf15f7e66118debc686b40d2a62a5cf4b3c6ca6ee1c7a1", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG/:X5DpBw/KViMTB1MnEWk0115Js", + "threat.indicator.file.hash.tlsh": "BB44D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:36.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -616,17 +654,20 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "98a1cdf7de4232363f1d1e0f33dbfd99", - "threatintel.indicator.file.hash.sha256": "909f890dbc5748845cf06d0fb0b73a5c0cb17761f37e9cd4810eea0d0eb8627f", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJQ:0h3eZgRQCcw+MN54dEq7kqRtoLZ+", - "threatintel.indicator.file.hash.tlsh": "C554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:16.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "98a1cdf7de4232363f1d1e0f33dbfd99", + "threat.indicator.file.hash.sha256": "909f890dbc5748845cf06d0fb0b73a5c0cb17761f37e9cd4810eea0d0eb8627f", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJQ:0h3eZgRQCcw+MN54dEq7kqRtoLZ+", + "threat.indicator.file.hash.tlsh": "C554CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:16.000Z", + "threat.indicator.type": "file" }, { + "abusech.malware.signature": "Heodo", "event.category": "threat", "event.dataset": "threatintel.abusemalware", "event.kind": "enrichment", @@ -647,16 +688,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.abusemalware.signature": "Heodo", - "threatintel.indicator.file.hash.md5": "8a51830c1662513ba6bd44e2f7849547", - "threatintel.indicator.file.hash.sha256": "d1fa76346bef5bc8adaa615e109894a7c30f0bef07ab6272409c4056ea8d52aa", - "threatintel.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJh:0h3eZgRQCcw+MN54dEq7kqRtoLZ/", - "threatintel.indicator.file.hash.tlsh": "1654CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 284672, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:15.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "8a51830c1662513ba6bd44e2f7849547", + "threat.indicator.file.hash.sha256": "d1fa76346bef5bc8adaa615e109894a7c30f0bef07ab6272409c4056ea8d52aa", + "threat.indicator.file.hash.ssdeep": "6144:0hlBeZgR9LqvgFcwNAwhGV52n5Dv4JdEqvQykqRqYdBx8pRA7OZJh:0h3eZgRQCcw+MN54dEq7kqRtoLZ/", + "threat.indicator.file.hash.tlsh": "1654CF22E642C926F1E900FCB2A98B4451257E355F40F4D777C40FABA835AE2AF27717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 284672, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:15.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -679,15 +721,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "ae21d742a8118d6b86674aa5370bd6a7", - "threatintel.indicator.file.hash.sha256": "3b9698b6c18bcba15ee33378440dd3f42509730e6b1d2d5832c71a74b1920e51", - "threatintel.indicator.file.hash.ssdeep": "6144:WlLMUG2gFWLDFO9vNa11y3NPcJufFFTXNZrjJTKS:W5MT4WNaHy9P1FjbrjlKS", - "threatintel.indicator.file.hash.tlsh": "5454CF217A53C826F5E800FCA6E9878925167F346F44A4C373D40F6AA8759E2DF2B317", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 280064, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:05:12.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "ae21d742a8118d6b86674aa5370bd6a7", + "threat.indicator.file.hash.sha256": "3b9698b6c18bcba15ee33378440dd3f42509730e6b1d2d5832c71a74b1920e51", + "threat.indicator.file.hash.ssdeep": "6144:WlLMUG2gFWLDFO9vNa11y3NPcJufFFTXNZrjJTKS:W5MT4WNaHy9P1FjbrjlKS", + "threat.indicator.file.hash.tlsh": "5454CF217A53C826F5E800FCA6E9878925167F346F44A4C373D40F6AA8759E2DF2B317", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 280064, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:05:12.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -710,15 +754,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "78c9d88d24ed1d982a83216eed1590f6", - "threatintel.indicator.file.hash.sha256": "d11edc90f0e879a175abc6e2ce5c94a263aa2a01cd3b6e8b9fdf93a51235ae99", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG8:X5DpBw/KViMTB1MnEWk0115Jr", - "threatintel.indicator.file.hash.tlsh": "6044D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:04:38.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "78c9d88d24ed1d982a83216eed1590f6", + "threat.indicator.file.hash.sha256": "d11edc90f0e879a175abc6e2ce5c94a263aa2a01cd3b6e8b9fdf93a51235ae99", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JG8:X5DpBw/KViMTB1MnEWk0115Jr", + "threat.indicator.file.hash.tlsh": "6044D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:04:38.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -741,15 +787,17 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "236577d5d83e2a8d08623a7a7f724188", - "threatintel.indicator.file.hash.sha256": "8cd28fed7ebdcd79ea2509dca84f0a727ca28d4eaaed5a92cd10b1279ff16afa", - "threatintel.indicator.file.hash.ssdeep": "6144:X1G3WVIOY6Bdjehj+qudd96ou/6mv5wdC:X1GmSafShjYdd96z/6cwdC", - "threatintel.indicator.file.hash.tlsh": "8D34BE41B28B8B4BD163163C2976D1F8953CFC909761CE693B64B22F0F739D0892E7A5", - "threatintel.indicator.file.pe.imphash": "ed2860c18f5483e3b5388bad75169dc1", - "threatintel.indicator.file.size": 241664, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:04:26.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "236577d5d83e2a8d08623a7a7f724188", + "threat.indicator.file.hash.sha256": "8cd28fed7ebdcd79ea2509dca84f0a727ca28d4eaaed5a92cd10b1279ff16afa", + "threat.indicator.file.hash.ssdeep": "6144:X1G3WVIOY6Bdjehj+qudd96ou/6mv5wdC:X1GmSafShjYdd96z/6cwdC", + "threat.indicator.file.hash.tlsh": "8D34BE41B28B8B4BD163163C2976D1F8953CFC909761CE693B64B22F0F739D0892E7A5", + "threat.indicator.file.pe.imphash": "ed2860c18f5483e3b5388bad75169dc1", + "threat.indicator.file.size": 241664, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:04:26.000Z", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -772,14 +820,16 @@ "forwarded", "threatintel-abusemalware" ], - "threatintel.indicator.file.hash.md5": "ff60107d82dcda7e6726d214528758e7", - "threatintel.indicator.file.hash.sha256": "fb25d13188a5d0913bbcf5aeff6c7e3208ad92a7d10ab6bed2735f4d43310a27", - "threatintel.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGz:X5DpBw/KViMTB1MnEWk0115JU", - "threatintel.indicator.file.hash.tlsh": "9244D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", - "threatintel.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", - "threatintel.indicator.file.size": 277504, - "threatintel.indicator.file.type": "dll", - "threatintel.indicator.first_seen": "2021-01-14T06:04:20.000Z", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH Malware", + "threat.indicator.file.hash.md5": "ff60107d82dcda7e6726d214528758e7", + "threat.indicator.file.hash.sha256": "fb25d13188a5d0913bbcf5aeff6c7e3208ad92a7d10ab6bed2735f4d43310a27", + "threat.indicator.file.hash.ssdeep": "6144:+60EDP6uCLfGw/GpxXinM1BCo1PlumGx2mx2tXd0t115JGz:X5DpBw/KViMTB1MnEWk0115JU", + "threat.indicator.file.hash.tlsh": "9244D022AD13DD37E1F400FCA6A58F8561626E381F00A89777D41F8A98356F1BB2B717", + "threat.indicator.file.pe.imphash": "68aea345b134d576ccdef7f06db86088", + "threat.indicator.file.size": 277504, + "threat.indicator.file.type": "dll", + "threat.indicator.first_seen": "2021-01-14T06:04:20.000Z", + "threat.indicator.type": "file" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/abuseurl/_meta/fields.yml b/x-pack/filebeat/module/threatintel/abuseurl/_meta/fields.yml index a93f91d339c1..f407bb8d6155 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/abuseurl/_meta/fields.yml @@ -1,4 +1,4 @@ -- name: abuseurl +- name: abusech.url type: group description: > Fields for AbuseCH Malware Threat Intel diff --git a/x-pack/filebeat/module/threatintel/abuseurl/config/config.yml b/x-pack/filebeat/module/threatintel/abuseurl/config/config.yml index da01bc61c40c..f577594ec06f 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/config/config.yml +++ b/x-pack/filebeat/module/threatintel/abuseurl/config/config.yml @@ -11,10 +11,6 @@ request.ssl: {{ .ssl | tojson }} request.proxy_url: {{ .proxy_url }} {{ end }} request.url: {{ .url }} -request.transforms: -- set: - target: header.Content-Type - value: application/json response.split: target: body.urls @@ -30,17 +26,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: ["json.id"] - target_field: "@metadata._id" - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml index bf674ba2c88e..f762db7351ee 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml @@ -1,3 +1,4 @@ +--- description: Pipeline for parsing Abuse.ch URL Threat Intel processors: #################### @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -20,62 +24,75 @@ processors: # General ECS fields # ###################### - rename: - field: json - target_field: threatintel.abuseurl + field: message + target_field: event.original ignore_missing: true + - json: + field: event.original + target_field: abusech.url + - fingerprint: + fields: + - abusech.url.id + target_field: "_id" ##################### # Threat ECS Fields # ##################### - set: - field: threatintel.indicator.type + field: threat.feed.name + value: "[Filebeat] AbuseCH URL" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" + - set: + field: threat.indicator.type value: url - date: - field: threatintel.abuseurl.date_added - target_field: threatintel.indicator.first_seen + field: abusech.url.date_added + target_field: threat.indicator.first_seen formats: - "yyyy-MM-dd HH:mm:ss z" - "yyyy-MM-dd HH:mm:ss Z" - if: "ctx?.threatintel?.abuseurl?.date_added != null" + if: "ctx.abusech?.url?.date_added != null" - uri_parts: - field: threatintel.abuseurl.url - target_field: threatintel.indicator.url + field: abusech.url.url + target_field: threat.indicator.url keep_original: true remove_if_successful: true - set: - field: threatintel.indicator.url.full - value: "{{{threatintel.indicator.url.original}}}" + field: threat.indicator.url.full + value: "{{{threat.indicator.url.original}}}" ignore_empty_value: true - rename: - field: threatintel.abuseurl.urlhaus_reference - target_field: threatintel.indicator.reference + field: abusech.url.urlhaus_reference + target_field: threat.indicator.reference ignore_missing: true # Host can be both IP addresses and domain names - grok: - field: threatintel.abuseurl.host + field: abusech.url.host patterns: - - "(?:%{IP:threatintel.indicator.ip}|%{GREEDYDATA:threatintel.indicator.url.domain})" + - "(?:%{IP:threat.indicator.ip}|%{GREEDYDATA:threat.indicator.url.domain})" ignore_failure: true - rename: - field: threatintel.abuseurl.reporter - target_field: threatintel.indicator.provider + field: abusech.url.reporter + target_field: threat.indicator.provider ignore_missing: true ###################### # Cleanup processors # ###################### - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx?.threat?.indicator?.type == null - convert: - field: threatintel.abuseurl.larted + field: abusech.url.larted type: boolean ignore_missing: true - script: lang: painless - if: ctx?.threatintel != null + if: ctx?.abusech != null source: | void handleMap(Map map) { for (def x : map.values()) { @@ -97,11 +114,16 @@ processors: } } handleMap(ctx); + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - remove: field: - - threatintel.abuseurl.date_added - - threatintel.abuseurl.url - - threatintel.abuseurl.host + - abusech.url.date_added + - abusech.url.url + - abusech.url.host - message ignore_missing: true on_failure: diff --git a/x-pack/filebeat/module/threatintel/abuseurl/manifest.yml b/x-pack/filebeat/module/threatintel/abuseurl/manifest.yml index 13b5e663c4ac..2f71ad88253a 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/manifest.yml +++ b/x-pack/filebeat/module/threatintel/abuseurl/manifest.yml @@ -11,6 +11,8 @@ var: - name: tags default: [threatintel-abuseurls, forwarded] - name: proxy_url + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/abuseurl/test/abusechurl.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/abuseurl/test/abusechurl.ndjson.log-expected.json index 3b312440b342..c76728b3c163 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/test/abusechurl.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/abuseurl/test/abusechurl.ndjson.log-expected.json @@ -1,5 +1,15 @@ [ { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961548", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi", + "elf" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -13,30 +23,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961548", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:19:13.000Z", + "threat.indicator.ip": "103.72.223.103", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961548/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "103.72.223.103", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://103.72.223.103:34613/Mozi.m", + "threat.indicator.url.original": "http://103.72.223.103:34613/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 34613, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961546", + "abusech.url.larted": false, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:19:13.000Z", - "threatintel.indicator.ip": "103.72.223.103", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961548/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "103.72.223.103", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://103.72.223.103:34613/Mozi.m", - "threatintel.indicator.url.original": "http://103.72.223.103:34613/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 34613, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -50,30 +62,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961546", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:19:05.000Z", + "threat.indicator.ip": "112.30.97.184", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961546/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "112.30.97.184", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://112.30.97.184:44941/Mozi.m", + "threat.indicator.url.original": "http://112.30.97.184:44941/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 44941, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961547", + "abusech.url.larted": false, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:19:05.000Z", - "threatintel.indicator.ip": "112.30.97.184", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961546/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "112.30.97.184", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://112.30.97.184:44941/Mozi.m", - "threatintel.indicator.url.original": "http://112.30.97.184:44941/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 44941, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -87,30 +101,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961547", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:19:05.000Z", + "threat.indicator.ip": "113.110.198.53", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961547/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "113.110.198.53", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://113.110.198.53:37173/Mozi.m", + "threat.indicator.url.original": "http://113.110.198.53:37173/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 37173, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961545", + "abusech.url.larted": false, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:19:05.000Z", - "threatintel.indicator.ip": "113.110.198.53", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961547/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "113.110.198.53", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://113.110.198.53:37173/Mozi.m", - "threatintel.indicator.url.original": "http://113.110.198.53:37173/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 37173, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -124,30 +140,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961545", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:19:04.000Z", + "threat.indicator.ip": "101.20.183.170", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961545/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "101.20.183.170", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://101.20.183.170:47545/Mozi.m", + "threat.indicator.url.original": "http://101.20.183.170:47545/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 47545, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961544", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:19:04.000Z", - "threatintel.indicator.ip": "101.20.183.170", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961545/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "101.20.183.170", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://101.20.183.170:47545/Mozi.m", - "threatintel.indicator.url.original": "http://101.20.183.170:47545/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 47545, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -161,30 +179,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961544", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:07.000Z", + "threat.indicator.ip": "59.8.35.22", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961544/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "59.8.35.22", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://59.8.35.22:44782/Mozi.a", + "threat.indicator.url.original": "http://59.8.35.22:44782/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 44782, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961543", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:07.000Z", - "threatintel.indicator.ip": "59.8.35.22", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961544/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "59.8.35.22", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://59.8.35.22:44782/Mozi.a", - "threatintel.indicator.url.original": "http://59.8.35.22:44782/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 44782, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -198,30 +218,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961543", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:06.000Z", + "threat.indicator.ip": "59.96.37.35", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961543/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "59.96.37.35", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://59.96.37.35:44359/Mozi.a", + "threat.indicator.url.original": "http://59.96.37.35:44359/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 44359, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961540", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:06.000Z", - "threatintel.indicator.ip": "59.96.37.35", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961543/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "59.96.37.35", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://59.96.37.35:44359/Mozi.a", - "threatintel.indicator.url.original": "http://59.96.37.35:44359/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 44359, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -235,30 +257,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961540", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:05.000Z", + "threat.indicator.ip": "42.239.233.17", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961540/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.239.233.17", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.239.233.17:56507/Mozi.m", + "threat.indicator.url.original": "http://42.239.233.17:56507/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 56507, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961541", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:05.000Z", - "threatintel.indicator.ip": "42.239.233.17", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961540/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.239.233.17", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.239.233.17:56507/Mozi.m", - "threatintel.indicator.url.original": "http://42.239.233.17:56507/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 56507, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -272,30 +296,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961541", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:05.000Z", + "threat.indicator.ip": "58.252.178.20", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961541/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "58.252.178.20", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://58.252.178.20:57562/Mozi.m", + "threat.indicator.url.original": "http://58.252.178.20:57562/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 57562, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961542", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:05.000Z", - "threatintel.indicator.ip": "58.252.178.20", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961541/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "58.252.178.20", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://58.252.178.20:57562/Mozi.m", - "threatintel.indicator.url.original": "http://58.252.178.20:57562/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 57562, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -309,30 +335,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961542", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:05.000Z", + "threat.indicator.ip": "45.176.111.95", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961542/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "45.176.111.95", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://45.176.111.95:48845/Mozi.m", + "threat.indicator.url.original": "http://45.176.111.95:48845/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 48845, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961539", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:05.000Z", - "threatintel.indicator.ip": "45.176.111.95", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961542/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "45.176.111.95", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://45.176.111.95:48845/Mozi.m", - "threatintel.indicator.url.original": "http://45.176.111.95:48845/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 48845, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -346,30 +374,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961539", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:07:04.000Z", + "threat.indicator.ip": "42.224.68.97", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961539/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.224.68.97", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.224.68.97:58245/Mozi.m", + "threat.indicator.url.original": "http://42.224.68.97:58245/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 58245, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961538", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:07:04.000Z", - "threatintel.indicator.ip": "42.224.68.97", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961539/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.224.68.97", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.224.68.97:58245/Mozi.m", - "threatintel.indicator.url.original": "http://42.224.68.97:58245/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 58245, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -383,30 +413,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961538", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:08.000Z", + "threat.indicator.ip": "222.81.144.207", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961538/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "222.81.144.207", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://222.81.144.207:37198/Mozi.m", + "threat.indicator.url.original": "http://222.81.144.207:37198/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 37198, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961537", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:08.000Z", - "threatintel.indicator.ip": "222.81.144.207", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961538/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "222.81.144.207", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://222.81.144.207:37198/Mozi.m", - "threatintel.indicator.url.original": "http://222.81.144.207:37198/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 37198, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -420,30 +452,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961537", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:06.000Z", + "threat.indicator.ip": "182.127.185.137", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961537/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.127.185.137", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://182.127.185.137:33524/Mozi.m", + "threat.indicator.url.original": "http://182.127.185.137:33524/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 33524, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961531", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:06.000Z", - "threatintel.indicator.ip": "182.127.185.137", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961537/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.127.185.137", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://182.127.185.137:33524/Mozi.m", - "threatintel.indicator.url.original": "http://182.127.185.137:33524/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 33524, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -457,30 +491,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961531", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "39.84.175.185", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961531/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "39.84.175.185", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://39.84.175.185:48261/Mozi.a", + "threat.indicator.url.original": "http://39.84.175.185:48261/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 48261, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961532", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "39.84.175.185", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961531/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "39.84.175.185", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://39.84.175.185:48261/Mozi.a", - "threatintel.indicator.url.original": "http://39.84.175.185:48261/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 48261, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -494,30 +530,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961532", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "27.41.11.238", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961532/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "27.41.11.238", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://27.41.11.238:34478/Mozi.m", + "threat.indicator.url.original": "http://27.41.11.238:34478/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 34478, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961533", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "27.41.11.238", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961532/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "27.41.11.238", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://27.41.11.238:34478/Mozi.m", - "threatintel.indicator.url.original": "http://27.41.11.238:34478/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 34478, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -531,30 +569,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961533", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "182.127.133.68", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961533/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.127.133.68", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://182.127.133.68:35703/Mozi.a", + "threat.indicator.url.original": "http://182.127.133.68:35703/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 35703, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961534", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "182.127.133.68", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961533/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.127.133.68", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://182.127.133.68:35703/Mozi.a", - "threatintel.indicator.url.original": "http://182.127.133.68:35703/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 35703, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -568,30 +608,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961534", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "27.46.44.102", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961534/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "27.46.44.102", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://27.46.44.102:48666/Mozi.m", + "threat.indicator.url.original": "http://27.46.44.102:48666/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 48666, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961535", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "27.46.44.102", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961534/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "27.46.44.102", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://27.46.44.102:48666/Mozi.m", - "threatintel.indicator.url.original": "http://27.46.44.102:48666/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 48666, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -605,30 +647,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961535", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "39.70.88.65", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961535/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "39.70.88.65", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://39.70.88.65:53923/Mozi.m", + "threat.indicator.url.original": "http://39.70.88.65:53923/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 53923, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961536", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "39.70.88.65", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961535/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "39.70.88.65", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://39.70.88.65:53923/Mozi.m", - "threatintel.indicator.url.original": "http://39.70.88.65:53923/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 53923, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -642,30 +686,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961536", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:06:05.000Z", + "threat.indicator.ip": "42.224.136.237", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961536/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.224.136.237", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.224.136.237:52794/Mozi.m", + "threat.indicator.url.original": "http://42.224.136.237:52794/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 52794, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961530", + "abusech.url.larted": false, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:06:05.000Z", - "threatintel.indicator.ip": "42.224.136.237", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961536/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.224.136.237", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.224.136.237:52794/Mozi.m", - "threatintel.indicator.url.original": "http://42.224.136.237:52794/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 52794, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -679,30 +725,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961530", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:34.000Z", + "threat.indicator.ip": "117.208.135.63", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961530/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "117.208.135.63", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://117.208.135.63:49312/Mozi.a", + "threat.indicator.url.original": "http://117.208.135.63:49312/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 49312, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961525", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:05:34.000Z", - "threatintel.indicator.ip": "117.208.135.63", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961530/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "117.208.135.63", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://117.208.135.63:49312/Mozi.a", - "threatintel.indicator.url.original": "http://117.208.135.63:49312/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 49312, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -716,30 +764,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961525", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:06.000Z", + "threat.indicator.ip": "125.47.66.60", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961525/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "125.47.66.60", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://125.47.66.60:38961/Mozi.m", + "threat.indicator.url.original": "http://125.47.66.60:38961/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 38961, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961526", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:05:06.000Z", - "threatintel.indicator.ip": "125.47.66.60", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961525/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "125.47.66.60", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://125.47.66.60:38961/Mozi.m", - "threatintel.indicator.url.original": "http://125.47.66.60:38961/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 38961, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -753,30 +803,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961526", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:06.000Z", + "threat.indicator.ip": "182.117.95.148", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961526/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.117.95.148", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://182.117.95.148:50420/Mozi.a", + "threat.indicator.url.original": "http://182.117.95.148:50420/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 50420, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961527", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:05:06.000Z", - "threatintel.indicator.ip": "182.117.95.148", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961526/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.117.95.148", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://182.117.95.148:50420/Mozi.a", - "threatintel.indicator.url.original": "http://182.117.95.148:50420/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 50420, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -790,30 +842,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961527", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:06.000Z", + "threat.indicator.ip": "117.202.71.48", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961527/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "117.202.71.48", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://117.202.71.48:55007/Mozi.m", + "threat.indicator.url.original": "http://117.202.71.48:55007/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 55007, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961528", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:05:06.000Z", - "threatintel.indicator.ip": "117.202.71.48", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961527/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "117.202.71.48", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://117.202.71.48:55007/Mozi.m", - "threatintel.indicator.url.original": "http://117.202.71.48:55007/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 55007, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -827,30 +881,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961528", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:06.000Z", + "threat.indicator.ip": "125.99.132.118", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961528/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "125.99.132.118", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://125.99.132.118:51143/Mozi.m", + "threat.indicator.url.original": "http://125.99.132.118:51143/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 51143, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961529", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:05:06.000Z", - "threatintel.indicator.ip": "125.99.132.118", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961528/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "125.99.132.118", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://125.99.132.118:51143/Mozi.m", - "threatintel.indicator.url.original": "http://125.99.132.118:51143/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 51143, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -864,30 +920,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961529", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi", - "elf" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:05:06.000Z", - "threatintel.indicator.ip": "182.114.123.69", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961529/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.114.123.69", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://182.114.123.69:41003/Mozi.m", - "threatintel.indicator.url.original": "http://182.114.123.69:41003/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 41003, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:05:06.000Z", + "threat.indicator.ip": "182.114.123.69", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961529/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.114.123.69", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://182.114.123.69:41003/Mozi.m", + "threat.indicator.url.original": "http://182.114.123.69:41003/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 41003, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961524", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -901,29 +958,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961524", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:04:38.000Z", - "threatintel.indicator.ip": "116.19.127.37", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961524/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "116.19.127.37", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://116.19.127.37:35739/Mozi.m", - "threatintel.indicator.url.original": "http://116.19.127.37:35739/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 35739, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:38.000Z", + "threat.indicator.ip": "116.19.127.37", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961524/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "116.19.127.37", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://116.19.127.37:35739/Mozi.m", + "threat.indicator.url.original": "http://116.19.127.37:35739/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 35739, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961523", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -937,29 +996,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961523", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:04:36.000Z", - "threatintel.indicator.ip": "42.239.253.55", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961523/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.239.253.55", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.239.253.55:45653/Mozi.m", - "threatintel.indicator.url.original": "http://42.239.253.55:45653/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 45653, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:36.000Z", + "threat.indicator.ip": "42.239.253.55", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961523/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.239.253.55", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.239.253.55:45653/Mozi.m", + "threat.indicator.url.original": "http://42.239.253.55:45653/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 45653, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961520", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -973,29 +1034,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961520", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:04:33.000Z", - "threatintel.indicator.ip": "103.217.121.228", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961520/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "103.217.121.228", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://103.217.121.228:41349/Mozi.m", - "threatintel.indicator.url.original": "http://103.217.121.228:41349/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 41349, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:33.000Z", + "threat.indicator.ip": "103.217.121.228", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961520/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "103.217.121.228", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://103.217.121.228:41349/Mozi.m", + "threat.indicator.url.original": "http://103.217.121.228:41349/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 41349, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961521", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1009,29 +1072,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961521", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:04:33.000Z", - "threatintel.indicator.ip": "111.92.81.255", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961521/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "111.92.81.255", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://111.92.81.255:48586/Mozi.m", - "threatintel.indicator.url.original": "http://111.92.81.255:48586/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 48586, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:33.000Z", + "threat.indicator.ip": "111.92.81.255", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961521/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "111.92.81.255", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://111.92.81.255:48586/Mozi.m", + "threat.indicator.url.original": "http://111.92.81.255:48586/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 48586, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961522", + "abusech.url.larted": false, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1045,29 +1110,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961522", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T21:04:33.000Z", - "threatintel.indicator.ip": "45.229.55.75", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961522/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "45.229.55.75", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://45.229.55.75:38111/Mozi.m", - "threatintel.indicator.url.original": "http://45.229.55.75:38111/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 38111, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:33.000Z", + "threat.indicator.ip": "45.229.55.75", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961522/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "45.229.55.75", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://45.229.55.75:38111/Mozi.m", + "threat.indicator.url.original": "http://45.229.55.75:38111/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 38111, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961518", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1081,29 +1148,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961518", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:10.000Z", - "threatintel.indicator.ip": "182.121.242.148", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961518/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.121.242.148", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://182.121.242.148:34556/Mozi.m", - "threatintel.indicator.url.original": "http://182.121.242.148:34556/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 34556, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:10.000Z", + "threat.indicator.ip": "182.121.242.148", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961518/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.121.242.148", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://182.121.242.148:34556/Mozi.m", + "threat.indicator.url.original": "http://182.121.242.148:34556/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 34556, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961519", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi", + "elf" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1117,30 +1187,33 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961519", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi", - "elf" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:10.000Z", - "threatintel.indicator.ip": "106.115.189.249", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961519/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "106.115.189.249", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://106.115.189.249:59815/Mozi.m", - "threatintel.indicator.url.original": "http://106.115.189.249:59815/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 59815, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:10.000Z", + "threat.indicator.ip": "106.115.189.249", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961519/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "106.115.189.249", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://106.115.189.249:59815/Mozi.m", + "threat.indicator.url.original": "http://106.115.189.249:59815/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 59815, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961516", + "abusech.url.larted": true, + "abusech.url.tags": [ + "32-bit", + "elf", + "mips" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1154,31 +1227,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961516", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "32-bit", - "elf", - "mips" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:08.000Z", - "threatintel.indicator.ip": "182.117.93.110", - "threatintel.indicator.provider": "geenensp", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961516/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.117.93.110", - "threatintel.indicator.url.extension": "sh", - "threatintel.indicator.url.full": "http://182.117.93.110:50587/bin.sh", - "threatintel.indicator.url.original": "http://182.117.93.110:50587/bin.sh", - "threatintel.indicator.url.path": "/bin.sh", - "threatintel.indicator.url.port": 50587, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:08.000Z", + "threat.indicator.ip": "182.117.93.110", + "threat.indicator.provider": "geenensp", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961516/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.117.93.110", + "threat.indicator.url.extension": "sh", + "threat.indicator.url.full": "http://182.117.93.110:50587/bin.sh", + "threat.indicator.url.original": "http://182.117.93.110:50587/bin.sh", + "threat.indicator.url.path": "/bin.sh", + "threat.indicator.url.port": 50587, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961517", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi", + "elf" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1192,30 +1266,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961517", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi", - "elf" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:08.000Z", - "threatintel.indicator.ip": "110.251.5.169", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961517/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "110.251.5.169", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://110.251.5.169:48322/Mozi.m", - "threatintel.indicator.url.original": "http://110.251.5.169:48322/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 48322, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:08.000Z", + "threat.indicator.ip": "110.251.5.169", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961517/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "110.251.5.169", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://110.251.5.169:48322/Mozi.m", + "threat.indicator.url.original": "http://110.251.5.169:48322/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 48322, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961515", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1229,29 +1304,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961515", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:06.000Z", - "threatintel.indicator.ip": "101.51.117.186", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961515/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "101.51.117.186", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://101.51.117.186:33317/Mozi.m", - "threatintel.indicator.url.original": "http://101.51.117.186:33317/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 33317, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:06.000Z", + "threat.indicator.ip": "101.51.117.186", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961515/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "101.51.117.186", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://101.51.117.186:33317/Mozi.m", + "threat.indicator.url.original": "http://101.51.117.186:33317/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 33317, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961513", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1265,29 +1342,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961513", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:05.000Z", - "threatintel.indicator.ip": "121.151.78.166", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961513/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "121.151.78.166", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://121.151.78.166:41516/Mozi.m", - "threatintel.indicator.url.original": "http://121.151.78.166:41516/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 41516, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:05.000Z", + "threat.indicator.ip": "121.151.78.166", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961513/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "121.151.78.166", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://121.151.78.166:41516/Mozi.m", + "threat.indicator.url.original": "http://121.151.78.166:41516/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 41516, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961514", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1301,29 +1380,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961514", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:05.000Z", - "threatintel.indicator.ip": "116.72.92.97", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961514/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "116.72.92.97", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://116.72.92.97:57798/Mozi.m", - "threatintel.indicator.url.original": "http://116.72.92.97:57798/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 57798, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:05.000Z", + "threat.indicator.ip": "116.72.92.97", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961514/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "116.72.92.97", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://116.72.92.97:57798/Mozi.m", + "threat.indicator.url.original": "http://116.72.92.97:57798/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 57798, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961509", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1337,29 +1418,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961509", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:04.000Z", - "threatintel.indicator.ip": "27.218.15.209", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961509/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "27.218.15.209", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://27.218.15.209:47671/Mozi.m", - "threatintel.indicator.url.original": "http://27.218.15.209:47671/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 47671, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:04.000Z", + "threat.indicator.ip": "27.218.15.209", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961509/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "27.218.15.209", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://27.218.15.209:47671/Mozi.m", + "threat.indicator.url.original": "http://27.218.15.209:47671/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 47671, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961510", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1373,29 +1456,33 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961510", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:04.000Z", - "threatintel.indicator.ip": "120.85.171.210", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961510/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "120.85.171.210", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://120.85.171.210:57690/Mozi.m", - "threatintel.indicator.url.original": "http://120.85.171.210:57690/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 57690, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:04.000Z", + "threat.indicator.ip": "120.85.171.210", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961510/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "120.85.171.210", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://120.85.171.210:57690/Mozi.m", + "threat.indicator.url.original": "http://120.85.171.210:57690/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 57690, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961511", + "abusech.url.larted": true, + "abusech.url.tags": [ + "32-bit", + "elf", + "mips" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1409,30 +1496,30 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961511", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "32-bit", - "elf", - "mips" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:04.000Z", - "threatintel.indicator.ip": "117.251.59.53", - "threatintel.indicator.provider": "geenensp", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961511/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "117.251.59.53", - "threatintel.indicator.url.full": "http://117.251.59.53:50611/i", - "threatintel.indicator.url.original": "http://117.251.59.53:50611/i", - "threatintel.indicator.url.path": "/i", - "threatintel.indicator.url.port": 50611, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:04.000Z", + "threat.indicator.ip": "117.251.59.53", + "threat.indicator.provider": "geenensp", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961511/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "117.251.59.53", + "threat.indicator.url.full": "http://117.251.59.53:50611/i", + "threat.indicator.url.original": "http://117.251.59.53:50611/i", + "threat.indicator.url.path": "/i", + "threat.indicator.url.port": 50611, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961512", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1446,29 +1533,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961512", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T21:04:04.000Z", - "threatintel.indicator.ip": "115.58.83.167", - "threatintel.indicator.provider": "Gandylyan1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961512/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "115.58.83.167", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://115.58.83.167:34141/Mozi.m", - "threatintel.indicator.url.original": "http://115.58.83.167:34141/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 34141, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T21:04:04.000Z", + "threat.indicator.ip": "115.58.83.167", + "threat.indicator.provider": "Gandylyan1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961512/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "115.58.83.167", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://115.58.83.167:34141/Mozi.m", + "threat.indicator.url.original": "http://115.58.83.167:34141/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 34141, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961507", + "abusech.url.larted": true, + "abusech.url.tags": [ + "Mozi", + "elf" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1482,30 +1572,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961507", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:08.000Z", + "threat.indicator.ip": "94.178.124.83", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961507/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "94.178.124.83", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://94.178.124.83:44399/Mozi.m", + "threat.indicator.url.original": "http://94.178.124.83:44399/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 44399, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961508", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:08.000Z", - "threatintel.indicator.ip": "94.178.124.83", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961507/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "94.178.124.83", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://94.178.124.83:44399/Mozi.m", - "threatintel.indicator.url.original": "http://94.178.124.83:44399/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 44399, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1519,30 +1611,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961508", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:08.000Z", + "threat.indicator.ip": "182.122.75.232", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961508/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "182.122.75.232", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://182.122.75.232:49120/Mozi.m", + "threat.indicator.url.original": "http://182.122.75.232:49120/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 49120, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961506", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:08.000Z", - "threatintel.indicator.ip": "182.122.75.232", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961508/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "182.122.75.232", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://182.122.75.232:49120/Mozi.m", - "threatintel.indicator.url.original": "http://182.122.75.232:49120/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 49120, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1556,30 +1650,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961506", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:07.000Z", + "threat.indicator.ip": "115.63.202.43", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961506/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "115.63.202.43", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://115.63.202.43:51136/Mozi.m", + "threat.indicator.url.original": "http://115.63.202.43:51136/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 51136, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961504", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:07.000Z", - "threatintel.indicator.ip": "115.63.202.43", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961506/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "115.63.202.43", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://115.63.202.43:51136/Mozi.m", - "threatintel.indicator.url.original": "http://115.63.202.43:51136/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 51136, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1593,30 +1689,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961504", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:06.000Z", + "threat.indicator.ip": "59.99.40.204", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961504/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "59.99.40.204", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://59.99.40.204:45773/Mozi.m", + "threat.indicator.url.original": "http://59.99.40.204:45773/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 45773, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961505", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:06.000Z", - "threatintel.indicator.ip": "59.99.40.204", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961504/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "59.99.40.204", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://59.99.40.204:45773/Mozi.m", - "threatintel.indicator.url.original": "http://59.99.40.204:45773/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 45773, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1630,30 +1728,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961505", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:06.000Z", + "threat.indicator.ip": "117.247.128.213", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961505/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "117.247.128.213", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://117.247.128.213:56528/Mozi.m", + "threat.indicator.url.original": "http://117.247.128.213:56528/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 56528, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961500", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:06.000Z", - "threatintel.indicator.ip": "117.247.128.213", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961505/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "117.247.128.213", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://117.247.128.213:56528/Mozi.m", - "threatintel.indicator.url.original": "http://117.247.128.213:56528/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 56528, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1667,30 +1767,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961500", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:05.000Z", + "threat.indicator.ip": "14.137.219.132", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961500/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "14.137.219.132", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://14.137.219.132:44427/Mozi.a", + "threat.indicator.url.original": "http://14.137.219.132:44427/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 44427, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961501", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:05.000Z", - "threatintel.indicator.ip": "14.137.219.132", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961500/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "14.137.219.132", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://14.137.219.132:44427/Mozi.a", - "threatintel.indicator.url.original": "http://14.137.219.132:44427/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 44427, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1704,30 +1806,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961501", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:05.000Z", + "threat.indicator.ip": "42.224.40.14", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961501/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.224.40.14", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.224.40.14:36134/Mozi.m", + "threat.indicator.url.original": "http://42.224.40.14:36134/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 36134, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961502", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:05.000Z", - "threatintel.indicator.ip": "42.224.40.14", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961501/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.224.40.14", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.224.40.14:36134/Mozi.m", - "threatintel.indicator.url.original": "http://42.224.40.14:36134/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 36134, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1741,30 +1845,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961502", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:05.000Z", + "threat.indicator.ip": "186.33.104.107", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961502/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "186.33.104.107", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://186.33.104.107:43973/Mozi.m", + "threat.indicator.url.original": "http://186.33.104.107:43973/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 43973, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961503", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:05.000Z", - "threatintel.indicator.ip": "186.33.104.107", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961502/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "186.33.104.107", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://186.33.104.107:43973/Mozi.m", - "threatintel.indicator.url.original": "http://186.33.104.107:43973/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 43973, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1778,30 +1884,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961503", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:05.000Z", + "threat.indicator.ip": "85.105.16.154", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961503/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "85.105.16.154", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://85.105.16.154:41319/Mozi.m", + "threat.indicator.url.original": "http://85.105.16.154:41319/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 41319, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961496", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:05.000Z", - "threatintel.indicator.ip": "85.105.16.154", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961503/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "85.105.16.154", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://85.105.16.154:41319/Mozi.m", - "threatintel.indicator.url.original": "http://85.105.16.154:41319/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 41319, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1815,30 +1923,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961496", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:04.000Z", + "threat.indicator.ip": "178.141.73.115", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961496/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "178.141.73.115", + "threat.indicator.url.extension": "a", + "threat.indicator.url.full": "http://178.141.73.115:51847/Mozi.a", + "threat.indicator.url.original": "http://178.141.73.115:51847/Mozi.a", + "threat.indicator.url.path": "/Mozi.a", + "threat.indicator.url.port": 51847, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961497", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:04.000Z", - "threatintel.indicator.ip": "178.141.73.115", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961496/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "178.141.73.115", - "threatintel.indicator.url.extension": "a", - "threatintel.indicator.url.full": "http://178.141.73.115:51847/Mozi.a", - "threatintel.indicator.url.original": "http://178.141.73.115:51847/Mozi.a", - "threatintel.indicator.url.path": "/Mozi.a", - "threatintel.indicator.url.port": 51847, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1852,30 +1962,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961497", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:04.000Z", + "threat.indicator.ip": "186.33.104.135", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961497/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "186.33.104.135", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://186.33.104.135:54469/Mozi.m", + "threat.indicator.url.original": "http://186.33.104.135:54469/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 54469, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961498", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:04.000Z", - "threatintel.indicator.ip": "186.33.104.135", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961497/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "186.33.104.135", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://186.33.104.135:54469/Mozi.m", - "threatintel.indicator.url.original": "http://186.33.104.135:54469/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 54469, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1889,30 +2001,32 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961498", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:04.000Z", + "threat.indicator.ip": "115.56.159.43", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961498/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "115.56.159.43", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://115.56.159.43:34547/Mozi.m", + "threat.indicator.url.original": "http://115.56.159.43:34547/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 34547, + "threat.indicator.url.scheme": "http" + }, + { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961499", + "abusech.url.larted": true, + "abusech.url.tags": [ "Mozi", "elf" ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:04.000Z", - "threatintel.indicator.ip": "115.56.159.43", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961498/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "115.56.159.43", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://115.56.159.43:34547/Mozi.m", - "threatintel.indicator.url.original": "http://115.56.159.43:34547/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 34547, - "threatintel.indicator.url.scheme": "http" - }, - { + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "online", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1926,30 +2040,31 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961499", - "threatintel.abuseurl.larted": true, - "threatintel.abuseurl.tags": [ - "Mozi", - "elf" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "online", - "threatintel.indicator.first_seen": "2021-01-14T20:52:04.000Z", - "threatintel.indicator.ip": "42.230.138.170", - "threatintel.indicator.provider": "lrz_urlhaus", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961499/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "42.230.138.170", - "threatintel.indicator.url.extension": "m", - "threatintel.indicator.url.full": "http://42.230.138.170:33932/Mozi.m", - "threatintel.indicator.url.original": "http://42.230.138.170:33932/Mozi.m", - "threatintel.indicator.url.path": "/Mozi.m", - "threatintel.indicator.url.port": 33932, - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:52:04.000Z", + "threat.indicator.ip": "42.230.138.170", + "threat.indicator.provider": "lrz_urlhaus", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961499/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "42.230.138.170", + "threat.indicator.url.extension": "m", + "threat.indicator.url.full": "http://42.230.138.170:33932/Mozi.m", + "threat.indicator.url.original": "http://42.230.138.170:33932/Mozi.m", + "threat.indicator.url.path": "/Mozi.m", + "threat.indicator.url.port": 33932, + "threat.indicator.url.scheme": "http" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961494", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1963,27 +2078,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961494", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:47.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961494/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://univirtek.com/viro/02478080035/blank.jpg", - "threatintel.indicator.url.original": "https://univirtek.com/viro/02478080035/blank.jpg", - "threatintel.indicator.url.path": "/viro/02478080035/blank.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:47.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961494/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://univirtek.com/viro/02478080035/blank.jpg", + "threat.indicator.url.original": "https://univirtek.com/viro/02478080035/blank.jpg", + "threat.indicator.url.path": "/viro/02478080035/blank.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961495", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -1997,27 +2114,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961495", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:47.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961495/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://univirtek.com/viro/FRRNDR77C25D325O/map.png", - "threatintel.indicator.url.original": "https://univirtek.com/viro/FRRNDR77C25D325O/map.png", - "threatintel.indicator.url.path": "/viro/FRRNDR77C25D325O/map.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:47.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961495/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://univirtek.com/viro/FRRNDR77C25D325O/map.png", + "threat.indicator.url.original": "https://univirtek.com/viro/FRRNDR77C25D325O/map.png", + "threat.indicator.url.path": "/viro/FRRNDR77C25D325O/map.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961492", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2031,27 +2150,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961492", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:45.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961492/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/CNNSRG83H04F158R/blank.jpg", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/CNNSRG83H04F158R/blank.jpg", - "threatintel.indicator.url.path": "/ladi/CNNSRG83H04F158R/blank.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:45.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961492/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/CNNSRG83H04F158R/blank.jpg", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/CNNSRG83H04F158R/blank.jpg", + "threat.indicator.url.path": "/ladi/CNNSRG83H04F158R/blank.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961493", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2065,27 +2186,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961493", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:45.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961493/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "letonguesc.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://letonguesc.com/leto/02328510512/logo.css", - "threatintel.indicator.url.original": "https://letonguesc.com/leto/02328510512/logo.css", - "threatintel.indicator.url.path": "/leto/02328510512/logo.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:45.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961493/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "letonguesc.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://letonguesc.com/leto/02328510512/logo.css", + "threat.indicator.url.original": "https://letonguesc.com/leto/02328510512/logo.css", + "threat.indicator.url.path": "/leto/02328510512/logo.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961490", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2099,27 +2222,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961490", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:44.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961490/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://cxminute.com/minu/MLILSN74B21E507L/uk.png", - "threatintel.indicator.url.original": "https://cxminute.com/minu/MLILSN74B21E507L/uk.png", - "threatintel.indicator.url.path": "/minu/MLILSN74B21E507L/uk.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:44.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961490/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://cxminute.com/minu/MLILSN74B21E507L/uk.png", + "threat.indicator.url.original": "https://cxminute.com/minu/MLILSN74B21E507L/uk.png", + "threat.indicator.url.path": "/minu/MLILSN74B21E507L/uk.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961491", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2133,27 +2258,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961491", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:44.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961491/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://cxminute.com/minu/12875710159/blank.css", - "threatintel.indicator.url.original": "https://cxminute.com/minu/12875710159/blank.css", - "threatintel.indicator.url.path": "/minu/12875710159/blank.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:44.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961491/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://cxminute.com/minu/12875710159/blank.css", + "threat.indicator.url.original": "https://cxminute.com/minu/12875710159/blank.css", + "threat.indicator.url.path": "/minu/12875710159/blank.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961489", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2167,27 +2294,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961489", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:41.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961489/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://cxminute.com/minu/CPNLNZ65M20A200N/maps.gif", - "threatintel.indicator.url.original": "https://cxminute.com/minu/CPNLNZ65M20A200N/maps.gif", - "threatintel.indicator.url.path": "/minu/CPNLNZ65M20A200N/maps.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:41.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961489/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://cxminute.com/minu/CPNLNZ65M20A200N/maps.gif", + "threat.indicator.url.original": "https://cxminute.com/minu/CPNLNZ65M20A200N/maps.gif", + "threat.indicator.url.path": "/minu/CPNLNZ65M20A200N/maps.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961488", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2201,27 +2330,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961488", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:40.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961488/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/DLPCMN64D02D789E/logo.png", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/DLPCMN64D02D789E/logo.png", - "threatintel.indicator.url.path": "/bella/DLPCMN64D02D789E/logo.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:40.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961488/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://belfetproduction.com/bella/DLPCMN64D02D789E/logo.png", + "threat.indicator.url.original": "https://belfetproduction.com/bella/DLPCMN64D02D789E/logo.png", + "threat.indicator.url.path": "/bella/DLPCMN64D02D789E/logo.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961487", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2235,27 +2366,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961487", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:17.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961487/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/01844510469/1x1.jpg", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/01844510469/1x1.jpg", - "threatintel.indicator.url.path": "/bella/01844510469/1x1.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:17.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961487/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://belfetproduction.com/bella/01844510469/1x1.jpg", + "threat.indicator.url.original": "https://belfetproduction.com/bella/01844510469/1x1.jpg", + "threat.indicator.url.path": "/bella/01844510469/1x1.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961485", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2269,27 +2402,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961485", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:16.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961485/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/FRRDNI52M71E522D/logo.css", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/FRRDNI52M71E522D/logo.css", - "threatintel.indicator.url.path": "/ladi/FRRDNI52M71E522D/logo.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:16.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961485/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/FRRDNI52M71E522D/logo.css", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/FRRDNI52M71E522D/logo.css", + "threat.indicator.url.path": "/ladi/FRRDNI52M71E522D/logo.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961486", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2303,27 +2438,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961486", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:16.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961486/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "letonguesc.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://letonguesc.com/leto/CPPMRC65E04H980Q/it.gif", - "threatintel.indicator.url.original": "https://letonguesc.com/leto/CPPMRC65E04H980Q/it.gif", - "threatintel.indicator.url.path": "/leto/CPPMRC65E04H980Q/it.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:16.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961486/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "letonguesc.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://letonguesc.com/leto/CPPMRC65E04H980Q/it.gif", + "threat.indicator.url.original": "https://letonguesc.com/leto/CPPMRC65E04H980Q/it.gif", + "threat.indicator.url.path": "/leto/CPPMRC65E04H980Q/it.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961482", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2337,27 +2474,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961482", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:15.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961482/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://univirtek.com/viro/06389650018/it.css", - "threatintel.indicator.url.original": "https://univirtek.com/viro/06389650018/it.css", - "threatintel.indicator.url.path": "/viro/06389650018/it.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:15.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961482/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://univirtek.com/viro/06389650018/it.css", + "threat.indicator.url.original": "https://univirtek.com/viro/06389650018/it.css", + "threat.indicator.url.path": "/viro/06389650018/it.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961483", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2371,27 +2510,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961483", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:15.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961483/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/CRSRRT61E15H501H/logo.png", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/CRSRRT61E15H501H/logo.png", - "threatintel.indicator.url.path": "/bella/CRSRRT61E15H501H/logo.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:15.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961483/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://belfetproduction.com/bella/CRSRRT61E15H501H/logo.png", + "threat.indicator.url.original": "https://belfetproduction.com/bella/CRSRRT61E15H501H/logo.png", + "threat.indicator.url.path": "/bella/CRSRRT61E15H501H/logo.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961484", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2405,27 +2546,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961484", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:15.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961484/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://cxminute.com/minu/SMPMSM67P05F205U/it.jpg", - "threatintel.indicator.url.original": "https://cxminute.com/minu/SMPMSM67P05F205U/it.jpg", - "threatintel.indicator.url.path": "/minu/SMPMSM67P05F205U/it.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:15.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961484/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://cxminute.com/minu/SMPMSM67P05F205U/it.jpg", + "threat.indicator.url.original": "https://cxminute.com/minu/SMPMSM67P05F205U/it.jpg", + "threat.indicator.url.path": "/minu/SMPMSM67P05F205U/it.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961480", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2439,27 +2582,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961480", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:13.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961480/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://univirtek.com/viro/SBNPQL78A24A783E/uk.png", - "threatintel.indicator.url.original": "https://univirtek.com/viro/SBNPQL78A24A783E/uk.png", - "threatintel.indicator.url.path": "/viro/SBNPQL78A24A783E/uk.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:13.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961480/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://univirtek.com/viro/SBNPQL78A24A783E/uk.png", + "threat.indicator.url.original": "https://univirtek.com/viro/SBNPQL78A24A783E/uk.png", + "threat.indicator.url.path": "/viro/SBNPQL78A24A783E/uk.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961481", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2473,27 +2618,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961481", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:13.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961481/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://cxminute.com/minu/15578761007/maps.jpg", - "threatintel.indicator.url.original": "https://cxminute.com/minu/15578761007/maps.jpg", - "threatintel.indicator.url.path": "/minu/15578761007/maps.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:13.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961481/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://cxminute.com/minu/15578761007/maps.jpg", + "threat.indicator.url.original": "https://cxminute.com/minu/15578761007/maps.jpg", + "threat.indicator.url.path": "/minu/15578761007/maps.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961478", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2507,27 +2654,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961478", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:10.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961478/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://univirtek.com/viro/03079590133/1x1.png", - "threatintel.indicator.url.original": "https://univirtek.com/viro/03079590133/1x1.png", - "threatintel.indicator.url.path": "/viro/03079590133/1x1.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:10.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961478/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://univirtek.com/viro/03079590133/1x1.png", + "threat.indicator.url.original": "https://univirtek.com/viro/03079590133/1x1.png", + "threat.indicator.url.path": "/viro/03079590133/1x1.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961479", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2541,27 +2690,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961479", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:51:10.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961479/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/BNCLNR77T56M082U/it.gif", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/BNCLNR77T56M082U/it.gif", - "threatintel.indicator.url.path": "/ladi/BNCLNR77T56M082U/it.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:51:10.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961479/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/BNCLNR77T56M082U/it.gif", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/BNCLNR77T56M082U/it.gif", + "threat.indicator.url.path": "/ladi/BNCLNR77T56M082U/it.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961476", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2575,27 +2726,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961476", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:45.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961476/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://cxminute.com/minu/JNKMTJ64B29L424O/uk.css", - "threatintel.indicator.url.original": "https://cxminute.com/minu/JNKMTJ64B29L424O/uk.css", - "threatintel.indicator.url.path": "/minu/JNKMTJ64B29L424O/uk.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:45.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961476/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://cxminute.com/minu/JNKMTJ64B29L424O/uk.css", + "threat.indicator.url.original": "https://cxminute.com/minu/JNKMTJ64B29L424O/uk.css", + "threat.indicator.url.path": "/minu/JNKMTJ64B29L424O/uk.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961477", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2609,27 +2762,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961477", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:45.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961477/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/PGNMRA64S22I608Z/en.png", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/PGNMRA64S22I608Z/en.png", - "threatintel.indicator.url.path": "/bella/PGNMRA64S22I608Z/en.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:45.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961477/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://belfetproduction.com/bella/PGNMRA64S22I608Z/en.png", + "threat.indicator.url.original": "https://belfetproduction.com/bella/PGNMRA64S22I608Z/en.png", + "threat.indicator.url.path": "/bella/PGNMRA64S22I608Z/en.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961470", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2643,27 +2798,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961470", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961470/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://cxminute.com/minu/RZKDRD77T23Z229T/logo.jpg", - "threatintel.indicator.url.original": "https://cxminute.com/minu/RZKDRD77T23Z229T/logo.jpg", - "threatintel.indicator.url.path": "/minu/RZKDRD77T23Z229T/logo.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961470/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://cxminute.com/minu/RZKDRD77T23Z229T/logo.jpg", + "threat.indicator.url.original": "https://cxminute.com/minu/RZKDRD77T23Z229T/logo.jpg", + "threat.indicator.url.path": "/minu/RZKDRD77T23Z229T/logo.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961471", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2677,27 +2834,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961471", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961471/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "fhivelifestyle.online", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://fhivelifestyle.online/nhbrwvdffsgt/adf/maps.jpg", - "threatintel.indicator.url.original": "https://fhivelifestyle.online/nhbrwvdffsgt/adf/maps.jpg", - "threatintel.indicator.url.path": "/nhbrwvdffsgt/adf/maps.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961471/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "fhivelifestyle.online", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://fhivelifestyle.online/nhbrwvdffsgt/adf/maps.jpg", + "threat.indicator.url.original": "https://fhivelifestyle.online/nhbrwvdffsgt/adf/maps.jpg", + "threat.indicator.url.path": "/nhbrwvdffsgt/adf/maps.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961472", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2711,27 +2870,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961472", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961472/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/05739900487/1x1.css", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/05739900487/1x1.css", - "threatintel.indicator.url.path": "/bella/05739900487/1x1.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961472/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://belfetproduction.com/bella/05739900487/1x1.css", + "threat.indicator.url.original": "https://belfetproduction.com/bella/05739900487/1x1.css", + "threat.indicator.url.path": "/bella/05739900487/1x1.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961473", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2745,27 +2906,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961473", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961473/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/01767180597/map.css", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/01767180597/map.css", - "threatintel.indicator.url.path": "/bella/01767180597/map.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961473/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://belfetproduction.com/bella/01767180597/map.css", + "threat.indicator.url.original": "https://belfetproduction.com/bella/01767180597/map.css", + "threat.indicator.url.path": "/bella/01767180597/map.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961474", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2779,27 +2942,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961474", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961474/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/BRNGRG55D21F394K/map.css", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/BRNGRG55D21F394K/map.css", - "threatintel.indicator.url.path": "/bella/BRNGRG55D21F394K/map.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961474/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://belfetproduction.com/bella/BRNGRG55D21F394K/map.css", + "threat.indicator.url.original": "https://belfetproduction.com/bella/BRNGRG55D21F394K/map.css", + "threat.indicator.url.path": "/bella/BRNGRG55D21F394K/map.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961475", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2813,27 +2978,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961475", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:43.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961475/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://cxminute.com/minu/DLLTZN67L20L157J/1x1.css", - "threatintel.indicator.url.original": "https://cxminute.com/minu/DLLTZN67L20L157J/1x1.css", - "threatintel.indicator.url.path": "/minu/DLLTZN67L20L157J/1x1.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:43.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961475/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://cxminute.com/minu/DLLTZN67L20L157J/1x1.css", + "threat.indicator.url.original": "https://cxminute.com/minu/DLLTZN67L20L157J/1x1.css", + "threat.indicator.url.path": "/minu/DLLTZN67L20L157J/1x1.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961468", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2847,27 +3014,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961468", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:38.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961468/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://cxminute.com/minu/08035410722/logo.jpg", - "threatintel.indicator.url.original": "https://cxminute.com/minu/08035410722/logo.jpg", - "threatintel.indicator.url.path": "/minu/08035410722/logo.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:38.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961468/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://cxminute.com/minu/08035410722/logo.jpg", + "threat.indicator.url.original": "https://cxminute.com/minu/08035410722/logo.jpg", + "threat.indicator.url.path": "/minu/08035410722/logo.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961469", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2881,27 +3050,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961469", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:38.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961469/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://univirtek.com/viro/GRNZEI60M13G346L/en.css", - "threatintel.indicator.url.original": "https://univirtek.com/viro/GRNZEI60M13G346L/en.css", - "threatintel.indicator.url.path": "/viro/GRNZEI60M13G346L/en.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:38.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961469/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://univirtek.com/viro/GRNZEI60M13G346L/en.css", + "threat.indicator.url.original": "https://univirtek.com/viro/GRNZEI60M13G346L/en.css", + "threat.indicator.url.path": "/viro/GRNZEI60M13G346L/en.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961467", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2915,27 +3086,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961467", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:13.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961467/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "letonguesc.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://letonguesc.com/leto/03253350239/1x1.png", - "threatintel.indicator.url.original": "https://letonguesc.com/leto/03253350239/1x1.png", - "threatintel.indicator.url.path": "/leto/03253350239/1x1.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:13.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961467/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "letonguesc.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://letonguesc.com/leto/03253350239/1x1.png", + "threat.indicator.url.original": "https://letonguesc.com/leto/03253350239/1x1.png", + "threat.indicator.url.path": "/leto/03253350239/1x1.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961464", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2949,27 +3122,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961464", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:09.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961464/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/10582470158/uk.css", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/10582470158/uk.css", - "threatintel.indicator.url.path": "/ladi/10582470158/uk.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:09.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961464/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/10582470158/uk.css", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/10582470158/uk.css", + "threat.indicator.url.path": "/ladi/10582470158/uk.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961465", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -2983,27 +3158,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961465", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:09.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961465/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/BTTLNZ68A56D325C/map.css", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/BTTLNZ68A56D325C/map.css", - "threatintel.indicator.url.path": "/ladi/BTTLNZ68A56D325C/map.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:09.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961465/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/BTTLNZ68A56D325C/map.css", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/BTTLNZ68A56D325C/map.css", + "threat.indicator.url.path": "/ladi/BTTLNZ68A56D325C/map.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961466", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3017,27 +3194,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961466", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:09.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961466/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "letonguesc.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://letonguesc.com/leto/NNTLRT68P28A717L/en.jpg", - "threatintel.indicator.url.original": "https://letonguesc.com/leto/NNTLRT68P28A717L/en.jpg", - "threatintel.indicator.url.path": "/leto/NNTLRT68P28A717L/en.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:09.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961466/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "letonguesc.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://letonguesc.com/leto/NNTLRT68P28A717L/en.jpg", + "threat.indicator.url.original": "https://letonguesc.com/leto/NNTLRT68P28A717L/en.jpg", + "threat.indicator.url.path": "/leto/NNTLRT68P28A717L/en.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961461", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3051,27 +3230,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961461", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:08.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961461/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://univirtek.com/viro/CTTNDR89A19B149W/maps.png", - "threatintel.indicator.url.original": "https://univirtek.com/viro/CTTNDR89A19B149W/maps.png", - "threatintel.indicator.url.path": "/viro/CTTNDR89A19B149W/maps.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:08.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961461/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://univirtek.com/viro/CTTNDR89A19B149W/maps.png", + "threat.indicator.url.original": "https://univirtek.com/viro/CTTNDR89A19B149W/maps.png", + "threat.indicator.url.path": "/viro/CTTNDR89A19B149W/maps.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961462", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3085,27 +3266,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961462", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:08.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961462/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://cxminute.com/minu/DRSNTN77B16I197U/logo.css", - "threatintel.indicator.url.original": "https://cxminute.com/minu/DRSNTN77B16I197U/logo.css", - "threatintel.indicator.url.path": "/minu/DRSNTN77B16I197U/logo.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:08.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961462/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://cxminute.com/minu/DRSNTN77B16I197U/logo.css", + "threat.indicator.url.original": "https://cxminute.com/minu/DRSNTN77B16I197U/logo.css", + "threat.indicator.url.path": "/minu/DRSNTN77B16I197U/logo.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961463", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3119,27 +3302,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961463", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:08.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961463/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://univirtek.com/viro/02941830735/uk.css", - "threatintel.indicator.url.original": "https://univirtek.com/viro/02941830735/uk.css", - "threatintel.indicator.url.path": "/viro/02941830735/uk.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:08.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961463/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://univirtek.com/viro/02941830735/uk.css", + "threat.indicator.url.original": "https://univirtek.com/viro/02941830735/uk.css", + "threat.indicator.url.path": "/viro/02941830735/uk.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961458", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3153,27 +3338,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961458", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:07.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961458/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/MNSGCM91A04G240K/it.css", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/MNSGCM91A04G240K/it.css", - "threatintel.indicator.url.path": "/bella/MNSGCM91A04G240K/it.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:07.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961458/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://belfetproduction.com/bella/MNSGCM91A04G240K/it.css", + "threat.indicator.url.original": "https://belfetproduction.com/bella/MNSGCM91A04G240K/it.css", + "threat.indicator.url.path": "/bella/MNSGCM91A04G240K/it.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961459", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3187,27 +3374,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961459", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:07.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961459/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ladiesincode.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://ladiesincode.com/ladi/03108100615/it.jpg", - "threatintel.indicator.url.original": "https://ladiesincode.com/ladi/03108100615/it.jpg", - "threatintel.indicator.url.path": "/ladi/03108100615/it.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:07.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961459/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ladiesincode.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://ladiesincode.com/ladi/03108100615/it.jpg", + "threat.indicator.url.original": "https://ladiesincode.com/ladi/03108100615/it.jpg", + "threat.indicator.url.path": "/ladi/03108100615/it.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961460", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3221,27 +3410,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961460", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:50:07.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961460/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://cxminute.com/minu/PTACSM56A31F604X/en.png", - "threatintel.indicator.url.original": "https://cxminute.com/minu/PTACSM56A31F604X/en.png", - "threatintel.indicator.url.path": "/minu/PTACSM56A31F604X/en.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:50:07.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961460/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://cxminute.com/minu/PTACSM56A31F604X/en.png", + "threat.indicator.url.original": "https://cxminute.com/minu/PTACSM56A31F604X/en.png", + "threat.indicator.url.path": "/minu/PTACSM56A31F604X/en.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961455", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3255,27 +3446,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961455", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:39.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961455/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://univirtek.com/viro/00183050368/en.gif", - "threatintel.indicator.url.original": "https://univirtek.com/viro/00183050368/en.gif", - "threatintel.indicator.url.path": "/viro/00183050368/en.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:39.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961455/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://univirtek.com/viro/00183050368/en.gif", + "threat.indicator.url.original": "https://univirtek.com/viro/00183050368/en.gif", + "threat.indicator.url.path": "/viro/00183050368/en.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961456", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3289,27 +3482,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961456", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:39.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961456/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://cxminute.com/minu/TSNLSN58H30G912H/uk.gif", - "threatintel.indicator.url.original": "https://cxminute.com/minu/TSNLSN58H30G912H/uk.gif", - "threatintel.indicator.url.path": "/minu/TSNLSN58H30G912H/uk.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:39.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961456/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://cxminute.com/minu/TSNLSN58H30G912H/uk.gif", + "threat.indicator.url.original": "https://cxminute.com/minu/TSNLSN58H30G912H/uk.gif", + "threat.indicator.url.path": "/minu/TSNLSN58H30G912H/uk.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961457", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3323,27 +3518,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961457", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:39.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961457/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "letonguesc.com", - "threatintel.indicator.url.extension": "gif", - "threatintel.indicator.url.full": "https://letonguesc.com/leto/08658331007/blank.gif", - "threatintel.indicator.url.original": "https://letonguesc.com/leto/08658331007/blank.gif", - "threatintel.indicator.url.path": "/leto/08658331007/blank.gif", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:39.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961457/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "letonguesc.com", + "threat.indicator.url.extension": "gif", + "threat.indicator.url.full": "https://letonguesc.com/leto/08658331007/blank.gif", + "threat.indicator.url.original": "https://letonguesc.com/leto/08658331007/blank.gif", + "threat.indicator.url.path": "/leto/08658331007/blank.gif", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961450", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3357,27 +3554,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961450", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:37.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961450/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cxminute.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://cxminute.com/minu/01098910324/blank.png", - "threatintel.indicator.url.original": "https://cxminute.com/minu/01098910324/blank.png", - "threatintel.indicator.url.path": "/minu/01098910324/blank.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:37.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961450/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cxminute.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://cxminute.com/minu/01098910324/blank.png", + "threat.indicator.url.original": "https://cxminute.com/minu/01098910324/blank.png", + "threat.indicator.url.path": "/minu/01098910324/blank.png", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961451", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3391,27 +3590,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961451", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:37.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961451/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://univirtek.com/viro/02794390233/uk.css", - "threatintel.indicator.url.original": "https://univirtek.com/viro/02794390233/uk.css", - "threatintel.indicator.url.path": "/viro/02794390233/uk.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:37.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961451/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://univirtek.com/viro/02794390233/uk.css", + "threat.indicator.url.original": "https://univirtek.com/viro/02794390233/uk.css", + "threat.indicator.url.path": "/viro/02794390233/uk.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961452", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3425,27 +3626,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961452", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:37.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961452/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "css", - "threatintel.indicator.url.full": "https://univirtek.com/viro/CSTDNT69D63F754D/en.css", - "threatintel.indicator.url.original": "https://univirtek.com/viro/CSTDNT69D63F754D/en.css", - "threatintel.indicator.url.path": "/viro/CSTDNT69D63F754D/en.css", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:37.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961452/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "css", + "threat.indicator.url.full": "https://univirtek.com/viro/CSTDNT69D63F754D/en.css", + "threat.indicator.url.original": "https://univirtek.com/viro/CSTDNT69D63F754D/en.css", + "threat.indicator.url.path": "/viro/CSTDNT69D63F754D/en.css", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961453", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3459,27 +3662,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961453", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:37.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961453/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://univirtek.com/viro/GSTGNE91B06L219W/1x1.jpg", - "threatintel.indicator.url.original": "https://univirtek.com/viro/GSTGNE91B06L219W/1x1.jpg", - "threatintel.indicator.url.path": "/viro/GSTGNE91B06L219W/1x1.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:37.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961453/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://univirtek.com/viro/GSTGNE91B06L219W/1x1.jpg", + "threat.indicator.url.original": "https://univirtek.com/viro/GSTGNE91B06L219W/1x1.jpg", + "threat.indicator.url.path": "/viro/GSTGNE91B06L219W/1x1.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961454", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3493,27 +3698,29 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961454", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:37.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961454/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "univirtek.com", - "threatintel.indicator.url.extension": "jpg", - "threatintel.indicator.url.full": "https://univirtek.com/viro/03610140125/map.jpg", - "threatintel.indicator.url.original": "https://univirtek.com/viro/03610140125/map.jpg", - "threatintel.indicator.url.path": "/viro/03610140125/map.jpg", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:37.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961454/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "univirtek.com", + "threat.indicator.url.extension": "jpg", + "threat.indicator.url.full": "https://univirtek.com/viro/03610140125/map.jpg", + "threat.indicator.url.original": "https://univirtek.com/viro/03610140125/map.jpg", + "threat.indicator.url.path": "/viro/03610140125/map.jpg", + "threat.indicator.url.scheme": "https" }, { + "abusech.url.blacklists.spamhaus_dbl": "not listed", + "abusech.url.blacklists.surbl": "not listed", + "abusech.url.id": "961448", + "abusech.url.larted": false, + "abusech.url.tags": [ + "sLoad" + ], + "abusech.url.threat": "malware_download", + "abusech.url.url_status": "offline", "event.category": "threat", "event.dataset": "threatintel.abuseurl", "event.kind": "enrichment", @@ -3527,24 +3734,17 @@ "forwarded", "threatintel-abuseurls" ], - "threatintel.abuseurl.blacklists.spamhaus_dbl": "not listed", - "threatintel.abuseurl.blacklists.surbl": "not listed", - "threatintel.abuseurl.id": "961448", - "threatintel.abuseurl.larted": false, - "threatintel.abuseurl.tags": [ - "sLoad" - ], - "threatintel.abuseurl.threat": "malware_download", - "threatintel.abuseurl.url_status": "offline", - "threatintel.indicator.first_seen": "2021-01-14T20:49:36.000Z", - "threatintel.indicator.provider": "Cryptolaemus1", - "threatintel.indicator.reference": "https://urlhaus.abuse.ch/url/961448/", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "belfetproduction.com", - "threatintel.indicator.url.extension": "png", - "threatintel.indicator.url.full": "https://belfetproduction.com/bella/CRRLRD74E09A462T/blank.png", - "threatintel.indicator.url.original": "https://belfetproduction.com/bella/CRRLRD74E09A462T/blank.png", - "threatintel.indicator.url.path": "/bella/CRRLRD74E09A462T/blank.png", - "threatintel.indicator.url.scheme": "https" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH URL", + "threat.indicator.first_seen": "2021-01-14T20:49:36.000Z", + "threat.indicator.provider": "Cryptolaemus1", + "threat.indicator.reference": "https://urlhaus.abuse.ch/url/961448/", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "belfetproduction.com", + "threat.indicator.url.extension": "png", + "threat.indicator.url.full": "https://belfetproduction.com/bella/CRRLRD74E09A462T/blank.png", + "threat.indicator.url.original": "https://belfetproduction.com/bella/CRRLRD74E09A462T/blank.png", + "threat.indicator.url.path": "/bella/CRRLRD74E09A462T/blank.png", + "threat.indicator.url.scheme": "https" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/anomali/_meta/fields.yml b/x-pack/filebeat/module/threatintel/anomali/_meta/fields.yml index 69ab6e22e9ba..696b062b6b28 100644 --- a/x-pack/filebeat/module/threatintel/anomali/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/anomali/_meta/fields.yml @@ -1,4 +1,4 @@ -- name: anomali +- name: anomali.limo type: group description: > Fields for Anomali Threat Intel @@ -50,4 +50,4 @@ - name: object_marking_refs type: keyword description: > - The STIX reference object. \ No newline at end of file + The STIX reference object. diff --git a/x-pack/filebeat/module/threatintel/anomali/config/config.yml b/x-pack/filebeat/module/threatintel/anomali/config/config.yml index a268ddb7559c..1a30d874635e 100644 --- a/x-pack/filebeat/module/threatintel/anomali/config/config.yml +++ b/x-pack/filebeat/module/threatintel/anomali/config/config.yml @@ -30,7 +30,7 @@ request.transforms: value: items 0-10000 - set: target: url.params.match[type] - value: {{ .types }} + value: indicator - set: target: url.params.added_after value: '[[.cursor.timestamp]]' @@ -54,17 +54,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: ["json.id"] - target_field: "@metadata._id" - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml index eccbf5e9826e..94ca3a847518 100644 --- a/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml @@ -1,4 +1,5 @@ -description: Pipeline for parsing Anomali Threat Intel +--- +description: Pipeline for parsing Anomali Limo indicators processors: #################### # Event ECS fields # @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -20,16 +24,30 @@ processors: # General ECS fields # ###################### - rename: - field: json - target_field: threatintel.anomali + field: message + target_field: event.original + ignore_missing: true + - json: + field: event.original + target_field: anomali.limo + - fingerprint: + fields: + - anomali.limo.id + target_field: "_id" ignore_missing: true ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] Anomali Limo" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" ## File indicator operations - date: - field: threatintel.anomali.created + field: anomali.limo.created formats: - "yyyy-MM-dd'T'HH:mm:ssz" - "yyyy-MM-dd'T'HH:mm:ssZ" @@ -39,68 +57,73 @@ processors: - "yyyy-MM-dd'T'HH:mm:ss.SSZ" - "yyyy-MM-dd'T'HH:mm:ss.SSSz" - "yyyy-MM-dd'T'HH:mm:ss.SSSZ" - if: "ctx?.threatintel?.anomali?.created != null" + if: "ctx.anomali?.limo?.created != null" - date: - field: threatintel.anomali.modified - target_field: threatintel.anomali.modified + field: anomali.limo.modified + target_field: anomali.limo.modified formats: + - "yyyy-MM-dd'T'HH:mm:ssz" + - "yyyy-MM-dd'T'HH:mm:ssZ" - "yyyy-MM-dd'T'HH:mm:ss.Sz" - "yyyy-MM-dd'T'HH:mm:ss.SZ" - "yyyy-MM-dd'T'HH:mm:ss.SSz" - "yyyy-MM-dd'T'HH:mm:ss.SSZ" - "yyyy-MM-dd'T'HH:mm:ss.SSSz" - "yyyy-MM-dd'T'HH:mm:ss.SSSZ" - if: "ctx?.threatintel?.anomali?.modified != null" + if: "ctx.anomali?.limo?.modified != null" - date: - field: threatintel.anomali.valid_from - target_field: threatintel.indicator.first_seen + field: anomali.limo.valid_from + target_field: threat.indicator.first_seen formats: + - "yyyy-MM-dd'T'HH:mm:ssz" + - "yyyy-MM-dd'T'HH:mm:ssZ" - "yyyy-MM-dd'T'HH:mm:ss.Sz" - "yyyy-MM-dd'T'HH:mm:ss.SZ" - "yyyy-MM-dd'T'HH:mm:ss.SSz" - "yyyy-MM-dd'T'HH:mm:ss.SSZ" - "yyyy-MM-dd'T'HH:mm:ss.SSSz" - "yyyy-MM-dd'T'HH:mm:ss.SSSZ" - if: "ctx?.threatintel?.anomali?.valid_from != null" + if: "ctx.anomali?.limo?.valid_from != null" - grok: - field: threatintel.anomali.pattern + field: anomali.limo.pattern patterns: - "^\\[%{DATA:_tmp.threattype}:value%{SPACE}=%{SPACE}'%{DATA:_tmp.threatvalue}'\\]" + if: ctx.anomali?.limo?.pattern != null - rename: field: _tmp.threattype - target_field: threatintel.indicator.type + target_field: threat.indicator.type ignore_missing: true - rename: field: _tmp.threatvalue - target_field: threatintel.indicator.ip + target_field: threat.indicator.ip ignore_missing: true - if: "['ipv4-addr', 'ipv6-addr'].contains(ctx?.threatintel?.indicator?.type)" + if: "['ipv4-addr', 'ipv6-addr'].contains(ctx.threat?.indicator?.type)" - uri_parts: field: _tmp.threatvalue - target_field: threatintel.indicator.url + target_field: threat.indicator.url keep_original: true remove_if_successful: true - if: ctx?.threatintel?.indicator?.type == 'url' + if: ctx.threat?.indicator?.type == 'url' - set: - field: threatintel.indicator.url.full - value: "{{{threatintel.indicator.url.original}}}" + field: threat.indicator.url.full + value: "{{{threat.indicator.url.original}}}" ignore_empty_value: true - rename: field: _tmp.threatvalue - target_field: threatintel.indicator.email.address + target_field: threat.indicator.email.address ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'email-addr' + if: ctx.threat?.indicator?.type == 'email-addr' - rename: field: _tmp.threatvalue - target_field: threatintel.indicator.url.domain + target_field: threat.indicator.url.domain ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'domain-name' + if: ctx.threat?.indicator?.type == 'domain-name' - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx.threat?.indicator?.type == null - foreach: - field: threatintel.anomali.labels + field: anomali.limo.labels ignore_missing: true processor: append: @@ -108,9 +131,9 @@ processors: value: "{{_ingest._value}}" allow_duplicates: false - grok: - field: threatintel.anomali.description + field: anomali.limo.description patterns: - - "^%{GREEDYDATA}Source: %{GREEDYDATA:threatintel.indicator.provider}" + - "^%{GREEDYDATA}Source: %{GREEDYDATA:threat.indicator.provider}" ignore_missing: true ignore_failure: true ###################### @@ -140,9 +163,14 @@ processors: } } handleMap(ctx); + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - remove: field: - - threatintel.anomali.created + - anomali.limo.created - message - _tmp ignore_missing: true diff --git a/x-pack/filebeat/module/threatintel/anomali/manifest.yml b/x-pack/filebeat/module/threatintel/anomali/manifest.yml index 1087e00df8a6..bdfcf20a3ade 100644 --- a/x-pack/filebeat/module/threatintel/anomali/manifest.yml +++ b/x-pack/filebeat/module/threatintel/anomali/manifest.yml @@ -8,8 +8,6 @@ var: - name: first_interval default: 24h - name: ssl - - name: types - default: indicators - name: username - name: password - name: url @@ -17,6 +15,8 @@ var: - name: tags default: [threatintel-anomali, forwarded] - name: proxy_url + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/anomali/test/anomali_limo.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/anomali/test/anomali_limo.ndjson.log-expected.json index f527da1ed989..7f998f8c7783 100644 --- a/x-pack/filebeat/module/threatintel/anomali/test/anomali_limo.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/anomali/test/anomali_limo.ndjson.log-expected.json @@ -1,5 +1,20 @@ [ { + "anomali.limo.description": "TS ID: 55241332361; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--44c85d4f-45ca-4977-b693-c810bbfb7a28", + "anomali.limo.labels": [ + "malicious-activity", + "threatstream-confidence-76", + "threatstream-severity-medium" + ], + "anomali.limo.modified": "2020-01-22T02:58:57.431Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ + "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" + ], + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:58:57.431Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -16,32 +31,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332361; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--44c85d4f-45ca-4977-b693-c810bbfb7a28", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:58:57.431Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work6/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332307; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--f9fe5c81-6869-4247-af81-62b7c8aba209", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:58:57.431Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:58:57.503Z", + "anomali.limo.name": "mal_url: http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:58:57.431Z", - "threatintel.indicator.first_seen": "2020-01-22T02:58:57.431Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work6/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work6/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:58:57.503Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -58,32 +75,34 @@ "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332307; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f9fe5c81-6869-4247-af81-62b7c8aba209", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:58:57.503Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "worldatdoor.in", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332302; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--b0e14122-9005-4776-99fc-00872476c6d1", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-68", + "threatstream-confidence-71", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:58:57.503Z", - "threatintel.anomali.name": "mal_url: http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:58:57.570Z", + "anomali.limo.name": "mal_url: http://f0387770.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:58:57.503Z", - "threatintel.indicator.first_seen": "2020-01-22T02:58:57.503Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "worldatdoor.in", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://worldatdoor.in/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/lewis/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0387770.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:58:57.57Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -100,31 +119,33 @@ "threatstream-confidence-71", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332302; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b0e14122-9005-4776-99fc-00872476c6d1", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:58:57.570Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0387770.xsph.ru", + "threat.indicator.url.full": "http://f0387770.xsph.ru/login", + "threat.indicator.url.original": "http://f0387770.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332312; iType: mal_url; State: active; Org: Digital Ocean; Source: CyberCrime", + "anomali.limo.id": "indicator--111ec76f-616d-4aa8-80fd-e11ef0066aba", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-71", + "threatstream-confidence-50", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:58:57.570Z", - "threatintel.anomali.name": "mal_url: http://f0387770.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:58:59.366Z", + "anomali.limo.name": "mal_url: http://178.62.187.103/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0387770.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:58:57.57Z", - "threatintel.indicator.first_seen": "2020-01-22T02:58:57.570Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0387770.xsph.ru", - "threatintel.indicator.url.full": "http://f0387770.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0387770.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://178.62.187.103/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:58:59.366Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -141,31 +162,33 @@ "threatstream-confidence-50", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332312; iType: mal_url; State: active; Org: Digital Ocean; Source: CyberCrime", - "threatintel.anomali.id": "indicator--111ec76f-616d-4aa8-80fd-e11ef0066aba", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:58:59.366Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "178.62.187.103", + "threat.indicator.url.full": "http://178.62.187.103/login", + "threat.indicator.url.original": "http://178.62.187.103/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332386; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--189ce776-6d7e-4e85-9222-de5876644988", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-50", + "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:58:59.366Z", - "threatintel.anomali.name": "mal_url: http://178.62.187.103/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:58:59.457Z", + "anomali.limo.name": "mal_url: http://appareluea.com/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://178.62.187.103/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:58:59.366Z", - "threatintel.indicator.first_seen": "2020-01-22T02:58:59.366Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "178.62.187.103", - "threatintel.indicator.url.full": "http://178.62.187.103/login", - "threatintel.indicator.url.original": "http://178.62.187.103/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://appareluea.com/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:58:59.457Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -182,32 +205,34 @@ "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332386; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--189ce776-6d7e-4e85-9222-de5876644988", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:58:59.457Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "appareluea.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://appareluea.com/panel/admin.php", + "threat.indicator.url.original": "http://appareluea.com/panel/admin.php", + "threat.indicator.url.path": "/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332391; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--a4144d34-b86d-475e-8047-eb46b48ee325", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-66", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:58:59.457Z", - "threatintel.anomali.name": "mal_url: http://appareluea.com/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:06.402Z", + "anomali.limo.name": "mal_url: http://nkpotu.xyz/Kpot3/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://appareluea.com/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:58:59.457Z", - "threatintel.indicator.first_seen": "2020-01-22T02:58:59.457Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "appareluea.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://appareluea.com/panel/admin.php", - "threatintel.indicator.url.original": "http://appareluea.com/panel/admin.php", - "threatintel.indicator.url.path": "/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://nkpotu.xyz/Kpot3/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:06.402Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -224,32 +249,34 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332391; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--a4144d34-b86d-475e-8047-eb46b48ee325", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:06.402Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "nkpotu.xyz", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://nkpotu.xyz/Kpot3/login.php", + "threat.indicator.url.original": "http://nkpotu.xyz/Kpot3/login.php", + "threat.indicator.url.path": "/Kpot3/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332372; iType: mal_ip; State: active; Org: Unified Layer; Source: CyberCrime", + "anomali.limo.id": "indicator--983d9c3d-b7f8-4345-b643-b1d18e6ac6b2", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-49", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:06.402Z", - "threatintel.anomali.name": "mal_url: http://nkpotu.xyz/Kpot3/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:19.990Z", + "anomali.limo.name": "mal_ip: 162.144.128.116", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://nkpotu.xyz/Kpot3/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:06.402Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:06.402Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "nkpotu.xyz", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://nkpotu.xyz/Kpot3/login.php", - "threatintel.indicator.url.original": "http://nkpotu.xyz/Kpot3/login.php", - "threatintel.indicator.url.path": "/Kpot3/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '162.144.128.116']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:19.99Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -266,27 +293,29 @@ "threatstream-confidence-49", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332372; iType: mal_ip; State: active; Org: Unified Layer; Source: CyberCrime", - "threatintel.anomali.id": "indicator--983d9c3d-b7f8-4345-b643-b1d18e6ac6b2", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:19.990Z", + "threat.indicator.ip": "162.144.128.116", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332313; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--f9c6386b-dba2-41f9-8160-d307671e5c8e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-49", + "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:19.990Z", - "threatintel.anomali.name": "mal_ip: 162.144.128.116", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:20.155Z", + "anomali.limo.name": "mal_url: http://ntrcgroup.com/nze/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '162.144.128.116']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:19.99Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:19.990Z", - "threatintel.indicator.ip": "162.144.128.116", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://ntrcgroup.com/nze/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:20.155Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -303,32 +332,34 @@ "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332313; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f9c6386b-dba2-41f9-8160-d307671e5c8e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:20.155Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ntrcgroup.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://ntrcgroup.com/nze/panel/admin.php", + "threat.indicator.url.original": "http://ntrcgroup.com/nze/panel/admin.php", + "threat.indicator.url.path": "/nze/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332350; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--98fad53e-5389-47f7-a3ff-44d334af2d6b", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-79", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:20.155Z", - "threatintel.anomali.name": "mal_url: http://ntrcgroup.com/nze/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:25.521Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://ntrcgroup.com/nze/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:20.155Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:20.155Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ntrcgroup.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://ntrcgroup.com/nze/panel/admin.php", - "threatintel.indicator.url.original": "http://ntrcgroup.com/nze/panel/admin.php", - "threatintel.indicator.url.path": "/nze/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:25.521Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -345,32 +376,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332350; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--98fad53e-5389-47f7-a3ff-44d334af2d6b", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:25.521Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work8/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332291; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--76c01735-fb76-463d-9609-9ea3aedf3f4f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:25.521Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:25.626Z", + "anomali.limo.name": "mal_url: http://f0390764.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:25.521Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:25.521Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work8/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work8/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0390764.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:25.626Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -387,31 +420,33 @@ "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332291; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--76c01735-fb76-463d-9609-9ea3aedf3f4f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:25.626Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0390764.xsph.ru", + "threat.indicator.url.full": "http://f0390764.xsph.ru/login", + "threat.indicator.url.original": "http://f0390764.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332343; iType: mal_ip; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--e0a812dc-63c8-4949-b038-2241b2dbfcdc", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-68", + "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:25.626Z", - "threatintel.anomali.name": "mal_url: http://f0390764.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:36.461Z", + "anomali.limo.name": "mal_ip: 45.143.138.39", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0390764.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:25.626Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:25.626Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0390764.xsph.ru", - "threatintel.indicator.url.full": "http://f0390764.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0390764.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '45.143.138.39']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:36.461Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -428,27 +463,29 @@ "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332343; iType: mal_ip; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e0a812dc-63c8-4949-b038-2241b2dbfcdc", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:36.461Z", + "threat.indicator.ip": "45.143.138.39", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332316; iType: mal_url; State: active; Org: Sksa Technology Sdn Bhd; Source: CyberCrime", + "anomali.limo.id": "indicator--6f0d8607-21cb-4738-9712-f4fd91a37f7d", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-85", + "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:36.461Z", - "threatintel.anomali.name": "mal_ip: 45.143.138.39", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:41.193Z", + "anomali.limo.name": "mal_url: http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '45.143.138.39']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:36.461Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:36.461Z", - "threatintel.indicator.ip": "45.143.138.39", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:41.193Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -465,32 +502,34 @@ "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332316; iType: mal_url; State: active; Org: Sksa Technology Sdn Bhd; Source: CyberCrime", - "threatintel.anomali.id": "indicator--6f0d8607-21cb-4738-9712-f4fd91a37f7d", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:41.193Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "aglfreight.com.my", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", + "threat.indicator.url.original": "http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", + "threat.indicator.url.path": "/inc/js/jstree/biu/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332284; iType: mal_url; State: active; Org: Oltelecom Jsc; Source: CyberCrime", + "anomali.limo.id": "indicator--c649d6d4-87c4-4b76-bfc2-75a509ccb187", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-82", + "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:41.193Z", - "threatintel.anomali.name": "mal_url: http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:41.228Z", + "anomali.limo.name": "mal_url: http://95.182.122.184/", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:41.193Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:41.193Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "aglfreight.com.my", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", - "threatintel.indicator.url.original": "http://aglfreight.com.my/inc/js/jstree/biu/panel/admin.php", - "threatintel.indicator.url.path": "/inc/js/jstree/biu/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://95.182.122.184/']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:41.228Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -507,31 +546,33 @@ "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332284; iType: mal_url; State: active; Org: Oltelecom Jsc; Source: CyberCrime", - "threatintel.anomali.id": "indicator--c649d6d4-87c4-4b76-bfc2-75a509ccb187", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:41.228Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "95.182.122.184", + "threat.indicator.url.full": "http://95.182.122.184/", + "threat.indicator.url.original": "http://95.182.122.184/", + "threat.indicator.url.path": "/", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332337; iType: mal_ip; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--408ebd2d-063f-4646-b2e7-c00519869736", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-61", + "threatstream-confidence-62", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:41.228Z", - "threatintel.anomali.name": "mal_url: http://95.182.122.184/", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:51.313Z", + "anomali.limo.name": "mal_ip: 198.54.115.121", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://95.182.122.184/']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:41.228Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:41.228Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "95.182.122.184", - "threatintel.indicator.url.full": "http://95.182.122.184/", - "threatintel.indicator.url.original": "http://95.182.122.184/", - "threatintel.indicator.url.path": "/", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '198.54.115.121']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:51.313Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -548,27 +589,29 @@ "threatstream-confidence-62", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332337; iType: mal_ip; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--408ebd2d-063f-4646-b2e7-c00519869736", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:51.313Z", + "threat.indicator.ip": "198.54.115.121", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332324; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--e1d215cb-c7a5-40e0-bc53-8f92a2bcaba8", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-62", + "threatstream-confidence-38", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:51.313Z", - "threatintel.anomali.name": "mal_ip: 198.54.115.121", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:51.372Z", + "anomali.limo.name": "mal_ip: 192.185.119.172", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '198.54.115.121']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:51.313Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:51.313Z", - "threatintel.indicator.ip": "198.54.115.121", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '192.185.119.172']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:51.372Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -585,27 +628,29 @@ "threatstream-confidence-38", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332324; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e1d215cb-c7a5-40e0-bc53-8f92a2bcaba8", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:51.372Z", + "threat.indicator.ip": "192.185.119.172", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332296; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--6f3a4a2b-62e3-48ef-94ae-70103f09cf7e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-38", + "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:51.372Z", - "threatintel.anomali.name": "mal_ip: 192.185.119.172", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T02:59:51.442Z", + "anomali.limo.name": "mal_url: http://f0389246.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '192.185.119.172']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:51.372Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:51.372Z", - "threatintel.indicator.ip": "192.185.119.172", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0389246.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T02:59:51.442Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -622,31 +667,33 @@ "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332296; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--6f3a4a2b-62e3-48ef-94ae-70103f09cf7e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T02:59:51.442Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0389246.xsph.ru", + "threat.indicator.url.full": "http://f0389246.xsph.ru/login", + "threat.indicator.url.original": "http://f0389246.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332400; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--213519c9-f511-4188-89c8-159f35f08008", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-61", + "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T02:59:51.442Z", - "threatintel.anomali.name": "mal_url: http://f0389246.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:01.563Z", + "anomali.limo.name": "mal_url: http://appareluea.com/server/cp.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0389246.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T02:59:51.442Z", - "threatintel.indicator.first_seen": "2020-01-22T02:59:51.442Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0389246.xsph.ru", - "threatintel.indicator.url.full": "http://f0389246.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0389246.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://appareluea.com/server/cp.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:01.563Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -663,32 +710,34 @@ "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332400; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--213519c9-f511-4188-89c8-159f35f08008", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:01.563Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "appareluea.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://appareluea.com/server/cp.php", + "threat.indicator.url.original": "http://appareluea.com/server/cp.php", + "threat.indicator.url.path": "/server/cp.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332396; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--5a563c85-c528-4e33-babe-2dcff34f73c4", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-66", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:01.563Z", - "threatintel.anomali.name": "mal_url: http://appareluea.com/server/cp.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:03.138Z", + "anomali.limo.name": "mal_url: http://nkpotu.xyz/Kpot2/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://appareluea.com/server/cp.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:01.563Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:01.563Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "appareluea.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://appareluea.com/server/cp.php", - "threatintel.indicator.url.original": "http://appareluea.com/server/cp.php", - "threatintel.indicator.url.path": "/server/cp.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://nkpotu.xyz/Kpot2/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:03.138Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -705,32 +754,34 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332396; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--5a563c85-c528-4e33-babe-2dcff34f73c4", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:03.138Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "nkpotu.xyz", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://nkpotu.xyz/Kpot2/login.php", + "threat.indicator.url.original": "http://nkpotu.xyz/Kpot2/login.php", + "threat.indicator.url.path": "/Kpot2/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332363; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--f3e33aab-e2af-4c15-8cb9-f008a37cf986", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:03.138Z", - "threatintel.anomali.name": "mal_url: http://nkpotu.xyz/Kpot2/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:03.396Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://nkpotu.xyz/Kpot2/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:03.138Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:03.138Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "nkpotu.xyz", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://nkpotu.xyz/Kpot2/login.php", - "threatintel.indicator.url.original": "http://nkpotu.xyz/Kpot2/login.php", - "threatintel.indicator.url.path": "/Kpot2/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:03.396Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -747,32 +798,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332363; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f3e33aab-e2af-4c15-8cb9-f008a37cf986", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:03.396Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work5/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332320; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--f03f098d-2fa9-49e1-a7dd-02518aa105fa", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:03.396Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:03.642Z", + "anomali.limo.name": "mal_url: http://mecharnise.ir/ca4/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:03.396Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:03.396Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work5/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work5/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://mecharnise.ir/ca4/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:03.642Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -789,32 +842,34 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332320; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f03f098d-2fa9-49e1-a7dd-02518aa105fa", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:03.642Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "mecharnise.ir", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://mecharnise.ir/ca4/panel/admin.php", + "threat.indicator.url.original": "http://mecharnise.ir/ca4/panel/admin.php", + "threat.indicator.url.path": "/ca4/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332367; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--e72e3ba0-7de5-46bb-ab1e-efdf3e0a0b3b", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:03.642Z", - "threatintel.anomali.name": "mal_url: http://mecharnise.ir/ca4/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:27.534Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://mecharnise.ir/ca4/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:03.642Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:03.642Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "mecharnise.ir", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://mecharnise.ir/ca4/panel/admin.php", - "threatintel.indicator.url.original": "http://mecharnise.ir/ca4/panel/admin.php", - "threatintel.indicator.url.path": "/ca4/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:27.534Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -831,32 +886,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332367; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e72e3ba0-7de5-46bb-ab1e-efdf3e0a0b3b", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:27.534Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work4/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332317; iType: mal_url; State: active; Org: SoftLayer Technologies; Source: CyberCrime", + "anomali.limo.id": "indicator--d6b59b66-5020-4368-85a7-196026856ea9", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:27.534Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:27.591Z", + "anomali.limo.name": "mal_url: http://kironofer.com/webpanel/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:27.534Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:27.534Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work4/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work4/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://kironofer.com/webpanel/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:27.591Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -873,32 +930,34 @@ "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332317; iType: mal_url; State: active; Org: SoftLayer Technologies; Source: CyberCrime", - "threatintel.anomali.id": "indicator--d6b59b66-5020-4368-85a7-196026856ea9", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:27.591Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "kironofer.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://kironofer.com/webpanel/login.php", + "threat.indicator.url.original": "http://kironofer.com/webpanel/login.php", + "threat.indicator.url.path": "/webpanel/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332309; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--aff7b07f-acc7-4bec-ab19-1fce972bfd09", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-78", + "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:27.591Z", - "threatintel.anomali.name": "mal_url: http://kironofer.com/webpanel/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:45.787Z", + "anomali.limo.name": "mal_url: http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://kironofer.com/webpanel/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:27.591Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:27.591Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "kironofer.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://kironofer.com/webpanel/login.php", - "threatintel.indicator.url.original": "http://kironofer.com/webpanel/login.php", - "threatintel.indicator.url.path": "/webpanel/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:45.787Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -915,32 +974,34 @@ "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332309; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--aff7b07f-acc7-4bec-ab19-1fce972bfd09", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:45.787Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "worldatdoor.in", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332286; iType: mal_url; State: active; Org: Garanntor-Hosting; Source: CyberCrime", + "anomali.limo.id": "indicator--ba71ba3a-1efd-40da-ab0d-f4397d6fc337", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-68", + "threatstream-confidence-91", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:45.787Z", - "threatintel.anomali.name": "mal_url: http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:45.841Z", + "anomali.limo.name": "mal_url: http://smartlinktelecom.top/kings/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:45.787Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:45.787Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "worldatdoor.in", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://worldatdoor.in/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/panel2/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://smartlinktelecom.top/kings/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:45.841Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -957,32 +1018,34 @@ "threatstream-confidence-91", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332286; iType: mal_url; State: active; Org: Garanntor-Hosting; Source: CyberCrime", - "threatintel.anomali.id": "indicator--ba71ba3a-1efd-40da-ab0d-f4397d6fc337", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:45.841Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "smartlinktelecom.top", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://smartlinktelecom.top/kings/panel/admin.php", + "threat.indicator.url.original": "http://smartlinktelecom.top/kings/panel/admin.php", + "threat.indicator.url.path": "/kings/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332339; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--17777e7f-3e91-4446-a43d-79139de8a948", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-91", + "threatstream-confidence-64", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:45.841Z", - "threatintel.anomali.name": "mal_url: http://smartlinktelecom.top/kings/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:45.959Z", + "anomali.limo.name": "mal_url: http://carirero.net/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://smartlinktelecom.top/kings/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:45.841Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:45.841Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "smartlinktelecom.top", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://smartlinktelecom.top/kings/panel/admin.php", - "threatintel.indicator.url.original": "http://smartlinktelecom.top/kings/panel/admin.php", - "threatintel.indicator.url.path": "/kings/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://carirero.net/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:45.959Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -999,32 +1062,34 @@ "threatstream-confidence-64", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332339; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--17777e7f-3e91-4446-a43d-79139de8a948", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:45.959Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "carirero.net", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://carirero.net/login.php", + "threat.indicator.url.original": "http://carirero.net/login.php", + "threat.indicator.url.path": "/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332319; iType: mal_ip; State: active; Org: SoftLayer Technologies; Source: CyberCrime", + "anomali.limo.id": "indicator--f6be1804-cfe4-4f41-9338-2b65f5b1dda1", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-64", + "threatstream-confidence-30", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:45.959Z", - "threatintel.anomali.name": "mal_url: http://carirero.net/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:46.025Z", + "anomali.limo.name": "mal_ip: 74.116.84.20", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://carirero.net/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:45.959Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:45.959Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "carirero.net", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://carirero.net/login.php", - "threatintel.indicator.url.original": "http://carirero.net/login.php", - "threatintel.indicator.url.path": "/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '74.116.84.20']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:46.025Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1041,27 +1106,29 @@ "threatstream-confidence-30", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332319; iType: mal_ip; State: active; Org: SoftLayer Technologies; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f6be1804-cfe4-4f41-9338-2b65f5b1dda1", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:46.025Z", + "threat.indicator.ip": "74.116.84.20", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332305; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--b4fd8489-9589-4f70-996c-84989245a21b", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-30", + "threatstream-confidence-43", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:46.025Z", - "threatintel.anomali.name": "mal_ip: 74.116.84.20", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:00:57.729Z", + "anomali.limo.name": "mal_url: http://tuu.nu/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '74.116.84.20']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:46.025Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:46.025Z", - "threatintel.indicator.ip": "74.116.84.20", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://tuu.nu/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:00:57.729Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1078,31 +1145,33 @@ "threatstream-confidence-43", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332305; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b4fd8489-9589-4f70-996c-84989245a21b", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:00:57.729Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "tuu.nu", + "threat.indicator.url.full": "http://tuu.nu/login", + "threat.indicator.url.original": "http://tuu.nu/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332346; iType: mal_url; State: active; Org: Ifx Networks Colombia; Source: CyberCrime", + "anomali.limo.id": "indicator--bc50c62f-a015-4460-87df-2137626877e3", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-43", + "threatstream-confidence-36", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:00:57.729Z", - "threatintel.anomali.name": "mal_url: http://tuu.nu/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:02.696Z", + "anomali.limo.name": "mal_url: http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://tuu.nu/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:00:57.729Z", - "threatintel.indicator.first_seen": "2020-01-22T03:00:57.729Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "tuu.nu", - "threatintel.indicator.url.full": "http://tuu.nu/login", - "threatintel.indicator.url.original": "http://tuu.nu/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:02.696Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1119,32 +1188,34 @@ "threatstream-confidence-36", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332346; iType: mal_url; State: active; Org: Ifx Networks Colombia; Source: CyberCrime", - "threatintel.anomali.id": "indicator--bc50c62f-a015-4460-87df-2137626877e3", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:02.696Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "dulfix.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332323; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--2765af4b-bfb7-4ac8-82d2-ab6ed8a52461", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-36", + "threatstream-confidence-65", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:02.696Z", - "threatintel.anomali.name": "mal_url: http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:02.807Z", + "anomali.limo.name": "mal_url: http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:02.696Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:02.696Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "dulfix.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://dulfix.com/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/cgi-bins/dulfix/gustav57/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:02.807Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1161,32 +1232,34 @@ "threatstream-confidence-65", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332323; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--2765af4b-bfb7-4ac8-82d2-ab6ed8a52461", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:02.807Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "deliciasdvally.com.pe", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/includes/gter/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332399; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--9c0e63a1-c32a-470a-bf09-51488e239c63", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-65", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:02.807Z", - "threatintel.anomali.name": "mal_url: http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:24.810Z", + "anomali.limo.name": "mal_url: http://nkpotu.xyz/Kpot1/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:02.807Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:02.807Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "deliciasdvally.com.pe", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://deliciasdvally.com.pe/includes/gter/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/includes/gter/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://nkpotu.xyz/Kpot1/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:24.81Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1203,32 +1276,34 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332399; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--9c0e63a1-c32a-470a-bf09-51488e239c63", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:24.810Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "nkpotu.xyz", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://nkpotu.xyz/Kpot1/login.php", + "threat.indicator.url.original": "http://nkpotu.xyz/Kpot1/login.php", + "threat.indicator.url.path": "/Kpot1/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332328; iType: mal_ip; State: active; Org: RUCloud; Source: CyberCrime", + "anomali.limo.id": "indicator--8047678e-20be-4116-9bc4-7bb7c26554e0", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:24.810Z", - "threatintel.anomali.name": "mal_url: http://nkpotu.xyz/Kpot1/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:41.158Z", + "anomali.limo.name": "mal_ip: 194.87.147.80", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://nkpotu.xyz/Kpot1/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:24.81Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:24.810Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "nkpotu.xyz", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://nkpotu.xyz/Kpot1/login.php", - "threatintel.indicator.url.original": "http://nkpotu.xyz/Kpot1/login.php", - "threatintel.indicator.url.path": "/Kpot1/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '194.87.147.80']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:41.158Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1245,27 +1320,29 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332328; iType: mal_ip; State: active; Org: RUCloud; Source: CyberCrime", - "threatintel.anomali.id": "indicator--8047678e-20be-4116-9bc4-7bb7c26554e0", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:41.158Z", + "threat.indicator.ip": "194.87.147.80", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332377; iType: mal_url; State: active; Org: A100 ROW GmbH; Source: CyberCrime", + "anomali.limo.id": "indicator--c57a880c-1ce0-45de-9bab-fb2910454a61", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:41.158Z", - "threatintel.anomali.name": "mal_ip: 194.87.147.80", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:57.189Z", + "anomali.limo.name": "mal_url: http://35.158.92.3/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '194.87.147.80']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:41.158Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:41.158Z", - "threatintel.indicator.ip": "194.87.147.80", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://35.158.92.3/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:57.189Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1282,32 +1359,34 @@ "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332377; iType: mal_url; State: active; Org: A100 ROW GmbH; Source: CyberCrime", - "threatintel.anomali.id": "indicator--c57a880c-1ce0-45de-9bab-fb2910454a61", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:57.189Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "35.158.92.3", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://35.158.92.3/panel/admin.php", + "threat.indicator.url.original": "http://35.158.92.3/panel/admin.php", + "threat.indicator.url.path": "/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332101; iType: mal_ip; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--6056152c-0fa5-4e34-871a-3c8990f1ee46", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-85", + "threatstream-confidence-42", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:57.189Z", - "threatintel.anomali.name": "mal_url: http://35.158.92.3/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:01:57.279Z", + "anomali.limo.name": "mal_ip: 45.95.168.70", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://35.158.92.3/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:57.189Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:57.189Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "35.158.92.3", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://35.158.92.3/panel/admin.php", - "threatintel.indicator.url.original": "http://35.158.92.3/panel/admin.php", - "threatintel.indicator.url.path": "/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '45.95.168.70']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:01:57.279Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1324,27 +1403,29 @@ "threatstream-confidence-42", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332101; iType: mal_ip; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--6056152c-0fa5-4e34-871a-3c8990f1ee46", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:01:57.279Z", + "threat.indicator.ip": "45.95.168.70", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55241332357; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--23215acb-4989-4434-ac6d-8f9367734f0f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-42", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:01:57.279Z", - "threatintel.anomali.name": "mal_ip: 45.95.168.70", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:02:50.570Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '45.95.168.70']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:01:57.279Z", - "threatintel.indicator.first_seen": "2020-01-22T03:01:57.279Z", - "threatintel.indicator.ip": "45.95.168.70", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:02:50.57Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1361,32 +1442,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332357; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--23215acb-4989-4434-ac6d-8f9367734f0f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:02:50.570Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work7/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332289; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--452ece92-9ff2-4f99-8a7f-fd614ebea8cf", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-26", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:02:50.570Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:02:52.496Z", + "anomali.limo.name": "mal_url: http://f0391600.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:02:50.57Z", - "threatintel.indicator.first_seen": "2020-01-22T03:02:50.570Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work7/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work7/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0391600.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:02:52.496Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1403,31 +1486,33 @@ "threatstream-confidence-26", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332289; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--452ece92-9ff2-4f99-8a7f-fd614ebea8cf", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:02:52.496Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0391600.xsph.ru", + "threat.indicator.url.full": "http://f0391600.xsph.ru/login", + "threat.indicator.url.original": "http://f0391600.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332334; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--10958d74-ec60-41af-a1ab-1613257e670f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-26", + "threatstream-confidence-94", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:02:52.496Z", - "threatintel.anomali.name": "mal_url: http://f0391600.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:03:42.819Z", + "anomali.limo.name": "mal_url: http://extraclick.space/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0391600.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:02:52.496Z", - "threatintel.indicator.first_seen": "2020-01-22T03:02:52.496Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0391600.xsph.ru", - "threatintel.indicator.url.full": "http://f0391600.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0391600.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://extraclick.space/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:03:42.819Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1444,32 +1529,34 @@ "threatstream-confidence-94", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332334; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--10958d74-ec60-41af-a1ab-1613257e670f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:03:42.819Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "extraclick.space", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://extraclick.space/login.php", + "threat.indicator.url.original": "http://extraclick.space/login.php", + "threat.indicator.url.path": "/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332326; iType: mal_url; State: active; Org: RUCloud; Source: CyberCrime", + "anomali.limo.id": "indicator--19556daa-6293-400d-8706-d0baa6b16b7a", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-94", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:03:42.819Z", - "threatintel.anomali.name": "mal_url: http://extraclick.space/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:03:52.044Z", + "anomali.limo.name": "mal_url: http://petrogarmani.pw/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://extraclick.space/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:03:42.819Z", - "threatintel.indicator.first_seen": "2020-01-22T03:03:42.819Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "extraclick.space", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://extraclick.space/login.php", - "threatintel.indicator.url.original": "http://extraclick.space/login.php", - "threatintel.indicator.url.path": "/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://petrogarmani.pw/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:03:52.044Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1486,32 +1573,34 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332326; iType: mal_url; State: active; Org: RUCloud; Source: CyberCrime", - "threatintel.anomali.id": "indicator--19556daa-6293-400d-8706-d0baa6b16b7a", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:03:52.044Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "petrogarmani.pw", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://petrogarmani.pw/login.php", + "threat.indicator.url.original": "http://petrogarmani.pw/login.php", + "threat.indicator.url.path": "/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332311; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--b09d9be9-6703-4a7d-a066-2baebb6418fc", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:03:52.044Z", - "threatintel.anomali.name": "mal_url: http://petrogarmani.pw/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:04:01.650Z", + "anomali.limo.name": "mal_url: http://worldatdoor.in/mighty/32/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://petrogarmani.pw/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:03:52.044Z", - "threatintel.indicator.first_seen": "2020-01-22T03:03:52.044Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "petrogarmani.pw", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://petrogarmani.pw/login.php", - "threatintel.indicator.url.original": "http://petrogarmani.pw/login.php", - "threatintel.indicator.url.path": "/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://worldatdoor.in/mighty/32/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:04:01.65Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1528,32 +1617,34 @@ "threatstream-confidence-68", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332311; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b09d9be9-6703-4a7d-a066-2baebb6418fc", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:04:01.650Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "worldatdoor.in", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://worldatdoor.in/mighty/32/panel/admin.php", + "threat.indicator.url.original": "http://worldatdoor.in/mighty/32/panel/admin.php", + "threat.indicator.url.path": "/mighty/32/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332341; iType: mal_url; State: active; Org: Institute of Philosophy, Russian Academy of Scienc; Source: CyberCrime", + "anomali.limo.id": "indicator--43febf7d-4185-4a12-a868-e7be690b14aa", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-68", + "threatstream-confidence-92", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:04:01.650Z", - "threatintel.anomali.name": "mal_url: http://worldatdoor.in/mighty/32/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:04:32.717Z", + "anomali.limo.name": "mal_url: http://zanlma.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://worldatdoor.in/mighty/32/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:04:01.65Z", - "threatintel.indicator.first_seen": "2020-01-22T03:04:01.650Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "worldatdoor.in", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://worldatdoor.in/mighty/32/panel/admin.php", - "threatintel.indicator.url.original": "http://worldatdoor.in/mighty/32/panel/admin.php", - "threatintel.indicator.url.path": "/mighty/32/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://zanlma.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:04:32.717Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1570,31 +1661,33 @@ "threatstream-confidence-92", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332341; iType: mal_url; State: active; Org: Institute of Philosophy, Russian Academy of Scienc; Source: CyberCrime", - "threatintel.anomali.id": "indicator--43febf7d-4185-4a12-a868-e7be690b14aa", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:04:32.717Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "zanlma.com", + "threat.indicator.url.full": "http://zanlma.com/login", + "threat.indicator.url.original": "http://zanlma.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332303; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--a34728e6-f91d-47e6-a4d8-a69176299e45", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-92", + "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:04:32.717Z", - "threatintel.anomali.name": "mal_url: http://zanlma.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:04:56.858Z", + "anomali.limo.name": "mal_url: http://f0369688.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://zanlma.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:04:32.717Z", - "threatintel.indicator.first_seen": "2020-01-22T03:04:32.717Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "zanlma.com", - "threatintel.indicator.url.full": "http://zanlma.com/login", - "threatintel.indicator.url.original": "http://zanlma.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0369688.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:04:56.858Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1611,31 +1704,33 @@ "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332303; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--a34728e6-f91d-47e6-a4d8-a69176299e45", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:04:56.858Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0369688.xsph.ru", + "threat.indicator.url.full": "http://f0369688.xsph.ru/login", + "threat.indicator.url.original": "http://f0369688.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55241332380; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--ac821704-5eb2-4f8f-a8b6-2a168dbd0e54", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-84", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:04:56.858Z", - "threatintel.anomali.name": "mal_url: http://f0369688.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-22T03:04:59.245Z", + "anomali.limo.name": "mal_url: http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0369688.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:04:56.858Z", - "threatintel.indicator.first_seen": "2020-01-22T03:04:56.858Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0369688.xsph.ru", - "threatintel.indicator.url.full": "http://f0369688.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0369688.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-22T03:04:59.245Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1652,32 +1747,34 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55241332380; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--ac821704-5eb2-4f8f-a8b6-2a168dbd0e54", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-22T03:04:59.245Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "chol.cc", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Work2/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868747; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--0d3e1bd8-0f16-4c22-b8a1-663ec255ad79", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-57", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-22T03:04:59.245Z", - "threatintel.anomali.name": "mal_url: http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:00:22.287Z", + "anomali.limo.name": "mal_ip: 192.185.214.199", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-22T03:04:59.245Z", - "threatintel.indicator.first_seen": "2020-01-22T03:04:59.245Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "chol.cc", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://chol.cc/Work2/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Work2/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '192.185.214.199']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:00:22.287Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1694,27 +1791,29 @@ "threatstream-confidence-57", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868747; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--0d3e1bd8-0f16-4c22-b8a1-663ec255ad79", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:00:22.287Z", + "threat.indicator.ip": "192.185.214.199", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55245868770; iType: mal_url; State: active; Org: Mills College; Source: CyberCrime", + "anomali.limo.id": "indicator--2cdd130a-c884-402d-b63c-e03f9448f5d9", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-57", + "threatstream-confidence-24", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:00:22.287Z", - "threatintel.anomali.name": "mal_ip: 192.185.214.199", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:01:11.329Z", + "anomali.limo.name": "mal_url: http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '192.185.214.199']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:00:22.287Z", - "threatintel.indicator.first_seen": "2020-01-23T03:00:22.287Z", - "threatintel.indicator.ip": "192.185.214.199", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:01:11.329Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1731,32 +1830,34 @@ "threatstream-confidence-24", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868770; iType: mal_url; State: active; Org: Mills College; Source: CyberCrime", - "threatintel.anomali.id": "indicator--2cdd130a-c884-402d-b63c-e03f9448f5d9", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:01:11.329Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "softtouchcollars.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868769; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--88e98e13-4bfd-4188-941a-f696a7b86b71", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-24", + "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:01:11.329Z", - "threatintel.anomali.name": "mal_url: http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:01:36.682Z", + "anomali.limo.name": "mal_url: http://imobiliariatirol.com/gh/panelnew/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:01:11.329Z", - "threatintel.indicator.first_seen": "2020-01-23T03:01:11.329Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "softtouchcollars.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://softtouchcollars.com/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/Loki/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://imobiliariatirol.com/gh/panelnew/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:01:36.682Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1773,32 +1874,34 @@ "threatstream-confidence-61", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868769; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--88e98e13-4bfd-4188-941a-f696a7b86b71", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:01:36.682Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "imobiliariatirol.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://imobiliariatirol.com/gh/panelnew/admin.php", + "threat.indicator.url.original": "http://imobiliariatirol.com/gh/panelnew/admin.php", + "threat.indicator.url.path": "/gh/panelnew/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868772; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--27323b7d-85d3-4e89-8249-b7696925a772", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-61", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:01:36.682Z", - "threatintel.anomali.name": "mal_url: http://imobiliariatirol.com/gh/panelnew/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:02:15.854Z", + "anomali.limo.name": "mal_url: http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://imobiliariatirol.com/gh/panelnew/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:01:36.682Z", - "threatintel.indicator.first_seen": "2020-01-23T03:01:36.682Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "imobiliariatirol.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://imobiliariatirol.com/gh/panelnew/admin.php", - "threatintel.indicator.url.original": "http://imobiliariatirol.com/gh/panelnew/admin.php", - "threatintel.indicator.url.path": "/gh/panelnew/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:02:15.854Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1815,32 +1918,34 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868772; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--27323b7d-85d3-4e89-8249-b7696925a772", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:02:15.854Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "deliveryexpressworld.xyz", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868766; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--b0639721-de55-48c6-b237-3859d61aecfb", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-62", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:02:15.854Z", - "threatintel.anomali.name": "mal_url: http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:02:47.364Z", + "anomali.limo.name": "mal_url: http://f0392261.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:02:15.854Z", - "threatintel.indicator.first_seen": "2020-01-23T03:02:15.854Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "deliveryexpressworld.xyz", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://deliveryexpressworld.xyz/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0392261.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:02:47.364Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1857,31 +1962,33 @@ "threatstream-confidence-62", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868766; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b0639721-de55-48c6-b237-3859d61aecfb", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:02:47.364Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0392261.xsph.ru", + "threat.indicator.url.full": "http://f0392261.xsph.ru/login", + "threat.indicator.url.original": "http://f0392261.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868749; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", + "anomali.limo.id": "indicator--677e714d-c237-42a1-b6b7-9145acd13eee", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-62", + "threatstream-confidence-80", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:02:47.364Z", - "threatintel.anomali.name": "mal_url: http://f0392261.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:03:05.048Z", + "anomali.limo.name": "mal_url: http://104.168.99.168/panel/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0392261.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:02:47.364Z", - "threatintel.indicator.first_seen": "2020-01-23T03:02:47.364Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0392261.xsph.ru", - "threatintel.indicator.url.full": "http://f0392261.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0392261.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://104.168.99.168/panel/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:03:05.048Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1898,32 +2005,34 @@ "threatstream-confidence-80", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868749; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", - "threatintel.anomali.id": "indicator--677e714d-c237-42a1-b6b7-9145acd13eee", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:03:05.048Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "104.168.99.168", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://104.168.99.168/panel/panel/admin.php", + "threat.indicator.url.original": "http://104.168.99.168/panel/panel/admin.php", + "threat.indicator.url.path": "/panel/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868767; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--5baa1dbd-d74e-408c-92b5-0a9f97e4b87a", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-80", + "threatstream-confidence-69", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:03:05.048Z", - "threatintel.anomali.name": "mal_url: http://104.168.99.168/panel/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:03:15.734Z", + "anomali.limo.name": "mal_url: http://f0387404.xsph.ru/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://104.168.99.168/panel/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:03:05.048Z", - "threatintel.indicator.first_seen": "2020-01-23T03:03:05.048Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "104.168.99.168", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://104.168.99.168/panel/panel/admin.php", - "threatintel.indicator.url.original": "http://104.168.99.168/panel/panel/admin.php", - "threatintel.indicator.url.path": "/panel/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0387404.xsph.ru/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:03:15.734Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1940,32 +2049,34 @@ "threatstream-confidence-69", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868767; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--5baa1dbd-d74e-408c-92b5-0a9f97e4b87a", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:03:15.734Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0387404.xsph.ru", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://f0387404.xsph.ru/panel/admin.php", + "threat.indicator.url.original": "http://f0387404.xsph.ru/panel/admin.php", + "threat.indicator.url.path": "/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55245868768; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--4563241e-5d2f-41a7-adb9-3925a5eeb1b1", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-69", + "threatstream-confidence-72", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:03:15.734Z", - "threatintel.anomali.name": "mal_url: http://f0387404.xsph.ru/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-23T03:03:42.599Z", + "anomali.limo.name": "mal_url: http://a0386457.xsph.ru/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0387404.xsph.ru/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:03:15.734Z", - "threatintel.indicator.first_seen": "2020-01-23T03:03:15.734Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0387404.xsph.ru", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://f0387404.xsph.ru/panel/admin.php", - "threatintel.indicator.url.original": "http://f0387404.xsph.ru/panel/admin.php", - "threatintel.indicator.url.path": "/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://a0386457.xsph.ru/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-23T03:03:42.599Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -1982,32 +2093,34 @@ "threatstream-confidence-72", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55245868768; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--4563241e-5d2f-41a7-adb9-3925a5eeb1b1", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-23T03:03:42.599Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "a0386457.xsph.ru", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://a0386457.xsph.ru/panel/admin.php", + "threat.indicator.url.original": "http://a0386457.xsph.ru/panel/admin.php", + "threat.indicator.url.path": "/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078037; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--70cb5d42-91d3-4efe-8c47-995fc0ac4141", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-72", + "threatstream-confidence-74", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-23T03:03:42.599Z", - "threatintel.anomali.name": "mal_url: http://a0386457.xsph.ru/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:04.821Z", + "anomali.limo.name": "mal_url: http://defenseisrael.com/dis/index.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://a0386457.xsph.ru/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-23T03:03:42.599Z", - "threatintel.indicator.first_seen": "2020-01-23T03:03:42.599Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "a0386457.xsph.ru", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://a0386457.xsph.ru/panel/admin.php", - "threatintel.indicator.url.original": "http://a0386457.xsph.ru/panel/admin.php", - "threatintel.indicator.url.path": "/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://defenseisrael.com/dis/index.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:04.821Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2024,32 +2137,34 @@ "threatstream-confidence-74", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078037; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--70cb5d42-91d3-4efe-8c47-995fc0ac4141", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:04.821Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "defenseisrael.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://defenseisrael.com/dis/index.php", + "threat.indicator.url.original": "http://defenseisrael.com/dis/index.php", + "threat.indicator.url.path": "/dis/index.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078030; iType: mal_ip; State: active; Org: Best-Hoster Group Co. Ltd.; Source: CyberCrime", + "anomali.limo.id": "indicator--3aa712bb-b5d4-4632-bf50-48a4aeeaeb6d", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-74", + "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:04.821Z", - "threatintel.anomali.name": "mal_url: http://defenseisrael.com/dis/index.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:04.857Z", + "anomali.limo.name": "mal_ip: 91.215.170.249", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://defenseisrael.com/dis/index.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:04.821Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:04.821Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "defenseisrael.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://defenseisrael.com/dis/index.php", - "threatintel.indicator.url.original": "http://defenseisrael.com/dis/index.php", - "threatintel.indicator.url.path": "/dis/index.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '91.215.170.249']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:04.857Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2066,27 +2181,29 @@ "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078030; iType: mal_ip; State: active; Org: Best-Hoster Group Co. Ltd.; Source: CyberCrime", - "threatintel.anomali.id": "indicator--3aa712bb-b5d4-4632-bf50-48a4aeeaeb6d", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:04.857Z", + "threat.indicator.ip": "91.215.170.249", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55250078019; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--64227c7d-86ea-4146-a868-3decb5aa5f1d", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-83", + "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:04.857Z", - "threatintel.anomali.name": "mal_ip: 91.215.170.249", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:04.883Z", + "anomali.limo.name": "mal_url: http://lbfb3f03.justinstalledpanel.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '91.215.170.249']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:04.857Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:04.857Z", - "threatintel.indicator.ip": "91.215.170.249", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://lbfb3f03.justinstalledpanel.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:04.883Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2103,31 +2220,33 @@ "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078019; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--64227c7d-86ea-4146-a868-3decb5aa5f1d", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:04.883Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "lbfb3f03.justinstalledpanel.com", + "threat.indicator.url.full": "http://lbfb3f03.justinstalledpanel.com/login", + "threat.indicator.url.original": "http://lbfb3f03.justinstalledpanel.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078035; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--37fcf9a7-1a90-4d81-be0a-e824a4fa938e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-79", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:04.883Z", - "threatintel.anomali.name": "mal_url: http://lbfb3f03.justinstalledpanel.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:12.997Z", + "anomali.limo.name": "mal_url: http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://lbfb3f03.justinstalledpanel.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:04.883Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:04.883Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "lbfb3f03.justinstalledpanel.com", - "threatintel.indicator.url.full": "http://lbfb3f03.justinstalledpanel.com/login", - "threatintel.indicator.url.original": "http://lbfb3f03.justinstalledpanel.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:12.997Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2144,32 +2263,34 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078035; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--37fcf9a7-1a90-4d81-be0a-e824a4fa938e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:12.997Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "byedtronchgroup.yt", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078008; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--5a38786f-107e-4060-a7c9-ea8a5ded6aac", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:12.997Z", - "threatintel.anomali.name": "mal_url: http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:13.025Z", + "anomali.limo.name": "mal_url: http://199.192.28.11/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:12.997Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:12.997Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "byedtronchgroup.yt", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://byedtronchgroup.yt/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/jik/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://199.192.28.11/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:13.025Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2186,32 +2307,34 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078008; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--5a38786f-107e-4060-a7c9-ea8a5ded6aac", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:13.025Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "199.192.28.11", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://199.192.28.11/panel/admin.php", + "threat.indicator.url.original": "http://199.192.28.11/panel/admin.php", + "threat.indicator.url.path": "/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078038; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--3eb79b31-1d6d-438c-a848-24a3407f6e32", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:13.025Z", - "threatintel.anomali.name": "mal_url: http://199.192.28.11/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:32.901Z", + "anomali.limo.name": "mal_url: http://217.8.117.51/aW8bVds1/login.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://199.192.28.11/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:13.025Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:13.025Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "199.192.28.11", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://199.192.28.11/panel/admin.php", - "threatintel.indicator.url.original": "http://199.192.28.11/panel/admin.php", - "threatintel.indicator.url.path": "/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://217.8.117.51/aW8bVds1/login.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:32.901Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2228,32 +2351,34 @@ "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078038; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--3eb79b31-1d6d-438c-a848-24a3407f6e32", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:32.901Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "217.8.117.51", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://217.8.117.51/aW8bVds1/login.php", + "threat.indicator.url.original": "http://217.8.117.51/aW8bVds1/login.php", + "threat.indicator.url.path": "/aW8bVds1/login.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078026; iType: mal_url; State: active; Org: IT DeLuxe Ltd.; Source: CyberCrime", + "anomali.limo.id": "indicator--a050832c-db6e-49a0-8470-7a3cd8f17178", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-82", + "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:32.901Z", - "threatintel.anomali.name": "mal_url: http://217.8.117.51/aW8bVds1/login.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:32.929Z", + "anomali.limo.name": "mal_url: http://lansome.site/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://217.8.117.51/aW8bVds1/login.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:32.901Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:32.901Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "217.8.117.51", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://217.8.117.51/aW8bVds1/login.php", - "threatintel.indicator.url.original": "http://217.8.117.51/aW8bVds1/login.php", - "threatintel.indicator.url.path": "/aW8bVds1/login.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://lansome.site/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:32.929Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2270,31 +2395,33 @@ "threatstream-confidence-93", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078026; iType: mal_url; State: active; Org: IT DeLuxe Ltd.; Source: CyberCrime", - "threatintel.anomali.id": "indicator--a050832c-db6e-49a0-8470-7a3cd8f17178", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:32.929Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "lansome.site", + "threat.indicator.url.full": "http://lansome.site/login", + "threat.indicator.url.original": "http://lansome.site/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078034; iType: mal_url; State: active; Org: Branch of BachKim Network solutions jsc; Source: CyberCrime", + "anomali.limo.id": "indicator--e88008f4-76fc-428d-831a-4b389e48b712", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-93", + "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:32.929Z", - "threatintel.anomali.name": "mal_url: http://lansome.site/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:57:49.028Z", + "anomali.limo.name": "mal_url: http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://lansome.site/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:32.929Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:32.929Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "lansome.site", - "threatintel.indicator.url.full": "http://lansome.site/login", - "threatintel.indicator.url.original": "http://lansome.site/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:57:49.028Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2311,32 +2438,34 @@ "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078034; iType: mal_url; State: active; Org: Branch of BachKim Network solutions jsc; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e88008f4-76fc-428d-831a-4b389e48b712", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:57:49.028Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "iplusvietnam.com.vn", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078032; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", + "anomali.limo.id": "indicator--dafe91cf-787c-471c-9afe-f7bb20a1b93f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-83", + "threatstream-confidence-94", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:57:49.028Z", - "threatintel.anomali.name": "mal_url: http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:03.345Z", + "anomali.limo.name": "mal_url: http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:57:49.028Z", - "threatintel.indicator.first_seen": "2020-01-24T02:57:49.028Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "iplusvietnam.com.vn", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://iplusvietnam.com.vn/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/jo/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:03.345Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2353,32 +2482,34 @@ "threatstream-confidence-94", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078032; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", - "threatintel.anomali.id": "indicator--dafe91cf-787c-471c-9afe-f7bb20a1b93f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:03.345Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "leakaryadeen.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/parl/id345/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078031; iType: mal_url; State: active; Org: IT House, Ltd; Source: CyberCrime", + "anomali.limo.id": "indicator--232bdc34-44cb-4f41-af52-f6f1cd28818e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-94", + "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:03.345Z", - "threatintel.anomali.name": "mal_url: http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:16.318Z", + "anomali.limo.name": "mal_url: http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:03.345Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:03.345Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "leakaryadeen.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://leakaryadeen.com/parl/id345/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/parl/id345/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:16.318Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2395,32 +2526,34 @@ "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078031; iType: mal_url; State: active; Org: IT House, Ltd; Source: CyberCrime", - "threatintel.anomali.id": "indicator--232bdc34-44cb-4f41-af52-f6f1cd28818e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:16.318Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "oaa-my.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/clap/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078027; iType: mal_url; State: active; Org: Branch of BachKim Network solutions jsc; Source: CyberCrime", + "anomali.limo.id": "indicator--4adabe80-3be4-401a-948a-f9724c872374", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-81", + "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:16.318Z", - "threatintel.anomali.name": "mal_url: http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:16.358Z", + "anomali.limo.name": "mal_url: http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:16.318Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:16.318Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "oaa-my.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://oaa-my.com/clap/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/clap/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:16.358Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2437,32 +2570,34 @@ "threatstream-confidence-66", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078027; iType: mal_url; State: active; Org: Branch of BachKim Network solutions jsc; Source: CyberCrime", - "threatintel.anomali.id": "indicator--4adabe80-3be4-401a-948a-f9724c872374", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:16.358Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "thaubenuocngam.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078013; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--1d7051c0-a42b-4801-bd7f-f0abf2cc125c", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-66", + "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:16.358Z", - "threatintel.anomali.name": "mal_url: http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:32.126Z", + "anomali.limo.name": "mal_url: http://suspiciousactivity.xyz/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:16.358Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:16.358Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "thaubenuocngam.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://thaubenuocngam.com/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/go/playbook/onelove/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://suspiciousactivity.xyz/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:32.126Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2479,31 +2614,33 @@ "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078013; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--1d7051c0-a42b-4801-bd7f-f0abf2cc125c", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:32.126Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "suspiciousactivity.xyz", + "threat.indicator.url.full": "http://suspiciousactivity.xyz/login", + "threat.indicator.url.original": "http://suspiciousactivity.xyz/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078017; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--fb06856c-8aad-4fae-92fc-b73aae4f6dc7", + "anomali.limo.labels": [ "malicious-activity", "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:32.126Z", - "threatintel.anomali.name": "mal_url: http://suspiciousactivity.xyz/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:37.603Z", + "anomali.limo.name": "mal_url: http://217.8.117.8/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://suspiciousactivity.xyz/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:32.126Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:32.126Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "suspiciousactivity.xyz", - "threatintel.indicator.url.full": "http://suspiciousactivity.xyz/login", - "threatintel.indicator.url.original": "http://suspiciousactivity.xyz/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://217.8.117.8/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:37.603Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2520,31 +2657,33 @@ "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078017; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--fb06856c-8aad-4fae-92fc-b73aae4f6dc7", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:37.603Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "217.8.117.8", + "threat.indicator.url.full": "http://217.8.117.8/login", + "threat.indicator.url.original": "http://217.8.117.8/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078012; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--33e674f5-a64a-48f4-9d8c-248348356135", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-82", + "threatstream-confidence-71", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:37.603Z", - "threatintel.anomali.name": "mal_url: http://217.8.117.8/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:37.643Z", + "anomali.limo.name": "mal_url: http://f0387550.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://217.8.117.8/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:37.603Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:37.603Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "217.8.117.8", - "threatintel.indicator.url.full": "http://217.8.117.8/login", - "threatintel.indicator.url.original": "http://217.8.117.8/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0387550.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:37.643Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2561,31 +2700,33 @@ "threatstream-confidence-71", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078012; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--33e674f5-a64a-48f4-9d8c-248348356135", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:37.643Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0387550.xsph.ru", + "threat.indicator.url.full": "http://f0387550.xsph.ru/login", + "threat.indicator.url.original": "http://f0387550.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078018; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--6311f539-1d5d-423f-a238-d0c1dc167432", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-71", + "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:37.643Z", - "threatintel.anomali.name": "mal_url: http://f0387550.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:58:39.465Z", + "anomali.limo.name": "mal_url: http://lf4e4abf.justinstalledpanel.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0387550.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:37.643Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:37.643Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0387550.xsph.ru", - "threatintel.indicator.url.full": "http://f0387550.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0387550.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://lf4e4abf.justinstalledpanel.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:58:39.465Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2602,31 +2743,33 @@ "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078018; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--6311f539-1d5d-423f-a238-d0c1dc167432", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:58:39.465Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "lf4e4abf.justinstalledpanel.com", + "threat.indicator.url.full": "http://lf4e4abf.justinstalledpanel.com/login", + "threat.indicator.url.original": "http://lf4e4abf.justinstalledpanel.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078033; iType: mal_ip; State: active; Org: ColoCrossing; Source: CyberCrime", + "anomali.limo.id": "indicator--1c91f219-cfa6-44c7-a5ee-1c760489b43c", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-84", + "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:58:39.465Z", - "threatintel.anomali.name": "mal_url: http://lf4e4abf.justinstalledpanel.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:02.031Z", + "anomali.limo.name": "mal_ip: 206.217.131.245", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://lf4e4abf.justinstalledpanel.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:58:39.465Z", - "threatintel.indicator.first_seen": "2020-01-24T02:58:39.465Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "lf4e4abf.justinstalledpanel.com", - "threatintel.indicator.url.full": "http://lf4e4abf.justinstalledpanel.com/login", - "threatintel.indicator.url.original": "http://lf4e4abf.justinstalledpanel.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '206.217.131.245']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:02.031Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2643,27 +2786,29 @@ "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078033; iType: mal_ip; State: active; Org: ColoCrossing; Source: CyberCrime", - "threatintel.anomali.id": "indicator--1c91f219-cfa6-44c7-a5ee-1c760489b43c", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:02.031Z", + "threat.indicator.ip": "206.217.131.245", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55250078010; iType: mal_url; State: active; Org: QuadraNet; Source: CyberCrime", + "anomali.limo.id": "indicator--c58983e2-18fd-47b8-aab4-6c8a2e2dcb35", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-81", + "threatstream-confidence-52", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:02.031Z", - "threatintel.anomali.name": "mal_ip: 206.217.131.245", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:15.878Z", + "anomali.limo.name": "mal_url: http://67.215.224.101/a1/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '206.217.131.245']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:02.031Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:02.031Z", - "threatintel.indicator.ip": "206.217.131.245", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://67.215.224.101/a1/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:15.878Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2680,32 +2825,34 @@ "threatstream-confidence-52", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078010; iType: mal_url; State: active; Org: QuadraNet; Source: CyberCrime", - "threatintel.anomali.id": "indicator--c58983e2-18fd-47b8-aab4-6c8a2e2dcb35", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:15.878Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "67.215.224.101", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://67.215.224.101/a1/panel/admin.php", + "threat.indicator.url.original": "http://67.215.224.101/a1/panel/admin.php", + "threat.indicator.url.path": "/a1/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078000; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--1ab178a8-7991-4879-b9aa-8da49f40e92e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-52", + "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:15.878Z", - "threatintel.anomali.name": "mal_url: http://67.215.224.101/a1/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:29.155Z", + "anomali.limo.name": "mal_ip: 162.241.73.163", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://67.215.224.101/a1/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:15.878Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:15.878Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "67.215.224.101", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://67.215.224.101/a1/panel/admin.php", - "threatintel.indicator.url.original": "http://67.215.224.101/a1/panel/admin.php", - "threatintel.indicator.url.path": "/a1/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '162.241.73.163']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:29.155Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2722,27 +2869,29 @@ "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078000; iType: mal_ip; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--1ab178a8-7991-4879-b9aa-8da49f40e92e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:29.155Z", + "threat.indicator.ip": "162.241.73.163", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55250078020; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--d5bdff38-6939-4a47-8e11-b910520565c4", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-58", + "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:29.155Z", - "threatintel.anomali.name": "mal_ip: 162.241.73.163", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:50.233Z", + "anomali.limo.name": "mal_url: http://l60bdd58.justinstalledpanel.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '162.241.73.163']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:29.155Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:29.155Z", - "threatintel.indicator.ip": "162.241.73.163", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://l60bdd58.justinstalledpanel.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:50.233Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2759,31 +2908,33 @@ "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078020; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--d5bdff38-6939-4a47-8e11-b910520565c4", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:50.233Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "l60bdd58.justinstalledpanel.com", + "threat.indicator.url.full": "http://l60bdd58.justinstalledpanel.com/login", + "threat.indicator.url.original": "http://l60bdd58.justinstalledpanel.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078009; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", + "anomali.limo.id": "indicator--1be74977-5aa6-4175-99dd-32b54863a06b", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-78", + "threatstream-confidence-25", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:50.233Z", - "threatintel.anomali.name": "mal_url: http://l60bdd58.justinstalledpanel.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:50.255Z", + "anomali.limo.name": "mal_url: http://107.175.150.73/~giftioz/.azma/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://l60bdd58.justinstalledpanel.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:50.233Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:50.233Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "l60bdd58.justinstalledpanel.com", - "threatintel.indicator.url.full": "http://l60bdd58.justinstalledpanel.com/login", - "threatintel.indicator.url.original": "http://l60bdd58.justinstalledpanel.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://107.175.150.73/~giftioz/.azma/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:50.255Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2800,32 +2951,34 @@ "threatstream-confidence-25", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078009; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", - "threatintel.anomali.id": "indicator--1be74977-5aa6-4175-99dd-32b54863a06b", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:50.255Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "107.175.150.73", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://107.175.150.73/~giftioz/.azma/panel/admin.php", + "threat.indicator.url.original": "http://107.175.150.73/~giftioz/.azma/panel/admin.php", + "threat.indicator.url.path": "/~giftioz/.azma/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078023; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--eacc25ce-584c-4b40-98ab-7935dabd5cb1", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-25", + "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:50.255Z", - "threatintel.anomali.name": "mal_url: http://107.175.150.73/~giftioz/.azma/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:52.536Z", + "anomali.limo.name": "mal_url: http://5.188.60.52/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://107.175.150.73/~giftioz/.azma/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:50.255Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:50.255Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "107.175.150.73", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://107.175.150.73/~giftioz/.azma/panel/admin.php", - "threatintel.indicator.url.original": "http://107.175.150.73/~giftioz/.azma/panel/admin.php", - "threatintel.indicator.url.path": "/~giftioz/.azma/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://5.188.60.52/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:52.536Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2842,31 +2995,33 @@ "threatstream-confidence-78", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078023; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--eacc25ce-584c-4b40-98ab-7935dabd5cb1", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:52.536Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "5.188.60.52", + "threat.indicator.url.full": "http://5.188.60.52/login", + "threat.indicator.url.original": "http://5.188.60.52/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078025; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", + "anomali.limo.id": "indicator--504f4011-eaea-4921-aad5-f102bef7c798", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-78", + "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:52.536Z", - "threatintel.anomali.name": "mal_url: http://5.188.60.52/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:54.784Z", + "anomali.limo.name": "mal_url: http://trotdeiman.ga/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://5.188.60.52/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:52.536Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:52.536Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "5.188.60.52", - "threatintel.indicator.url.full": "http://5.188.60.52/login", - "threatintel.indicator.url.original": "http://5.188.60.52/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://trotdeiman.ga/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:54.784Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2883,31 +3038,33 @@ "threatstream-confidence-85", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078025; iType: mal_url; State: active; Org: Cloudflare; Source: CyberCrime", - "threatintel.anomali.id": "indicator--504f4011-eaea-4921-aad5-f102bef7c798", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:54.784Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "trotdeiman.ga", + "threat.indicator.url.full": "http://trotdeiman.ga/login", + "threat.indicator.url.original": "http://trotdeiman.ga/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078014; iType: mal_ip; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--e3ffb953-6c59-461a-8242-0d26c2b5c358", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-85", + "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:54.784Z", - "threatintel.anomali.name": "mal_url: http://trotdeiman.ga/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T02:59:54.815Z", + "anomali.limo.name": "mal_ip: 217.8.117.8", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://trotdeiman.ga/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:54.784Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:54.784Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "trotdeiman.ga", - "threatintel.indicator.url.full": "http://trotdeiman.ga/login", - "threatintel.indicator.url.original": "http://trotdeiman.ga/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '217.8.117.8']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T02:59:54.815Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2924,27 +3081,29 @@ "threatstream-confidence-82", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078014; iType: mal_ip; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e3ffb953-6c59-461a-8242-0d26c2b5c358", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T02:59:54.815Z", + "threat.indicator.ip": "217.8.117.8", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55250078036; iType: mal_ip; State: active; Org: Global Frag Networks; Source: CyberCrime", + "anomali.limo.id": "indicator--3a47ad46-930d-4ced-b0e7-dc9d0776153e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-82", + "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T02:59:54.815Z", - "threatintel.anomali.name": "mal_ip: 217.8.117.8", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:01.726Z", + "anomali.limo.name": "mal_ip: 104.223.170.113", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '217.8.117.8']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T02:59:54.815Z", - "threatintel.indicator.first_seen": "2020-01-24T02:59:54.815Z", - "threatintel.indicator.ip": "217.8.117.8", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '104.223.170.113']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:01.726Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2961,27 +3120,29 @@ "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078036; iType: mal_ip; State: active; Org: Global Frag Networks; Source: CyberCrime", - "threatintel.anomali.id": "indicator--3a47ad46-930d-4ced-b0e7-dc9d0776153e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:01.726Z", + "threat.indicator.ip": "104.223.170.113", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55250078011; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--0e10924c-745c-4a58-8e27-ab3a6bacd666", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-83", + "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:01.726Z", - "threatintel.anomali.name": "mal_ip: 104.223.170.113", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:01.762Z", + "anomali.limo.name": "mal_url: http://tavim.org/includes/firmino/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '104.223.170.113']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:01.726Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:01.726Z", - "threatintel.indicator.ip": "104.223.170.113", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://tavim.org/includes/firmino/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:01.762Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -2998,32 +3159,34 @@ "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078011; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--0e10924c-745c-4a58-8e27-ab3a6bacd666", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:01.762Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "tavim.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://tavim.org/includes/firmino/admin.php", + "threat.indicator.url.original": "http://tavim.org/includes/firmino/admin.php", + "threat.indicator.url.path": "/includes/firmino/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078015; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--c3fb816a-cc3b-4442-be4d-d62113ae5168", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-58", + "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:01.762Z", - "threatintel.anomali.name": "mal_url: http://tavim.org/includes/firmino/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:10.928Z", + "anomali.limo.name": "mal_url: http://onlinesecuritycenter.xyz/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://tavim.org/includes/firmino/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:01.762Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:01.762Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "tavim.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://tavim.org/includes/firmino/admin.php", - "threatintel.indicator.url.original": "http://tavim.org/includes/firmino/admin.php", - "threatintel.indicator.url.path": "/includes/firmino/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://onlinesecuritycenter.xyz/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:10.928Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3040,31 +3203,33 @@ "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078015; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--c3fb816a-cc3b-4442-be4d-d62113ae5168", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:10.928Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "onlinesecuritycenter.xyz", + "threat.indicator.url.full": "http://onlinesecuritycenter.xyz/login", + "threat.indicator.url.original": "http://onlinesecuritycenter.xyz/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078029; iType: mal_url; State: active; Org: IT House, Ltd; Source: CyberCrime", + "anomali.limo.id": "indicator--9159e46d-f3a4-464b-ac68-8beaf87e1a8f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-84", + "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:10.928Z", - "threatintel.anomali.name": "mal_url: http://onlinesecuritycenter.xyz/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:20.166Z", + "anomali.limo.name": "mal_url: http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://onlinesecuritycenter.xyz/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:10.928Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:10.928Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "onlinesecuritycenter.xyz", - "threatintel.indicator.url.full": "http://onlinesecuritycenter.xyz/login", - "threatintel.indicator.url.original": "http://onlinesecuritycenter.xyz/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:20.166Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3081,32 +3246,34 @@ "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078029; iType: mal_url; State: active; Org: IT House, Ltd; Source: CyberCrime", - "threatintel.anomali.id": "indicator--9159e46d-f3a4-464b-ac68-8beaf87e1a8f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:20.166Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "oaa-my.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/cutter/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078016; iType: mal_url; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--fefa8e76-ae0f-41ab-84e7-ea43ab055573", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-81", + "threatstream-confidence-90", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:20.166Z", - "threatintel.anomali.name": "mal_url: http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:24.048Z", + "anomali.limo.name": "mal_url: http://jumbajumbadun.fun/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:20.166Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:20.166Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "oaa-my.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://oaa-my.com/cutter/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/cutter/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://jumbajumbadun.fun/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:24.048Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3123,31 +3290,33 @@ "threatstream-confidence-90", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078016; iType: mal_url; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--fefa8e76-ae0f-41ab-84e7-ea43ab055573", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:24.048Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "jumbajumbadun.fun", + "threat.indicator.url.full": "http://jumbajumbadun.fun/login", + "threat.indicator.url.original": "http://jumbajumbadun.fun/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078024; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", + "anomali.limo.id": "indicator--6a76fa89-4d5f-40d0-9b03-671bdb2d5b4b", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-90", + "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:24.048Z", - "threatintel.anomali.name": "mal_url: http://jumbajumbadun.fun/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:00:55.816Z", + "anomali.limo.name": "mal_url: http://tavim.org/includes/salah/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://jumbajumbadun.fun/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:24.048Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:24.048Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "jumbajumbadun.fun", - "threatintel.indicator.url.full": "http://jumbajumbadun.fun/login", - "threatintel.indicator.url.original": "http://jumbajumbadun.fun/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://tavim.org/includes/salah/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:00:55.816Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3164,32 +3333,34 @@ "threatstream-confidence-58", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078024; iType: mal_url; State: active; Org: CyrusOne LLC; Source: CyberCrime", - "threatintel.anomali.id": "indicator--6a76fa89-4d5f-40d0-9b03-671bdb2d5b4b", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:00:55.816Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "tavim.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://tavim.org/includes/salah/admin.php", + "threat.indicator.url.original": "http://tavim.org/includes/salah/admin.php", + "threat.indicator.url.path": "/includes/salah/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078022; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--21055dfd-d0cb-42ec-93bd-ffaeadd11d80", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-58", + "threatstream-confidence-80", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:00:55.816Z", - "threatintel.anomali.name": "mal_url: http://tavim.org/includes/salah/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:01:10.501Z", + "anomali.limo.name": "mal_url: http://l0c23205.justinstalledpanel.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://tavim.org/includes/salah/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:00:55.816Z", - "threatintel.indicator.first_seen": "2020-01-24T03:00:55.816Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "tavim.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://tavim.org/includes/salah/admin.php", - "threatintel.indicator.url.original": "http://tavim.org/includes/salah/admin.php", - "threatintel.indicator.url.path": "/includes/salah/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://l0c23205.justinstalledpanel.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:01:10.501Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3206,31 +3377,33 @@ "threatstream-confidence-80", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078022; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--21055dfd-d0cb-42ec-93bd-ffaeadd11d80", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:01:10.501Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "l0c23205.justinstalledpanel.com", + "threat.indicator.url.full": "http://l0c23205.justinstalledpanel.com/login", + "threat.indicator.url.original": "http://l0c23205.justinstalledpanel.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078021; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", + "anomali.limo.id": "indicator--7471a595-e8b0-4c41-be4c-0a3e55675630", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-80", + "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:01:10.501Z", - "threatintel.anomali.name": "mal_url: http://l0c23205.justinstalledpanel.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:01:10.518Z", + "anomali.limo.name": "mal_url: http://l535e9e5.justinstalledpanel.com/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://l0c23205.justinstalledpanel.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:01:10.501Z", - "threatintel.indicator.first_seen": "2020-01-24T03:01:10.501Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "l0c23205.justinstalledpanel.com", - "threatintel.indicator.url.full": "http://l0c23205.justinstalledpanel.com/login", - "threatintel.indicator.url.original": "http://l0c23205.justinstalledpanel.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://l535e9e5.justinstalledpanel.com/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:01:10.518Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3247,31 +3420,33 @@ "threatstream-confidence-83", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078021; iType: mal_url; State: active; Org: MoreneHost; Source: CyberCrime", - "threatintel.anomali.id": "indicator--7471a595-e8b0-4c41-be4c-0a3e55675630", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:01:10.518Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "l535e9e5.justinstalledpanel.com", + "threat.indicator.url.full": "http://l535e9e5.justinstalledpanel.com/login", + "threat.indicator.url.original": "http://l535e9e5.justinstalledpanel.com/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55250078007; iType: mal_ip; State: active; Source: CyberCrime", + "anomali.limo.id": "indicator--ead1e7e5-fdb3-47c2-9476-aa82741c038e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-83", + "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:01:10.518Z", - "threatintel.anomali.name": "mal_url: http://l535e9e5.justinstalledpanel.com/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-24T03:01:14.843Z", + "anomali.limo.name": "mal_ip: 217.8.117.47", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://l535e9e5.justinstalledpanel.com/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:01:10.518Z", - "threatintel.indicator.first_seen": "2020-01-24T03:01:10.518Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "l535e9e5.justinstalledpanel.com", - "threatintel.indicator.url.full": "http://l535e9e5.justinstalledpanel.com/login", - "threatintel.indicator.url.original": "http://l535e9e5.justinstalledpanel.com/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '217.8.117.47']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-24T03:01:14.843Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3288,27 +3463,29 @@ "threatstream-confidence-76", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55250078007; iType: mal_ip; State: active; Source: CyberCrime", - "threatintel.anomali.id": "indicator--ead1e7e5-fdb3-47c2-9476-aa82741c038e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-24T03:01:14.843Z", + "threat.indicator.ip": "217.8.117.47", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55253484365; iType: mal_url; State: active; Org: Petersburg Internet Network ltd.; Source: CyberCrime", + "anomali.limo.id": "indicator--b0aee6bf-32f4-4f65-8de6-f65e04e92b15", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-76", + "threatstream-confidence-67", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-24T03:01:14.843Z", - "threatintel.anomali.name": "mal_ip: 217.8.117.47", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:12.699Z", + "anomali.limo.name": "mal_url: http://46.161.27.57/northon/", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '217.8.117.47']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-24T03:01:14.843Z", - "threatintel.indicator.first_seen": "2020-01-24T03:01:14.843Z", - "threatintel.indicator.ip": "217.8.117.47", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://46.161.27.57/northon/']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:12.699Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3325,31 +3502,33 @@ "threatstream-confidence-67", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484365; iType: mal_url; State: active; Org: Petersburg Internet Network ltd.; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b0aee6bf-32f4-4f65-8de6-f65e04e92b15", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:12.699Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "46.161.27.57", + "threat.indicator.url.full": "http://46.161.27.57/northon/", + "threat.indicator.url.original": "http://46.161.27.57/northon/", + "threat.indicator.url.path": "/northon/", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484350; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", + "anomali.limo.id": "indicator--54afbceb-72f3-484e-aee4-904f77beeff6", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-67", + "threatstream-confidence-90", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:12.699Z", - "threatintel.anomali.name": "mal_url: http://46.161.27.57/northon/", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:28.034Z", + "anomali.limo.name": "mal_url: http://104.168.99.170/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://46.161.27.57/northon/']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:12.699Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:12.699Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "46.161.27.57", - "threatintel.indicator.url.full": "http://46.161.27.57/northon/", - "threatintel.indicator.url.original": "http://46.161.27.57/northon/", - "threatintel.indicator.url.path": "/northon/", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://104.168.99.170/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:28.034Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3366,31 +3545,33 @@ "threatstream-confidence-90", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484350; iType: mal_url; State: active; Org: ColoCrossing; Source: CyberCrime", - "threatintel.anomali.id": "indicator--54afbceb-72f3-484e-aee4-904f77beeff6", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:28.034Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "104.168.99.170", + "threat.indicator.url.full": "http://104.168.99.170/login", + "threat.indicator.url.original": "http://104.168.99.170/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484356; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--da030e10-af9f-462d-bda8-33abb223e950", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-90", + "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:28.034Z", - "threatintel.anomali.name": "mal_url: http://104.168.99.170/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:38.187Z", + "anomali.limo.name": "mal_url: http://officelog.org/inc/js/jstree/scan/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://104.168.99.170/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:28.034Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:28.034Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "104.168.99.170", - "threatintel.indicator.url.full": "http://104.168.99.170/login", - "threatintel.indicator.url.original": "http://104.168.99.170/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/scan/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:38.187Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3407,32 +3588,34 @@ "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484356; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--da030e10-af9f-462d-bda8-33abb223e950", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:38.187Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "officelog.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://officelog.org/inc/js/jstree/scan/panel/admin.php", + "threat.indicator.url.original": "http://officelog.org/inc/js/jstree/scan/panel/admin.php", + "threat.indicator.url.path": "/inc/js/jstree/scan/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484343; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--d38e051a-bc5b-4723-884a-65e017d98299", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-89", + "threatstream-confidence-65", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:38.187Z", - "threatintel.anomali.name": "mal_url: http://officelog.org/inc/js/jstree/scan/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:38.214Z", + "anomali.limo.name": "mal_url: http://f0391587.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/scan/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:38.187Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:38.187Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "officelog.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://officelog.org/inc/js/jstree/scan/panel/admin.php", - "threatintel.indicator.url.original": "http://officelog.org/inc/js/jstree/scan/panel/admin.php", - "threatintel.indicator.url.path": "/inc/js/jstree/scan/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0391587.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:38.214Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3449,31 +3632,33 @@ "threatstream-confidence-65", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484343; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--d38e051a-bc5b-4723-884a-65e017d98299", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:38.214Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0391587.xsph.ru", + "threat.indicator.url.full": "http://f0391587.xsph.ru/login", + "threat.indicator.url.original": "http://f0391587.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484367; iType: mal_url; State: active; Org: Petersburg Internet Network ltd.; Source: CyberCrime", + "anomali.limo.id": "indicator--46491826-6ba1-4217-a35e-1eb0081a9e6a", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-65", + "threatstream-confidence-67", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:38.214Z", - "threatintel.anomali.name": "mal_url: http://f0391587.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:47.281Z", + "anomali.limo.name": "mal_url: http://46.161.27.57:8080/northon/", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0391587.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:38.214Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:38.214Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0391587.xsph.ru", - "threatintel.indicator.url.full": "http://f0391587.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0391587.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://46.161.27.57:8080/northon/']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:47.281Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3490,32 +3675,34 @@ "threatstream-confidence-67", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484367; iType: mal_url; State: active; Org: Petersburg Internet Network ltd.; Source: CyberCrime", - "threatintel.anomali.id": "indicator--46491826-6ba1-4217-a35e-1eb0081a9e6a", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:47.281Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "46.161.27.57", + "threat.indicator.url.full": "http://46.161.27.57:8080/northon/", + "threat.indicator.url.original": "http://46.161.27.57:8080/northon/", + "threat.indicator.url.path": "/northon/", + "threat.indicator.url.port": 8080, + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484342; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", + "anomali.limo.id": "indicator--b9715fd5-b89a-4859-b19f-55e052709227", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-67", + "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:47.281Z", - "threatintel.anomali.name": "mal_url: http://46.161.27.57:8080/northon/", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:51.296Z", + "anomali.limo.name": "mal_url: http://f0393086.xsph.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://46.161.27.57:8080/northon/']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:47.281Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:47.281Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "46.161.27.57", - "threatintel.indicator.url.full": "http://46.161.27.57:8080/northon/", - "threatintel.indicator.url.original": "http://46.161.27.57:8080/northon/", - "threatintel.indicator.url.path": "/northon/", - "threatintel.indicator.url.port": 8080, - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://f0393086.xsph.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:51.296Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3532,31 +3719,33 @@ "threatstream-confidence-79", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484342; iType: mal_url; State: active; Org: SPRINTHOST.RU - shared/premium hosting, VDS, dedic; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b9715fd5-b89a-4859-b19f-55e052709227", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:51.296Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "f0393086.xsph.ru", + "threat.indicator.url.full": "http://f0393086.xsph.ru/login", + "threat.indicator.url.original": "http://f0393086.xsph.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484363; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--e3177515-f481-46c8-bad8-582ba0858ef3", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-79", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:51.296Z", - "threatintel.anomali.name": "mal_url: http://f0393086.xsph.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:56.007Z", + "anomali.limo.name": "mal_url: http://insuncos.com/files1/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://f0393086.xsph.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:51.296Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:51.296Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "f0393086.xsph.ru", - "threatintel.indicator.url.full": "http://f0393086.xsph.ru/login", - "threatintel.indicator.url.original": "http://f0393086.xsph.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://insuncos.com/files1/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:56.007Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3573,32 +3762,34 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484363; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--e3177515-f481-46c8-bad8-582ba0858ef3", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:56.007Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "insuncos.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://insuncos.com/files1/panel/admin.php", + "threat.indicator.url.original": "http://insuncos.com/files1/panel/admin.php", + "threat.indicator.url.path": "/files1/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484339; iType: mal_url; State: active; Org: DDoS-GUARD GmbH; Source: CyberCrime", + "anomali.limo.id": "indicator--33cdeaeb-5201-4fbb-b9ae-9c23377e7533", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:56.007Z", - "threatintel.anomali.name": "mal_url: http://insuncos.com/files1/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:57:56.044Z", + "anomali.limo.name": "mal_url: http://tg-h.ru/login", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://insuncos.com/files1/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:56.007Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:56.007Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "insuncos.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://insuncos.com/files1/panel/admin.php", - "threatintel.indicator.url.original": "http://insuncos.com/files1/panel/admin.php", - "threatintel.indicator.url.path": "/files1/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://tg-h.ru/login']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:57:56.044Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3615,31 +3806,33 @@ "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484339; iType: mal_url; State: active; Org: DDoS-GUARD GmbH; Source: CyberCrime", - "threatintel.anomali.id": "indicator--33cdeaeb-5201-4fbb-b9ae-9c23377e7533", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:57:56.044Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "tg-h.ru", + "threat.indicator.url.full": "http://tg-h.ru/login", + "threat.indicator.url.original": "http://tg-h.ru/login", + "threat.indicator.url.path": "/login", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484351; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--2baaa5f0-c2f6-4bd1-b59d-3a75931da735", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-89", + "threatstream-confidence-86", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:57:56.044Z", - "threatintel.anomali.name": "mal_url: http://tg-h.ru/login", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:11.038Z", + "anomali.limo.name": "mal_url: http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://tg-h.ru/login']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:57:56.044Z", - "threatintel.indicator.first_seen": "2020-01-25T02:57:56.044Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "tg-h.ru", - "threatintel.indicator.url.full": "http://tg-h.ru/login", - "threatintel.indicator.url.original": "http://tg-h.ru/login", - "threatintel.indicator.url.path": "/login", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:11.038Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3656,32 +3849,34 @@ "threatstream-confidence-86", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484351; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--2baaa5f0-c2f6-4bd1-b59d-3a75931da735", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:11.038Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "wusetwo.xyz", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484366; iType: mal_url; State: active; Org: World Hosting Farm Limited; Source: CyberCrime", + "anomali.limo.id": "indicator--f1bdef49-666f-46b5-a323-efa1f1446b62", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-86", + "threatstream-confidence-64", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:11.038Z", - "threatintel.anomali.name": "mal_url: http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:20.420Z", + "anomali.limo.name": "mal_url: http://185.234.217.36/northon/", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:11.038Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:11.038Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "wusetwo.xyz", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://wusetwo.xyz/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/public_html/file/five/inc/class/pCharts/info/Panel/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://185.234.217.36/northon/']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:20.42Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3698,31 +3893,33 @@ "threatstream-confidence-64", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484366; iType: mal_url; State: active; Org: World Hosting Farm Limited; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f1bdef49-666f-46b5-a323-efa1f1446b62", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:20.420Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "185.234.217.36", + "threat.indicator.url.full": "http://185.234.217.36/northon/", + "threat.indicator.url.original": "http://185.234.217.36/northon/", + "threat.indicator.url.path": "/northon/", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484354; iType: mal_url; State: active; Org: McHost.Ru; Source: CyberCrime", + "anomali.limo.id": "indicator--a173f4b1-67ce-44f8-a6d0-bd8a24e8c593", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-64", + "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:20.420Z", - "threatintel.anomali.name": "mal_url: http://185.234.217.36/northon/", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:20.448Z", + "anomali.limo.name": "mal_url: http://topik07.mcdir.ru/papka/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://185.234.217.36/northon/']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:20.42Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:20.420Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "185.234.217.36", - "threatintel.indicator.url.full": "http://185.234.217.36/northon/", - "threatintel.indicator.url.original": "http://185.234.217.36/northon/", - "threatintel.indicator.url.path": "/northon/", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://topik07.mcdir.ru/papka/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:20.448Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3739,32 +3936,34 @@ "threatstream-confidence-84", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484354; iType: mal_url; State: active; Org: McHost.Ru; Source: CyberCrime", - "threatintel.anomali.id": "indicator--a173f4b1-67ce-44f8-a6d0-bd8a24e8c593", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:20.448Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "topik07.mcdir.ru", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://topik07.mcdir.ru/papka/admin.php", + "threat.indicator.url.original": "http://topik07.mcdir.ru/papka/admin.php", + "threat.indicator.url.path": "/papka/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484362; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--b53dded1-d293-4cd1-9e63-b6e0cbd850f0", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-84", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:20.448Z", - "threatintel.anomali.name": "mal_url: http://topik07.mcdir.ru/papka/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:33.189Z", + "anomali.limo.name": "mal_url: http://insuncos.com/files2/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://topik07.mcdir.ru/papka/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:20.448Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:20.448Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "topik07.mcdir.ru", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://topik07.mcdir.ru/papka/admin.php", - "threatintel.indicator.url.original": "http://topik07.mcdir.ru/papka/admin.php", - "threatintel.indicator.url.path": "/papka/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://insuncos.com/files2/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:33.189Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3781,32 +3980,34 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484362; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--b53dded1-d293-4cd1-9e63-b6e0cbd850f0", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:33.189Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "insuncos.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://insuncos.com/files2/panel/admin.php", + "threat.indicator.url.original": "http://insuncos.com/files2/panel/admin.php", + "threat.indicator.url.path": "/files2/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484364; iType: mal_url; State: active; Org: World Hosting Farm Limited; Source: CyberCrime", + "anomali.limo.id": "indicator--2b30f8fe-13e8-4a7d-8eba-3e59c288bef7", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-87", + "threatstream-confidence-47", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:33.189Z", - "threatintel.anomali.name": "mal_url: http://insuncos.com/files2/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:49.056Z", + "anomali.limo.name": "mal_url: http://185.234.218.68/kaspersky/", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://insuncos.com/files2/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:33.189Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:33.189Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "insuncos.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://insuncos.com/files2/panel/admin.php", - "threatintel.indicator.url.original": "http://insuncos.com/files2/panel/admin.php", - "threatintel.indicator.url.path": "/files2/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://185.234.218.68/kaspersky/']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:49.056Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3823,31 +4024,33 @@ "threatstream-confidence-47", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484364; iType: mal_url; State: active; Org: World Hosting Farm Limited; Source: CyberCrime", - "threatintel.anomali.id": "indicator--2b30f8fe-13e8-4a7d-8eba-3e59c288bef7", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:49.056Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "185.234.218.68", + "threat.indicator.url.full": "http://185.234.218.68/kaspersky/", + "threat.indicator.url.original": "http://185.234.218.68/kaspersky/", + "threat.indicator.url.path": "/kaspersky/", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484357; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--f502199a-17a4-404b-a114-fb5eda28c32c", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-47", + "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:49.056Z", - "threatintel.anomali.name": "mal_url: http://185.234.218.68/kaspersky/", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:58:59.472Z", + "anomali.limo.name": "mal_url: http://officelog.org/inc/js/jstree/mh/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://185.234.218.68/kaspersky/']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:49.056Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:49.056Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "185.234.218.68", - "threatintel.indicator.url.full": "http://185.234.218.68/kaspersky/", - "threatintel.indicator.url.original": "http://185.234.218.68/kaspersky/", - "threatintel.indicator.url.path": "/kaspersky/", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/mh/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:58:59.472Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3864,32 +4067,34 @@ "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484357; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--f502199a-17a4-404b-a114-fb5eda28c32c", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:58:59.472Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "officelog.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://officelog.org/inc/js/jstree/mh/panel/admin.php", + "threat.indicator.url.original": "http://officelog.org/inc/js/jstree/mh/panel/admin.php", + "threat.indicator.url.path": "/inc/js/jstree/mh/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484359; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--af7422eb-5d8e-4878-bdd1-395313434dae", + "anomali.limo.labels": [ "malicious-activity", "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:58:59.472Z", - "threatintel.anomali.name": "mal_url: http://officelog.org/inc/js/jstree/mh/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:59:27.070Z", + "anomali.limo.name": "mal_url: http://officelog.org/inc/js/jstree/ch/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/mh/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:58:59.472Z", - "threatintel.indicator.first_seen": "2020-01-25T02:58:59.472Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "officelog.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://officelog.org/inc/js/jstree/mh/panel/admin.php", - "threatintel.indicator.url.original": "http://officelog.org/inc/js/jstree/mh/panel/admin.php", - "threatintel.indicator.url.path": "/inc/js/jstree/mh/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/ch/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:59:27.07Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3906,32 +4111,34 @@ "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484359; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--af7422eb-5d8e-4878-bdd1-395313434dae", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:59:27.070Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "officelog.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://officelog.org/inc/js/jstree/ch/panel/admin.php", + "threat.indicator.url.original": "http://officelog.org/inc/js/jstree/ch/panel/admin.php", + "threat.indicator.url.path": "/inc/js/jstree/ch/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484358; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--71b36c05-86dd-4685-81c0-5a99e2e14c23", + "anomali.limo.labels": [ "malicious-activity", "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:59:27.070Z", - "threatintel.anomali.name": "mal_url: http://officelog.org/inc/js/jstree/ch/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:59:28.967Z", + "anomali.limo.name": "mal_url: http://officelog.org/inc/js/jstree/dar/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/ch/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:59:27.07Z", - "threatintel.indicator.first_seen": "2020-01-25T02:59:27.070Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "officelog.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://officelog.org/inc/js/jstree/ch/panel/admin.php", - "threatintel.indicator.url.original": "http://officelog.org/inc/js/jstree/ch/panel/admin.php", - "threatintel.indicator.url.path": "/inc/js/jstree/ch/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/dar/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:59:28.967Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3948,32 +4155,34 @@ "threatstream-confidence-89", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484358; iType: mal_url; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--71b36c05-86dd-4685-81c0-5a99e2e14c23", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:59:28.967Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "officelog.org", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://officelog.org/inc/js/jstree/dar/panel/admin.php", + "threat.indicator.url.original": "http://officelog.org/inc/js/jstree/dar/panel/admin.php", + "threat.indicator.url.path": "/inc/js/jstree/dar/panel/admin.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484352; iType: mal_url; State: active; Org: Best-Hoster Group Co. Ltd.; Source: CyberCrime", + "anomali.limo.id": "indicator--9d948509-dfb4-45b6-b8bc-780df88a213f", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-89", + "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:59:28.967Z", - "threatintel.anomali.name": "mal_url: http://officelog.org/inc/js/jstree/dar/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:59:37.661Z", + "anomali.limo.name": "mal_url: http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://officelog.org/inc/js/jstree/dar/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:59:28.967Z", - "threatintel.indicator.first_seen": "2020-01-25T02:59:28.967Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "officelog.org", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://officelog.org/inc/js/jstree/dar/panel/admin.php", - "threatintel.indicator.url.original": "http://officelog.org/inc/js/jstree/dar/panel/admin.php", - "threatintel.indicator.url.path": "/inc/js/jstree/dar/panel/admin.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[url:value = 'http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:59:37.661Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -3990,32 +4199,34 @@ "threatstream-confidence-81", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484352; iType: mal_url; State: active; Org: Best-Hoster Group Co. Ltd.; Source: CyberCrime", - "threatintel.anomali.id": "indicator--9d948509-dfb4-45b6-b8bc-780df88a213f", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:59:37.661Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "oaa-my.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.original": "http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.path": "/cage/five/PvqDq929BSx_A_D_M1n_a.php", + "threat.indicator.url.scheme": "http" + }, + { + "anomali.limo.description": "TS ID: 55253484224; iType: mal_ip; State: active; Org: Namecheap; Source: CyberCrime", + "anomali.limo.id": "indicator--9f613f8e-2040-4eee-8044-044023a8093e", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-81", + "threatstream-confidence-53", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:59:37.661Z", - "threatintel.anomali.name": "mal_url: http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:59:37.692Z", + "anomali.limo.name": "mal_ip: 192.64.118.56", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[url:value = 'http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:59:37.661Z", - "threatintel.indicator.first_seen": "2020-01-25T02:59:37.661Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "oaa-my.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.original": "http://oaa-my.com/cage/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.path": "/cage/five/PvqDq929BSx_A_D_M1n_a.php", - "threatintel.indicator.url.scheme": "http" - }, - { + "anomali.limo.pattern": "[ipv4-addr:value = '192.64.118.56']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:59:37.692Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -4032,27 +4243,29 @@ "threatstream-confidence-53", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484224; iType: mal_ip; State: active; Org: Namecheap; Source: CyberCrime", - "threatintel.anomali.id": "indicator--9f613f8e-2040-4eee-8044-044023a8093e", - "threatintel.anomali.labels": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:59:37.692Z", + "threat.indicator.ip": "192.64.118.56", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "ipv4-addr" + }, + { + "anomali.limo.description": "TS ID: 55253484361; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", + "anomali.limo.id": "indicator--518c3959-6c26-413f-9a5f-c8f76d86185a", + "anomali.limo.labels": [ "malicious-activity", - "threatstream-confidence-53", + "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.modified": "2020-01-25T02:59:37.692Z", - "threatintel.anomali.name": "mal_ip: 192.64.118.56", - "threatintel.anomali.object_marking_refs": [ + "anomali.limo.modified": "2020-01-25T02:59:54.296Z", + "anomali.limo.name": "mal_url: http://insuncos.com/files3/panel/admin.php", + "anomali.limo.object_marking_refs": [ "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" ], - "threatintel.anomali.pattern": "[ipv4-addr:value = '192.64.118.56']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:59:37.692Z", - "threatintel.indicator.first_seen": "2020-01-25T02:59:37.692Z", - "threatintel.indicator.ip": "192.64.118.56", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "ipv4-addr" - }, - { + "anomali.limo.pattern": "[url:value = 'http://insuncos.com/files3/panel/admin.php']", + "anomali.limo.type": "indicator", + "anomali.limo.valid_from": "2020-01-25T02:59:54.296Z", "event.category": "threat", "event.dataset": "threatintel.anomali", "event.kind": "enrichment", @@ -4069,29 +4282,16 @@ "threatstream-confidence-87", "threatstream-severity-medium" ], - "threatintel.anomali.description": "TS ID: 55253484361; iType: mal_url; State: active; Org: ServerMania; Source: CyberCrime", - "threatintel.anomali.id": "indicator--518c3959-6c26-413f-9a5f-c8f76d86185a", - "threatintel.anomali.labels": [ - "malicious-activity", - "threatstream-confidence-87", - "threatstream-severity-medium" - ], - "threatintel.anomali.modified": "2020-01-25T02:59:54.296Z", - "threatintel.anomali.name": "mal_url: http://insuncos.com/files3/panel/admin.php", - "threatintel.anomali.object_marking_refs": [ - "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da" - ], - "threatintel.anomali.pattern": "[url:value = 'http://insuncos.com/files3/panel/admin.php']", - "threatintel.anomali.type": "indicator", - "threatintel.anomali.valid_from": "2020-01-25T02:59:54.296Z", - "threatintel.indicator.first_seen": "2020-01-25T02:59:54.296Z", - "threatintel.indicator.provider": "CyberCrime", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "insuncos.com", - "threatintel.indicator.url.extension": "php", - "threatintel.indicator.url.full": "http://insuncos.com/files3/panel/admin.php", - "threatintel.indicator.url.original": "http://insuncos.com/files3/panel/admin.php", - "threatintel.indicator.url.path": "/files3/panel/admin.php", - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali Limo", + "threat.indicator.first_seen": "2020-01-25T02:59:54.296Z", + "threat.indicator.provider": "CyberCrime", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "insuncos.com", + "threat.indicator.url.extension": "php", + "threat.indicator.url.full": "http://insuncos.com/files3/panel/admin.php", + "threat.indicator.url.original": "http://insuncos.com/files3/panel/admin.php", + "threat.indicator.url.path": "/files3/panel/admin.php", + "threat.indicator.url.scheme": "http" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/_meta/fields.yml b/x-pack/filebeat/module/threatintel/anomalithreatstream/_meta/fields.yml index de0ededab33c..41fae21921cb 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/_meta/fields.yml @@ -1,4 +1,4 @@ -- name: anomalithreatstream +- name: anomali.threatstream type: group description: > Fields for Anomali ThreatStream diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/config/config.yml b/x-pack/filebeat/module/threatintel/anomalithreatstream/config/config.yml index f6cfe0243053..4d814c03fe56 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/config/config.yml +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/config/config.yml @@ -1,7 +1,6 @@ {{ if eq .input "http_endpoint" }} type: http_endpoint -enabled: true listen_address: {{ .listen_address }} listen_port: {{ .listen_port }} @@ -16,12 +15,12 @@ hmac: prefix: sha256= {{ end }} -{{ if .ssl_certificate }} -ssl: - enabled: true - certificate: {{ .ssl_certificate }} - key: {{ .ssl_key }} - verification_mode: none +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + +{{ if .preserve_original_event }} +preserve_original_event: true {{ end }} {{ else if eq .input "file" }} @@ -35,24 +34,12 @@ exclude_files: [".gz$"] json.add_error_key: true {{ end }} -tags: {{.tags | tojson}} - -processors: - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 - - fingerprint: - fields: - - event.dataset - - json.id - target_field: '@metadata._id' - encoding: base64 - - script: - lang: javascript - id: my_filter - source: > - function process(event) { - event.Put("@metadata.op_type", "index"); - } +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml index 22644d79518a..50b5c6c7bb2a 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml @@ -1,19 +1,21 @@ +--- description: Pipeline for parsing Anomali ThreatStream processors: - # - # Safeguard against feeding the pipeline with documents other - # that the ones generated by Filebeat's http_endpoint input. - # - - fail: - if: "ctx.json == null || !(ctx.json instanceof Map)" - message: "missing json object in input document" - # # Set basic ECS fields. # - set: field: event.ingested value: "{{{ _ingest.timestamp }}}" + - set: + field: ecs.version + value: "1.12" + - fingerprint: + fields: + - event.dataset + - json.id + target_field: "_id" + ignore_missing: true - set: field: event.kind value: enrichment @@ -24,14 +26,21 @@ processors: field: event.type value: indicator + - set: + field: threat.feed.name + value: "[Filebeat] Anomali ThreatStream" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" + # - # Map itype field to STIX 2.0 Cyber Observable values (threatintel.indicator.type). + # Map itype field to STIX 2.0 Cyber Observable values (threat.indicator.type). # - script: lang: painless if: "ctx.json.itype != null" description: > - Map itype field to STIX 2.0 Cyber Observable values (threatintel.indicator.type). + Map itype field to STIX 2.0 Cyber Observable values (threat.indicator.type). params: actor_ip: ipv4-addr adware_domain: domain-name @@ -125,26 +134,26 @@ processors: - rename: field: threatintel_indicator_type - target_field: threatintel.indicator.type + target_field: threat.indicator.type ignore_missing: true # # Detect ipv6 for ipv4-addr types. # - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv6-addr - if: 'ctx.threatintel?.indicator?.type == "ipv4-addr" && ctx.json.srcip != null && ctx.json.srcip.contains(":")' + if: 'ctx.threat?.indicator?.type == "ipv4-addr" && ctx.json?.srcip != null && ctx.json.srcip.contains(":")' # # Map first and last seen dates. # - date: field: json.date_first - target_field: threatintel.indicator.first_seen + target_field: threat.indicator.first_seen formats: - ISO8601 - if: "ctx.json.date_first != null" + if: "ctx.json?.date_first != null" on_failure: - append: field: error.message @@ -152,10 +161,10 @@ processors: - date: field: json.date_last - target_field: threatintel.indicator.last_seen + target_field: threat.indicator.last_seen formats: - ISO8601 - if: "ctx.json.date_last != null" + if: "ctx.json?.date_last != null" on_failure: - append: field: error.message @@ -166,18 +175,18 @@ processors: # - convert: field: json.lat - target_field: threatintel.indicator.geo.location.lat + target_field: threat.indicator.geo.location.lat type: double - if: "ctx.json.lat != null && ctx.json.lon != null" + if: "ctx.json?.lat != null && ctx.json?.lon != null" on_failure: - append: field: error.message value: 'Cannot convert lat field "{{{ json.lat }}}" to double: {{{ _ingest.on_failure_message }}}' - convert: field: json.lon - target_field: threatintel.indicator.geo.location.lon + target_field: threat.indicator.geo.location.lon type: double - if: "ctx.json.lat != null && ctx.json.lon != null" + if: "ctx.json?.lat != null && ctx.json?.lon != null" on_failure: - append: field: error.message @@ -190,25 +199,40 @@ processors: # private => Amber ("Limited disclosure, restricted to participants’ organizations."). # - append: - field: threatintel.indicator.marking.tlp + field: threat.indicator.marking.tlp value: Amber - if: 'ctx.json.classification == "private"' + if: 'ctx.json?.classification == "private"' - append: - field: threatintel.indicator.marking.tlp + field: threat.indicator.marking.tlp value: White - if: 'ctx.json.classification == "public"' + if: 'ctx.json?.classification == "public"' # # Convert confidence field (-1..100) to ECS confidence (0..10). # - script: lang: painless + if: ctx.json?.confidence != null description: > Normalize confidence level. source: > def value = ctx.json.confidence; - if (value == null || value < 0.0 || value > 100.0) return; - ctx["threatintel_indicator_confidence"] = (long)Math.round((double)value / 10.0); + if (value <= 0.0 || value > 100.0) { + ctx["threatintel_indicator_confidence"] = "None"; + return; + } + if (value >= 1.0 && value <= 29.0) { + ctx["threatintel_indicator_confidence"] = "Low"; + return; + } + if (value >= 30.0 && value <= 69.0) { + ctx["threatintel_indicator_confidence"] = "Med"; + return; + } + if (value >= 70 && value <= 100) { + ctx["threatintel_indicator_confidence"] = "High"; + return; + } on_failure: - append: field: error.message @@ -216,7 +240,7 @@ processors: - rename: field: threatintel_indicator_confidence - target_field: threatintel.indicator.confidence + target_field: threat.indicator.confidence ignore_missing: true # @@ -224,7 +248,7 @@ processors: # - convert: field: json.asn - target_field: threatintel.indicator.as.number + target_field: threat.indicator.as.number type: long ignore_missing: true on_failure: @@ -234,41 +258,41 @@ processors: - rename: field: json.org - target_field: threatintel.indicator.as.organization.name + target_field: threat.indicator.as.organization.name ignore_missing: true - rename: field: json.email - target_field: threatintel.indicator.email.address + target_field: threat.indicator.email.address ignore_missing: true - rename: field: json.srcip - target_field: threatintel.indicator.ip + target_field: threat.indicator.ip ignore_missing: true - uri_parts: field: json.url - target_field: threatintel.indicator.url + target_field: threat.indicator.url keep_original: true remove_if_successful: true - if: "ctx.json.url != null" + if: "ctx.json?.url != null" on_failure: - append: field: error.message value: "Cannot parse url field `{{{ json.url }}}`: {{{ _ingest.on_failure_message }}}" - set: - field: threatintel.indicator.url.full - value: "{{{threatintel.indicator.url.original}}}" + field: threat.indicator.url.full + value: "{{{threat.indicator.url.original}}}" ignore_empty_value: true - rename: field: json.domain - target_field: threatintel.indicator.url.domain + target_field: threat.indicator.url.domain ignore_missing: true - if: ctx.threatintel?.indicator?.url?.domain == null + if: ctx.threat?.indicator?.url?.domain == null - rename: field: json.country - target_field: threatintel.indicator.geo.country_iso_code + target_field: threat.indicator.geo.country_iso_code ignore_missing: true # @@ -277,27 +301,27 @@ processors: # - rename: field: json.md5 - target_field: threatintel.indicator.file.hash.md5 - if: "ctx.json.md5 != null && ctx.json.md5.length() == 32" + target_field: threat.indicator.file.hash.md5 + if: "ctx.json?.md5 != null && ctx.json.md5.length() == 32" - rename: field: json.md5 - target_field: threatintel.indicator.file.hash.sha1 - if: "ctx.json.md5 != null && ctx.json.md5.length() == 40" + target_field: threat.indicator.file.hash.sha1 + if: "ctx.json?.md5 != null && ctx.json.md5.length() == 40" - rename: field: json.md5 - target_field: threatintel.indicator.file.hash.sha256 - if: "ctx.json.md5 != null && ctx.json.md5.length() == 64" + target_field: threat.indicator.file.hash.sha256 + if: "ctx.json?.md5 != null && ctx.json.md5.length() == 64" - rename: field: json.md5 - target_field: threatintel.indicator.file.hash.sha512 - if: "ctx.json.md5 != null && ctx.json.md5.length() == 128" + target_field: threat.indicator.file.hash.sha512 + if: "ctx.json?.md5 != null && ctx.json.md5.length() == 128" - rename: field: json.source - target_field: threatintel.indicator.provider + target_field: threat.indicator.provider ignore_missing: true # @@ -310,22 +334,22 @@ processors: - set: field: event.severity value: 3 - if: 'ctx.json.severity == "low"' + if: 'ctx.json?.severity == "low"' - set: field: event.severity value: 5 - if: 'ctx.json.severity == "medium"' + if: 'ctx.json?.severity == "medium"' - set: field: event.severity value: 7 - if: 'ctx.json.severity == "high"' + if: 'ctx.json?.severity == "high"' - set: field: event.severity value: 9 - if: 'ctx.json.severity == "very-high"' + if: 'ctx.json?.severity == "very-high"' # # Field trusted_circles_ids is a comma-separated string @@ -335,24 +359,16 @@ processors: # - script: lang: painless - if: "ctx.json.trusted_circle_ids != null && ctx.json.trusted_circle_ids instanceof String" + if: "ctx.json?.trusted_circle_ids != null && ctx.json?.trusted_circle_ids instanceof String" description: > Convert trusted_circles_ids from CSV to an array. source: > - def lst = - Stream.of(ctx.json.trusted_circle_ids.splitOnToken(",")) - .filter(s -> !s.isEmpty()) - .toArray(String[]::new); - if (lst.length > 0) { + def lst = Stream.of(ctx.json.trusted_circle_ids.splitOnToken(',')).filter(s -> !s.isEmpty()).collect(Collectors.toList()); + if (lst.size() > 0) { ctx.json.trusted_circle_ids = lst; } else { ctx.json.remove('trusted_circle_ids'); } - on_failure: - - append: - field: error.message - value: 'unable to split trusted_circle_ids "{{{ json.trusted_circle_ids }}}": {{{ _ingest.on_failure_message }}}' - # # Split detail field and append each component to ECS tags field. # @@ -372,10 +388,33 @@ processors: append: field: tags value: "{{{ _ingest._value }}}" - + # + # Convert certain fields to the correct value + # + - convert: + field: json.id + type: string + if: "ctx.json?.id != null" + - convert: + field: json.source_feed_id + type: string + if: "ctx.json?.source_feed_id != null" + - convert: + field: json.update_id + type: string + if: "ctx.json?.update_id != null" + - convert: + field: json.import_session_id + type: string + if: "ctx.json?.import_session_id != null" # # Remove fields converted to an ECS field. # + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - remove: field: - json.asn @@ -391,7 +430,7 @@ processors: # - rename: field: json - target_field: threatintel.anomalithreatstream + target_field: anomali.threatstream on_failure: - append: diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/manifest.yml b/x-pack/filebeat/module/threatintel/anomalithreatstream/manifest.yml index de6faeea2274..011e2bb553eb 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/manifest.yml +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/manifest.yml @@ -8,13 +8,15 @@ var: - name: listen_port default: 8080 - name: secret - - name: ssl_certificate - - name: ssl_key + - name: ssl - name: paths default: /path/to/testing.log - name: tags default: - threatintel-anomalithreatstream + - forwarded + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml input: config/config.yml diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/test/generated.log-expected.json b/x-pack/filebeat/module/threatintel/anomalithreatstream/test/generated.log-expected.json index 21c627dde57d..b101076a9e1c 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/test/generated.log-expected.json +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/test/generated.log-expected.json @@ -1,5 +1,20 @@ [ { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 20, + "anomali.threatstream.detail2": "imported by user 184", + "anomali.threatstream.id": "3135167627", + "anomali.threatstream.import_session_id": "1400", + "anomali.threatstream.itype": "mal_domain", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P46279656657/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3143", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "122" + ], + "anomali.threatstream.update_id": "3786618776", + "anomali.threatstream.value_type": "domain", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -11,39 +26,44 @@ "log.offset": 0, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 20, - "threatintel.anomalithreatstream.detail2": "imported by user 184", - "threatintel.anomalithreatstream.id": 3135167627, - "threatintel.anomalithreatstream.import_session_id": 1400, - "threatintel.anomalithreatstream.itype": "mal_domain", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P46279656657/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3143, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "122" - ], - "threatintel.anomalithreatstream.update_id": 3786618776, - "threatintel.anomalithreatstream.value_type": "domain", - "threatintel.indicator.as.organization.name": "OVH Hosting", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-08T12:21:50.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.geo.location.lat": -49.1, - "threatintel.indicator.geo.location.lon": 94.4, - "threatintel.indicator.ip": "203.0.113.35", - "threatintel.indicator.last_seen": "2020-10-08T12:24:42.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.organization.name": "OVH Hosting", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-08T12:21:50.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.geo.location.lat": -49.1, + "threat.indicator.geo.location.lon": 94.4, + "threat.indicator.ip": "203.0.113.35", + "threat.indicator.last_seen": "2020-10-08T12:24:42.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "d4xgfj.example.net" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "d4xgfj.example.net" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 51, + "anomali.threatstream.detail2": "imported by user 979", + "anomali.threatstream.id": "2465691587", + "anomali.threatstream.import_session_id": "1934", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P26893014825/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "639", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "355", + "386", + "461" + ], + "anomali.threatstream.update_id": "3311633654", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -55,40 +75,42 @@ "log.offset": 575, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 51, - "threatintel.anomalithreatstream.detail2": "imported by user 979", - "threatintel.anomalithreatstream.id": 2465691587, - "threatintel.anomalithreatstream.import_session_id": 1934, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P26893014825/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 639, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "355", - "386", - "461" - ], - "threatintel.anomalithreatstream.update_id": 3311633654, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.as.organization.name": "IP Khnykin Vitaliy Yakovlevich", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-08T12:21:59.000Z", - "threatintel.indicator.geo.country_iso_code": "RU", - "threatintel.indicator.geo.location.lat": -51.2, - "threatintel.indicator.geo.location.lon": -64.7, - "threatintel.indicator.ip": "2001:db8:fc77:2510:5ab8:7bc8:65a3:4894", - "threatintel.indicator.last_seen": "2020-10-08T12:24:42.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.organization.name": "IP Khnykin Vitaliy Yakovlevich", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-08T12:21:59.000Z", + "threat.indicator.geo.country_iso_code": "RU", + "threat.indicator.geo.location.lat": -51.2, + "threat.indicator.geo.location.lon": -64.7, + "threat.indicator.ip": "2001:db8:fc77:2510:5ab8:7bc8:65a3:4894", + "threat.indicator.last_seen": "2020-10-08T12:24:42.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv6-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv6-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 24, + "anomali.threatstream.detail2": "imported by user 830", + "anomali.threatstream.id": "1886961414", + "anomali.threatstream.import_session_id": "3569", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P16938191113/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2564", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "740", + "954" + ], + "anomali.threatstream.update_id": "1860329541", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -100,40 +122,45 @@ "log.offset": 1163, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 24, - "threatintel.anomalithreatstream.detail2": "imported by user 830", - "threatintel.anomalithreatstream.id": 1886961414, - "threatintel.anomalithreatstream.import_session_id": 3569, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P16938191113/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2564, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "740", - "954" - ], - "threatintel.anomalithreatstream.update_id": 1860329541, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.as.number": 22773, - "threatintel.indicator.as.organization.name": "Cox Communications", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-08T12:22:11.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.geo.location.lat": 38.4, - "threatintel.indicator.geo.location.lon": 0.0, - "threatintel.indicator.ip": "192.0.2.8", - "threatintel.indicator.last_seen": "2020-10-08T12:24:42.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.number": 22773, + "threat.indicator.as.organization.name": "Cox Communications", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-08T12:22:11.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.geo.location.lat": 38.4, + "threat.indicator.geo.location.lon": 0.0, + "threat.indicator.ip": "192.0.2.8", + "threat.indicator.last_seen": "2020-10-08T12:24:42.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 56, + "anomali.threatstream.detail2": "imported by user 723", + "anomali.threatstream.id": "1785659799", + "anomali.threatstream.import_session_id": "244", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.md5": "6466e2", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P44706407813/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "3759", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "439", + "801", + "942" + ], + "anomali.threatstream.update_id": "3898969521", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -145,36 +172,38 @@ "log.offset": 1720, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 56, - "threatintel.anomalithreatstream.detail2": "imported by user 723", - "threatintel.anomalithreatstream.id": 1785659799, - "threatintel.anomalithreatstream.import_session_id": 244, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.md5": "6466e2", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P44706407813/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 3759, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "439", - "801", - "942" - ], - "threatintel.anomalithreatstream.update_id": 3898969521, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-08T12:22:16.000Z", - "threatintel.indicator.last_seen": "2020-10-08T12:24:42.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-08T12:22:16.000Z", + "threat.indicator.last_seen": "2020-10-08T12:24:42.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 61, + "anomali.threatstream.detail2": "imported by user 16", + "anomali.threatstream.id": "2788278724", + "anomali.threatstream.import_session_id": "3146", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P39996084337/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1834", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "310", + "553", + "709" + ], + "anomali.threatstream.update_id": "1925356831", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -186,41 +215,43 @@ "log.offset": 2195, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 61, - "threatintel.anomalithreatstream.detail2": "imported by user 16", - "threatintel.anomalithreatstream.id": 2788278724, - "threatintel.anomalithreatstream.import_session_id": 3146, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P39996084337/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1834, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "310", - "553", - "709" - ], - "threatintel.anomalithreatstream.update_id": 1925356831, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.as.number": 20001, - "threatintel.indicator.as.organization.name": "Spectrum", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-08T12:28:50.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.geo.location.lat": -64.8, - "threatintel.indicator.geo.location.lon": -129.3, - "threatintel.indicator.ip": "192.0.2.235", - "threatintel.indicator.last_seen": "2020-10-09T18:49:37.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.number": 20001, + "threat.indicator.as.organization.name": "Spectrum", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-08T12:28:50.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.geo.location.lat": -64.8, + "threat.indicator.geo.location.lon": -129.3, + "threat.indicator.ip": "192.0.2.235", + "threat.indicator.last_seen": "2020-10-09T18:49:37.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 31, + "anomali.threatstream.detail2": "imported by user 659", + "anomali.threatstream.id": "2979716207", + "anomali.threatstream.import_session_id": "2369", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P24601068254/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "2122", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "297", + "811" + ], + "anomali.threatstream.update_id": "1327494837", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -232,40 +263,44 @@ "log.offset": 2757, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 31, - "threatintel.anomalithreatstream.detail2": "imported by user 659", - "threatintel.anomalithreatstream.id": 2979716207, - "threatintel.anomalithreatstream.import_session_id": 2369, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P24601068254/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 2122, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "297", - "811" - ], - "threatintel.anomalithreatstream.update_id": 1327494837, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.as.number": 11351, - "threatintel.indicator.as.organization.name": "Spectrum", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-08T12:29:01.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.geo.location.lat": 72.1, - "threatintel.indicator.geo.location.lon": -52.2, - "threatintel.indicator.ip": "2001:db8:df14:f43b:a986:5e2a:8ce9:4523", - "threatintel.indicator.last_seen": "2020-10-09T18:49:37.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.number": 11351, + "threat.indicator.as.organization.name": "Spectrum", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-08T12:29:01.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.geo.location.lat": 72.1, + "threat.indicator.geo.location.lon": -52.2, + "threat.indicator.ip": "2001:db8:df14:f43b:a986:5e2a:8ce9:4523", + "threat.indicator.last_seen": "2020-10-09T18:49:37.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv6-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv6-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 72, + "anomali.threatstream.detail2": "imported by user 50", + "anomali.threatstream.id": "3763825895", + "anomali.threatstream.itype": "c2_domain", + "anomali.threatstream.maltype": "malware:r47agu9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P49850231022/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "967", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "238", + "259", + "537" + ], + "anomali.threatstream.update_id": "1356750652", + "anomali.threatstream.value_type": "domain", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -281,6 +316,7 @@ "Botnet-1QZ2U", "Botnet-VXPC5QK8T", "first_seen=2020-07-24T07:36:41", + "forwarded", "mask=2001:db8:867f:42a1:d692:b396:4f14:548c", "popularity=high", "popularity=high", @@ -288,35 +324,37 @@ "threatintel-anomalithreatstream", "type=2" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 72, - "threatintel.anomalithreatstream.detail2": "imported by user 50", - "threatintel.anomalithreatstream.id": 3763825895, - "threatintel.anomalithreatstream.itype": "c2_domain", - "threatintel.anomalithreatstream.maltype": "malware:r47agu9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P49850231022/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 967, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "238", - "259", - "537" - ], - "threatintel.anomalithreatstream.update_id": 1356750652, - "threatintel.anomalithreatstream.value_type": "domain", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:14:43.000Z", - "threatintel.indicator.ip": "203.0.113.130", - "threatintel.indicator.last_seen": "2020-10-09T18:14:43.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:14:43.000Z", + "threat.indicator.ip": "203.0.113.130", + "threat.indicator.last_seen": "2020-10-09T18:14:43.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "ei1im6skd.example.com" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "ei1im6skd.example.com" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 60, + "anomali.threatstream.detail2": "imported by user 167", + "anomali.threatstream.id": "3178646499", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.md5": "0f321db9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P35792781031/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1743", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "112", + "455", + "761" + ], + "anomali.threatstream.update_id": "1585930018", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -328,35 +366,37 @@ "log.offset": 4049, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 60, - "threatintel.anomalithreatstream.detail2": "imported by user 167", - "threatintel.anomalithreatstream.id": 3178646499, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.md5": "0f321db9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P35792781031/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1743, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "112", - "455", - "761" - ], - "threatintel.anomalithreatstream.update_id": 1585930018, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:30:10.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:10.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:30:10.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:10.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 70, + "anomali.threatstream.detail2": "imported by user 654", + "anomali.threatstream.id": "2435568409", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:9rb9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P41264495308/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "3940", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "633", + "641" + ], + "anomali.threatstream.update_id": "2070423140", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -368,43 +408,46 @@ "log.offset": 4495, "service.type": "threatintel", "tags": [ + "forwarded", "jn5jpvg", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 70, - "threatintel.anomalithreatstream.detail2": "imported by user 654", - "threatintel.anomalithreatstream.id": 2435568409, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:9rb9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P41264495308/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 3940, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "633", - "641" - ], - "threatintel.anomalithreatstream.update_id": 2070423140, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:30:13.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.236", - "threatintel.indicator.last_seen": "2020-10-09T18:30:13.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:30:13.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.236", + "threat.indicator.last_seen": "2020-10-09T18:30:13.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ax1a6o38z.example.org", - "threatintel.indicator.url.full": "https://ax1a6o38z.example.org/enec3i/f1n8fv?4shpqq9=fbo9osx8p", - "threatintel.indicator.url.original": "https://ax1a6o38z.example.org/enec3i/f1n8fv?4shpqq9=fbo9osx8p", - "threatintel.indicator.url.path": "/enec3i/f1n8fv", - "threatintel.indicator.url.query": "4shpqq9=fbo9osx8p", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ax1a6o38z.example.org", + "threat.indicator.url.full": "https://ax1a6o38z.example.org/enec3i/f1n8fv?4shpqq9=fbo9osx8p", + "threat.indicator.url.original": "https://ax1a6o38z.example.org/enec3i/f1n8fv?4shpqq9=fbo9osx8p", + "threat.indicator.url.path": "/enec3i/f1n8fv", + "threat.indicator.url.query": "4shpqq9=fbo9osx8p", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 35, + "anomali.threatstream.detail2": "imported by user 81", + "anomali.threatstream.id": "1404936664", + "anomali.threatstream.itype": "mal_url", + "anomali.threatstream.maltype": "malware:4p1lc0bf", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P22799247040/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "2236", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "424", + "718" + ], + "anomali.threatstream.update_id": "2151391711", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -417,43 +460,46 @@ "service.type": "threatintel", "tags": [ "7zhsn5t7", + "forwarded", "threatintel-anomalithreatstream", "xl4" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 35, - "threatintel.anomalithreatstream.detail2": "imported by user 81", - "threatintel.anomalithreatstream.id": 1404936664, - "threatintel.anomalithreatstream.itype": "mal_url", - "threatintel.anomalithreatstream.maltype": "malware:4p1lc0bf", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P22799247040/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 2236, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "424", - "718" - ], - "threatintel.anomalithreatstream.update_id": 2151391711, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 4, - "threatintel.indicator.first_seen": "2020-10-09T18:30:13.000Z", - "threatintel.indicator.geo.country_iso_code": "CN", - "threatintel.indicator.ip": "2001:db8:62cc:2fd2:f406:9c03:e2e8:617d", - "threatintel.indicator.last_seen": "2020-10-09T18:30:13.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:30:13.000Z", + "threat.indicator.geo.country_iso_code": "CN", + "threat.indicator.ip": "2001:db8:62cc:2fd2:f406:9c03:e2e8:617d", + "threat.indicator.last_seen": "2020-10-09T18:30:13.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "beko3.example.com", - "threatintel.indicator.url.full": "https://beko3.example.com/vkelnz/jdz6zf-ga?g39fu=88309ge", - "threatintel.indicator.url.original": "https://beko3.example.com/vkelnz/jdz6zf-ga?g39fu=88309ge", - "threatintel.indicator.url.path": "/vkelnz/jdz6zf-ga", - "threatintel.indicator.url.query": "g39fu=88309ge", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "beko3.example.com", + "threat.indicator.url.full": "https://beko3.example.com/vkelnz/jdz6zf-ga?g39fu=88309ge", + "threat.indicator.url.original": "https://beko3.example.com/vkelnz/jdz6zf-ga?g39fu=88309ge", + "threat.indicator.url.path": "/vkelnz/jdz6zf-ga", + "threat.indicator.url.query": "g39fu=88309ge", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 7, + "anomali.threatstream.detail2": "imported by user 993", + "anomali.threatstream.id": "1300368058", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:s7-t", + "anomali.threatstream.md5": "b91c", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P43593676062/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1581", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "812" + ], + "anomali.threatstream.update_id": "1852221746", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -467,34 +513,39 @@ "tags": [ "aampq5", "d6-", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 7, - "threatintel.anomalithreatstream.detail2": "imported by user 993", - "threatintel.anomalithreatstream.id": 1300368058, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:s7-t", - "threatintel.anomalithreatstream.md5": "b91c", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P43593676062/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1581, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "812" - ], - "threatintel.anomalithreatstream.update_id": 1852221746, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:30:22.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:22.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:30:22.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:22.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 63, + "anomali.threatstream.detail2": "imported by user 963", + "anomali.threatstream.id": "1511736215", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:0vnvp84", + "anomali.threatstream.md5": "3c49c", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P47666251160/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1695", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "29", + "537", + "879" + ], + "anomali.threatstream.update_id": "3048270616", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -507,36 +558,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 63, - "threatintel.anomalithreatstream.detail2": "imported by user 963", - "threatintel.anomalithreatstream.id": 1511736215, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:0vnvp84", - "threatintel.anomalithreatstream.md5": "3c49c", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P47666251160/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1695, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "29", - "537", - "879" - ], - "threatintel.anomalithreatstream.update_id": 3048270616, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:30:23.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:23.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:30:23.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:23.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 95, + "anomali.threatstream.detail2": "imported by user 302", + "anomali.threatstream.id": "2213035853", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:25iv", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P11608678465/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "787", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "154", + "766" + ], + "anomali.threatstream.update_id": "2851232102", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -549,42 +601,46 @@ "service.type": "threatintel", "tags": [ "22nciqjs", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 95, - "threatintel.anomalithreatstream.detail2": "imported by user 302", - "threatintel.anomalithreatstream.id": 2213035853, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:25iv", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P11608678465/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 787, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "154", - "766" - ], - "threatintel.anomalithreatstream.update_id": 2851232102, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 10, - "threatintel.indicator.first_seen": "2020-10-09T18:30:30.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.162", - "threatintel.indicator.last_seen": "2020-10-09T18:30:30.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:30:30.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.162", + "threat.indicator.last_seen": "2020-10-09T18:30:30.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "sevs82.example.com", - "threatintel.indicator.url.full": "http://sevs82.example.com/c5-d/hdajog?4rs78hl=wvwi", - "threatintel.indicator.url.original": "http://sevs82.example.com/c5-d/hdajog?4rs78hl=wvwi", - "threatintel.indicator.url.path": "/c5-d/hdajog", - "threatintel.indicator.url.query": "4rs78hl=wvwi", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "sevs82.example.com", + "threat.indicator.url.full": "http://sevs82.example.com/c5-d/hdajog?4rs78hl=wvwi", + "threat.indicator.url.original": "http://sevs82.example.com/c5-d/hdajog?4rs78hl=wvwi", + "threat.indicator.url.path": "/c5-d/hdajog", + "threat.indicator.url.query": "4rs78hl=wvwi", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 18, + "anomali.threatstream.detail2": "imported by user 548", + "anomali.threatstream.id": "2594216423", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:i6z9qr", + "anomali.threatstream.md5": "e29608b", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P32471582403/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1475", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "539", + "6" + ], + "anomali.threatstream.update_id": "2328838402", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -597,36 +653,38 @@ "service.type": "threatintel", "tags": [ "26sg-3-", + "forwarded", "threatintel-anomalithreatstream", "vnx4nu7c" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 18, - "threatintel.anomalithreatstream.detail2": "imported by user 548", - "threatintel.anomalithreatstream.id": 2594216423, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:i6z9qr", - "threatintel.anomalithreatstream.md5": "e29608b", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P32471582403/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1475, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "539", - "6" - ], - "threatintel.anomalithreatstream.update_id": 2328838402, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:30:37.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:37.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:30:37.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:37.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 54, + "anomali.threatstream.detail2": "imported by user 438", + "anomali.threatstream.id": "1133111133", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:4rs9qpc1", + "anomali.threatstream.md5": "c38d2e6d", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P20539380512/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3600", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "762" + ], + "anomali.threatstream.update_id": "1784507596", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -639,34 +697,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 54, - "threatintel.anomalithreatstream.detail2": "imported by user 438", - "threatintel.anomalithreatstream.id": 1133111133, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:4rs9qpc1", - "threatintel.anomalithreatstream.md5": "c38d2e6d", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P20539380512/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3600, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "762" - ], - "threatintel.anomalithreatstream.update_id": 1784507596, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:30:40.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:40.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:30:40.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:40.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 78, + "anomali.threatstream.detail2": "imported by user 690", + "anomali.threatstream.id": "2543010039", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:ghdl7nwwq", + "anomali.threatstream.md5": "67808c", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P16167095005/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "926", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "751" + ], + "anomali.threatstream.update_id": "2343991526", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -679,35 +740,40 @@ "service.type": "threatintel", "tags": [ "8ahl", + "forwarded", "ica", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 78, - "threatintel.anomalithreatstream.detail2": "imported by user 690", - "threatintel.anomalithreatstream.id": 2543010039, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:ghdl7nwwq", - "threatintel.anomalithreatstream.md5": "67808c", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P16167095005/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 926, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "751" - ], - "threatintel.anomalithreatstream.update_id": 2343991526, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2020-10-09T18:30:45.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:45.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:30:45.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:45.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 0, + "anomali.threatstream.detail2": "imported by user 517", + "anomali.threatstream.id": "3233930917", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:m5pk44o", + "anomali.threatstream.md5": "efa99", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P15758111412/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2010", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "390", + "519", + "909" + ], + "anomali.threatstream.update_id": "3008175946", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -719,38 +785,41 @@ "log.offset": 8774, "service.type": "threatintel", "tags": [ + "forwarded", "gyu-", "iop", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 0, - "threatintel.anomalithreatstream.detail2": "imported by user 517", - "threatintel.anomalithreatstream.id": 3233930917, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:m5pk44o", - "threatintel.anomalithreatstream.md5": "efa99", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P15758111412/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2010, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "390", - "519", - "909" - ], - "threatintel.anomalithreatstream.update_id": 3008175946, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 0, - "threatintel.indicator.first_seen": "2020-10-09T18:30:54.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:54.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:30:54.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:54.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 34, + "anomali.threatstream.detail2": "imported by user 303", + "anomali.threatstream.id": "1777540600", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:-fesxy", + "anomali.threatstream.md5": "e8c1", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P13990676648/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3201", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "109", + "621", + "718" + ], + "anomali.threatstream.update_id": "2404949482", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -763,36 +832,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 34, - "threatintel.anomalithreatstream.detail2": "imported by user 303", - "threatintel.anomalithreatstream.id": 1777540600, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:-fesxy", - "threatintel.anomalithreatstream.md5": "e8c1", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P13990676648/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3201, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "109", - "621", - "718" - ], - "threatintel.anomalithreatstream.update_id": 2404949482, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:30:59.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:30:59.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:30:59.000Z", + "threat.indicator.last_seen": "2020-10-09T18:30:59.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 15, + "anomali.threatstream.detail2": "imported by user 219", + "anomali.threatstream.id": "2796250594", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:c1b7kt7", + "anomali.threatstream.md5": "be24", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P13506696048/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "3205", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "559" + ], + "anomali.threatstream.update_id": "3529199846", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -805,34 +875,39 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 15, - "threatintel.anomalithreatstream.detail2": "imported by user 219", - "threatintel.anomalithreatstream.id": 2796250594, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:c1b7kt7", - "threatintel.anomalithreatstream.md5": "be24", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P13506696048/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 3205, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "559" - ], - "threatintel.anomalithreatstream.update_id": 3529199846, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:31:10.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:10.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:31:10.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:10.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 56, + "anomali.threatstream.detail2": "imported by user 762", + "anomali.threatstream.id": "2310429917", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:slwl", + "anomali.threatstream.md5": "a2678fc", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P35629727989/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "885", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "190", + "495", + "959" + ], + "anomali.threatstream.update_id": "3510871820", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -845,36 +920,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 56, - "threatintel.anomalithreatstream.detail2": "imported by user 762", - "threatintel.anomalithreatstream.id": 2310429917, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:slwl", - "threatintel.anomalithreatstream.md5": "a2678fc", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P35629727989/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 885, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "190", - "495", - "959" - ], - "threatintel.anomalithreatstream.update_id": 3510871820, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:31:16.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:16.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:31:16.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:16.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 11, + "anomali.threatstream.detail2": "imported by user 616", + "anomali.threatstream.id": "2853859039", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:voc", + "anomali.threatstream.md5": "2ee715a9b", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P39948074871/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "586", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "454", + "562" + ], + "anomali.threatstream.update_id": "3756244435", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -887,35 +964,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 11, - "threatintel.anomalithreatstream.detail2": "imported by user 616", - "threatintel.anomalithreatstream.id": 2853859039, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:voc", - "threatintel.anomalithreatstream.md5": "2ee715a9b", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P39948074871/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 586, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "454", - "562" - ], - "threatintel.anomalithreatstream.update_id": 3756244435, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:31:22.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:22.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:31:22.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:22.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 51, + "anomali.threatstream.detail2": "imported by user 510", + "anomali.threatstream.id": "2328858169", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:yuq33pg5", + "anomali.threatstream.md5": "e1df8d", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P30902643017/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "826", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "362", + "846" + ], + "anomali.threatstream.update_id": "1410682100", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -928,39 +1008,41 @@ "service.type": "threatintel", "tags": [ "etukwxhs", + "forwarded", "g0vc9", "gcgm1we6l", "mask=203.0.113.182", "threat=bm-uj8c12", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 51, - "threatintel.anomalithreatstream.detail2": "imported by user 510", - "threatintel.anomalithreatstream.id": 2328858169, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:yuq33pg5", - "threatintel.anomalithreatstream.md5": "e1df8d", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P30902643017/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 826, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "362", - "846" - ], - "threatintel.anomalithreatstream.update_id": 1410682100, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:31:27.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:27.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:31:27.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:27.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 14", + "anomali.threatstream.id": "1145199430", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:qc6c9qt", + "anomali.threatstream.md5": "9006d07f", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P14842247088/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1793", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "305" + ], + "anomali.threatstream.update_id": "1592676961", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -973,33 +1055,36 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 14", - "threatintel.anomalithreatstream.id": 1145199430, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:qc6c9qt", - "threatintel.anomalithreatstream.md5": "9006d07f", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P14842247088/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1793, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "305" - ], - "threatintel.anomalithreatstream.update_id": 1592676961, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.first_seen": "2020-10-09T18:31:29.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:29.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:31:29.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:29.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 2, + "anomali.threatstream.detail2": "imported by user 600", + "anomali.threatstream.id": "1726466938", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:t52oo3", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P39735553093/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1965", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "553" + ], + "anomali.threatstream.update_id": "2718905308", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1011,42 +1096,46 @@ "log.offset": 12237, "service.type": "threatintel", "tags": [ + "forwarded", "g1wn0g", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 2, - "threatintel.anomalithreatstream.detail2": "imported by user 600", - "threatintel.anomalithreatstream.id": 1726466938, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:t52oo3", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P39735553093/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1965, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "553" - ], - "threatintel.anomalithreatstream.update_id": 2718905308, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 0, - "threatintel.indicator.first_seen": "2020-10-09T18:31:34.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.229", - "threatintel.indicator.last_seen": "2020-10-09T18:31:34.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:31:34.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.229", + "threat.indicator.last_seen": "2020-10-09T18:31:34.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "faahk3drf.example.net", - "threatintel.indicator.url.full": "http://faahk3drf.example.net/julf98x5/0g1t8f?cbffxs2qv=vwgz", - "threatintel.indicator.url.original": "http://faahk3drf.example.net/julf98x5/0g1t8f?cbffxs2qv=vwgz", - "threatintel.indicator.url.path": "/julf98x5/0g1t8f", - "threatintel.indicator.url.query": "cbffxs2qv=vwgz", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "faahk3drf.example.net", + "threat.indicator.url.full": "http://faahk3drf.example.net/julf98x5/0g1t8f?cbffxs2qv=vwgz", + "threat.indicator.url.original": "http://faahk3drf.example.net/julf98x5/0g1t8f?cbffxs2qv=vwgz", + "threat.indicator.url.path": "/julf98x5/0g1t8f", + "threat.indicator.url.query": "cbffxs2qv=vwgz", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 71, + "anomali.threatstream.detail2": "imported by user 976", + "anomali.threatstream.id": "1457264389", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:nx1qwwprl", + "anomali.threatstream.md5": "f5d", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P20794801988/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1437", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "866" + ], + "anomali.threatstream.update_id": "2310970191", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1059,35 +1148,40 @@ "service.type": "threatintel", "tags": [ "6rblg", + "forwarded", "pzs4xlqy", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 71, - "threatintel.anomalithreatstream.detail2": "imported by user 976", - "threatintel.anomalithreatstream.id": 1457264389, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:nx1qwwprl", - "threatintel.anomalithreatstream.md5": "f5d", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P20794801988/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1437, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "866" - ], - "threatintel.anomalithreatstream.update_id": 2310970191, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:31:36.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:36.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:31:36.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:36.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 70, + "anomali.threatstream.detail2": "imported by user 761", + "anomali.threatstream.id": "3532094043", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:k1y", + "anomali.threatstream.md5": "cfd9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P48760414603/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2198", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "68", + "70", + "789" + ], + "anomali.threatstream.update_id": "1487534287", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1100,36 +1194,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 70, - "threatintel.anomalithreatstream.detail2": "imported by user 761", - "threatintel.anomalithreatstream.id": 3532094043, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:k1y", - "threatintel.anomalithreatstream.md5": "cfd9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P48760414603/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2198, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "68", - "70", - "789" - ], - "threatintel.anomalithreatstream.update_id": 1487534287, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:31:39.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:39.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:31:39.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:39.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 23, + "anomali.threatstream.detail2": "imported by user 680", + "anomali.threatstream.id": "1753194968", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:ixlyb", + "anomali.threatstream.md5": "93daa", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P36997562731/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "2101", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "15" + ], + "anomali.threatstream.update_id": "1772862647", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1142,35 +1237,38 @@ "service.type": "threatintel", "tags": [ "6rw", + "forwarded", "g80r1d4sj", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 23, - "threatintel.anomalithreatstream.detail2": "imported by user 680", - "threatintel.anomalithreatstream.id": 1753194968, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:ixlyb", - "threatintel.anomalithreatstream.md5": "93daa", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P36997562731/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 2101, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "15" - ], - "threatintel.anomalithreatstream.update_id": 1772862647, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:31:43.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:31:43.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:31:43.000Z", + "threat.indicator.last_seen": "2020-10-09T18:31:43.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 0, + "anomali.threatstream.detail2": "imported by user 820", + "anomali.threatstream.id": "3285278133", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:1u76t", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P45121980169/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1152", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "390", + "7" + ], + "anomali.threatstream.update_id": "2657969647", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1183,36 +1281,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 0, - "threatintel.anomalithreatstream.detail2": "imported by user 820", - "threatintel.anomalithreatstream.id": 3285278133, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:1u76t", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P45121980169/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1152, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "390", - "7" - ], - "threatintel.anomalithreatstream.update_id": 2657969647, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 0, - "threatintel.indicator.first_seen": "2020-10-09T18:31:49.000Z", - "threatintel.indicator.geo.country_iso_code": "DE", - "threatintel.indicator.ip": "192.0.2.219", - "threatintel.indicator.last_seen": "2020-10-09T18:31:49.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:31:49.000Z", + "threat.indicator.geo.country_iso_code": "DE", + "threat.indicator.ip": "192.0.2.219", + "threat.indicator.last_seen": "2020-10-09T18:31:49.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 45, + "anomali.threatstream.detail2": "imported by user 894", + "anomali.threatstream.id": "2098390184", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:hc-wh", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P33231447204/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "3354", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "846" + ], + "anomali.threatstream.update_id": "2110937414", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1224,42 +1324,46 @@ "log.offset": 14812, "service.type": "threatintel", "tags": [ + "forwarded", "om0z7", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 45, - "threatintel.anomalithreatstream.detail2": "imported by user 894", - "threatintel.anomalithreatstream.id": 2098390184, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:hc-wh", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P33231447204/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 3354, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "846" - ], - "threatintel.anomalithreatstream.update_id": 2110937414, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:31:49.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.208", - "threatintel.indicator.last_seen": "2020-10-09T18:31:49.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:31:49.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.208", + "threat.indicator.last_seen": "2020-10-09T18:31:49.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "p9okf0.example.org", - "threatintel.indicator.url.full": "http://p9okf0.example.org/jyb3n8f/f55vfyt48?s2n=0t2d", - "threatintel.indicator.url.original": "http://p9okf0.example.org/jyb3n8f/f55vfyt48?s2n=0t2d", - "threatintel.indicator.url.path": "/jyb3n8f/f55vfyt48", - "threatintel.indicator.url.query": "s2n=0t2d", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "p9okf0.example.org", + "threat.indicator.url.full": "http://p9okf0.example.org/jyb3n8f/f55vfyt48?s2n=0t2d", + "threat.indicator.url.original": "http://p9okf0.example.org/jyb3n8f/f55vfyt48?s2n=0t2d", + "threat.indicator.url.path": "/jyb3n8f/f55vfyt48", + "threat.indicator.url.query": "s2n=0t2d", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 34, + "anomali.threatstream.detail2": "imported by user 747", + "anomali.threatstream.id": "3367490507", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:0ua9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P34959401147/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "959", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "404", + "574" + ], + "anomali.threatstream.update_id": "2335801340", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1272,42 +1376,47 @@ "service.type": "threatintel", "tags": [ "adeba89", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 34, - "threatintel.anomalithreatstream.detail2": "imported by user 747", - "threatintel.anomalithreatstream.id": 3367490507, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:0ua9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P34959401147/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 959, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "404", - "574" - ], - "threatintel.anomalithreatstream.update_id": 2335801340, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:31:58.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.105", - "threatintel.indicator.last_seen": "2020-10-09T18:31:58.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:31:58.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.105", + "threat.indicator.last_seen": "2020-10-09T18:31:58.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "fxkeo24m.example.com", - "threatintel.indicator.url.full": "https://fxkeo24m.example.com/y75tg7sw/jnnu9xmc?apus=ob1hnba4", - "threatintel.indicator.url.original": "https://fxkeo24m.example.com/y75tg7sw/jnnu9xmc?apus=ob1hnba4", - "threatintel.indicator.url.path": "/y75tg7sw/jnnu9xmc", - "threatintel.indicator.url.query": "apus=ob1hnba4", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "fxkeo24m.example.com", + "threat.indicator.url.full": "https://fxkeo24m.example.com/y75tg7sw/jnnu9xmc?apus=ob1hnba4", + "threat.indicator.url.original": "https://fxkeo24m.example.com/y75tg7sw/jnnu9xmc?apus=ob1hnba4", + "threat.indicator.url.path": "/y75tg7sw/jnnu9xmc", + "threat.indicator.url.query": "apus=ob1hnba4", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 14, + "anomali.threatstream.detail2": "imported by user 604", + "anomali.threatstream.id": "1998649659", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:s0anj", + "anomali.threatstream.md5": "b4dd5cf7", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P21831217400/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1405", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "422", + "749", + "852" + ], + "anomali.threatstream.update_id": "1339527388", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1320,36 +1429,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 14, - "threatintel.anomalithreatstream.detail2": "imported by user 604", - "threatintel.anomalithreatstream.id": 1998649659, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:s0anj", - "threatintel.anomalithreatstream.md5": "b4dd5cf7", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P21831217400/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1405, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "422", - "749", - "852" - ], - "threatintel.anomalithreatstream.update_id": 1339527388, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:32:02.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:02.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:32:02.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:02.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 85, + "anomali.threatstream.detail2": "imported by user 386", + "anomali.threatstream.id": "3005939184", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:hn5uajghq", + "anomali.threatstream.md5": "b890cdad", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P23229581043/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "652", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "120" + ], + "anomali.threatstream.update_id": "1316735853", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1362,35 +1472,40 @@ "service.type": "threatintel", "tags": [ "a-e8lz", + "forwarded", "nj3f", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 85, - "threatintel.anomalithreatstream.detail2": "imported by user 386", - "threatintel.anomalithreatstream.id": 3005939184, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:hn5uajghq", - "threatintel.anomalithreatstream.md5": "b890cdad", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P23229581043/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 652, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "120" - ], - "threatintel.anomalithreatstream.update_id": 1316735853, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:32:03.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:03.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:32:03.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:03.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 31, + "anomali.threatstream.detail2": "imported by user 706", + "anomali.threatstream.id": "1900495748", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:3taf", + "anomali.threatstream.md5": "817", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P35660572297/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "506", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "718", + "828", + "98" + ], + "anomali.threatstream.update_id": "3243777736", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1403,36 +1518,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 31, - "threatintel.anomalithreatstream.detail2": "imported by user 706", - "threatintel.anomalithreatstream.id": 1900495748, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:3taf", - "threatintel.anomalithreatstream.md5": "817", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P35660572297/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 506, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "718", - "828", - "98" - ], - "threatintel.anomalithreatstream.update_id": 3243777736, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:32:04.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:04.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:32:04.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:04.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 50, + "anomali.threatstream.detail2": "imported by user 222", + "anomali.threatstream.id": "1040883425", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:wsge", + "anomali.threatstream.md5": "a06b", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P33297645928/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "146", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "539", + "959" + ], + "anomali.threatstream.update_id": "1284922297", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1445,35 +1562,39 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 50, - "threatintel.anomalithreatstream.detail2": "imported by user 222", - "threatintel.anomalithreatstream.id": 1040883425, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:wsge", - "threatintel.anomalithreatstream.md5": "a06b", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P33297645928/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 146, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "539", - "959" - ], - "threatintel.anomalithreatstream.update_id": 1284922297, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:32:08.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:08.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:32:08.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:08.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 50, + "anomali.threatstream.detail2": "imported by user 414", + "anomali.threatstream.id": "1703603090", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:yid8n1", + "anomali.threatstream.md5": "ebd6108", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P25381157923/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "294", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "124", + "394", + "820" + ], + "anomali.threatstream.update_id": "1405107391", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1486,36 +1607,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 50, - "threatintel.anomalithreatstream.detail2": "imported by user 414", - "threatintel.anomalithreatstream.id": 1703603090, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:yid8n1", - "threatintel.anomalithreatstream.md5": "ebd6108", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P25381157923/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 294, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "124", - "394", - "820" - ], - "threatintel.anomalithreatstream.update_id": 1405107391, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:32:11.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:11.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:32:11.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:11.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 6, + "anomali.threatstream.detail2": "imported by user 872", + "anomali.threatstream.id": "1393798645", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:aeu2f0", + "anomali.threatstream.md5": "5afe0a", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P34100122259/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1256", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "386", + "980" + ], + "anomali.threatstream.update_id": "2194495180", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1528,35 +1651,36 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 6, - "threatintel.anomalithreatstream.detail2": "imported by user 872", - "threatintel.anomalithreatstream.id": 1393798645, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:aeu2f0", - "threatintel.anomalithreatstream.md5": "5afe0a", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P34100122259/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1256, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "386", - "980" - ], - "threatintel.anomalithreatstream.update_id": 2194495180, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:32:19.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:19.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:32:19.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:19.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 46, + "anomali.threatstream.detail2": "imported by user 237", + "anomali.threatstream.id": "3384379889", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:w3rx", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P38445847685/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "773", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "830" + ], + "anomali.threatstream.update_id": "2280522298", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1569,35 +1693,40 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 46, - "threatintel.anomalithreatstream.detail2": "imported by user 237", - "threatintel.anomalithreatstream.id": 3384379889, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:w3rx", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P38445847685/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 773, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "830" - ], - "threatintel.anomalithreatstream.update_id": 2280522298, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:32:30.000Z", - "threatintel.indicator.geo.country_iso_code": "CN", - "threatintel.indicator.ip": "2001:db8:b94f:43d3:f1ef:8964:c8e3:48d4", - "threatintel.indicator.last_seen": "2020-10-09T18:32:30.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:32:30.000Z", + "threat.indicator.geo.country_iso_code": "CN", + "threat.indicator.ip": "2001:db8:b94f:43d3:f1ef:8964:c8e3:48d4", + "threat.indicator.last_seen": "2020-10-09T18:32:30.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv6-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv6-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 60, + "anomali.threatstream.detail2": "imported by user 317", + "anomali.threatstream.id": "1291701932", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:upf65oc8", + "anomali.threatstream.md5": "758a81", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P40886917073/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2980", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "407", + "437" + ], + "anomali.threatstream.update_id": "1128332354", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1610,35 +1739,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 60, - "threatintel.anomalithreatstream.detail2": "imported by user 317", - "threatintel.anomalithreatstream.id": 1291701932, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:upf65oc8", - "threatintel.anomalithreatstream.md5": "758a81", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P40886917073/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2980, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "407", - "437" - ], - "threatintel.anomalithreatstream.update_id": 1128332354, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:32:35.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:32:35.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:32:35.000Z", + "threat.indicator.last_seen": "2020-10-09T18:32:35.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 352", + "anomali.threatstream.id": "3279148213", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:u0e", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P37449871811/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "2315", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "29", + "817", + "831" + ], + "anomali.threatstream.update_id": "2267992225", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1650,43 +1782,47 @@ "log.offset": 19948, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream", "ziqdk" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 352", - "threatintel.anomalithreatstream.id": 3279148213, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:u0e", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P37449871811/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 2315, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "29", - "817", - "831" - ], - "threatintel.anomalithreatstream.update_id": 2267992225, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.first_seen": "2020-10-09T18:33:10.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.16", - "threatintel.indicator.last_seen": "2020-10-09T18:33:10.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:33:10.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.16", + "threat.indicator.last_seen": "2020-10-09T18:33:10.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ke4ffyj5.example.com", - "threatintel.indicator.url.full": "http://ke4ffyj5.example.com/t-9ikyrtt/ai91?s6u=3y1", - "threatintel.indicator.url.original": "http://ke4ffyj5.example.com/t-9ikyrtt/ai91?s6u=3y1", - "threatintel.indicator.url.path": "/t-9ikyrtt/ai91", - "threatintel.indicator.url.query": "s6u=3y1", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ke4ffyj5.example.com", + "threat.indicator.url.full": "http://ke4ffyj5.example.com/t-9ikyrtt/ai91?s6u=3y1", + "threat.indicator.url.original": "http://ke4ffyj5.example.com/t-9ikyrtt/ai91?s6u=3y1", + "threat.indicator.url.path": "/t-9ikyrtt/ai91", + "threat.indicator.url.query": "s6u=3y1", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 42, + "anomali.threatstream.detail2": "imported by user 768", + "anomali.threatstream.id": "2138145846", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:-shiotjs", + "anomali.threatstream.md5": "c9b4", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P24530928152/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "837", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "322", + "410" + ], + "anomali.threatstream.update_id": "3812327380", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1699,35 +1835,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 42, - "threatintel.anomalithreatstream.detail2": "imported by user 768", - "threatintel.anomalithreatstream.id": 2138145846, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:-shiotjs", - "threatintel.anomalithreatstream.md5": "c9b4", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P24530928152/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 837, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "322", - "410" - ], - "threatintel.anomalithreatstream.update_id": 3812327380, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 4, - "threatintel.indicator.first_seen": "2020-10-09T18:33:13.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:13.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:13.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:13.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 25, + "anomali.threatstream.detail2": "imported by user 148", + "anomali.threatstream.id": "1502954738", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:c8f0r5d4", + "anomali.threatstream.md5": "ad0", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P43216360516/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3786", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "520", + "695" + ], + "anomali.threatstream.update_id": "2085432040", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1740,35 +1879,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 25, - "threatintel.anomalithreatstream.detail2": "imported by user 148", - "threatintel.anomalithreatstream.id": 1502954738, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:c8f0r5d4", - "threatintel.anomalithreatstream.md5": "ad0", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P43216360516/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3786, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "520", - "695" - ], - "threatintel.anomalithreatstream.update_id": 2085432040, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:33:14.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:14.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:33:14.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:14.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 56, + "anomali.threatstream.detail2": "imported by user 649", + "anomali.threatstream.id": "2730182815", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:2vsd1miq", + "anomali.threatstream.md5": "571957", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P23842171060/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2923", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "127" + ], + "anomali.threatstream.update_id": "3768246717", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1781,34 +1922,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 56, - "threatintel.anomalithreatstream.detail2": "imported by user 649", - "threatintel.anomalithreatstream.id": 2730182815, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:2vsd1miq", - "threatintel.anomalithreatstream.md5": "571957", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P23842171060/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2923, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "127" - ], - "threatintel.anomalithreatstream.update_id": 3768246717, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:33:14.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:14.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:14.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:14.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 132", + "anomali.threatstream.id": "1649793681", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:d1q-sdovn", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P13727067406/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1993", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "176", + "715", + "824" + ], + "anomali.threatstream.update_id": "3498000116", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1821,42 +1966,45 @@ "service.type": "threatintel", "tags": [ "73d", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 132", - "threatintel.anomalithreatstream.id": 1649793681, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:d1q-sdovn", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P13727067406/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1993, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "176", - "715", - "824" - ], - "threatintel.anomalithreatstream.update_id": 3498000116, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.first_seen": "2020-10-09T18:33:22.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.154", - "threatintel.indicator.last_seen": "2020-10-09T18:33:22.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:33:22.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.154", + "threat.indicator.last_seen": "2020-10-09T18:33:22.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "rl27d.example.net", - "threatintel.indicator.url.full": "https://rl27d.example.net/ko6/4rtt?b12=o4mgzz2kk", - "threatintel.indicator.url.original": "https://rl27d.example.net/ko6/4rtt?b12=o4mgzz2kk", - "threatintel.indicator.url.path": "/ko6/4rtt", - "threatintel.indicator.url.query": "b12=o4mgzz2kk", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "rl27d.example.net", + "threat.indicator.url.full": "https://rl27d.example.net/ko6/4rtt?b12=o4mgzz2kk", + "threat.indicator.url.original": "https://rl27d.example.net/ko6/4rtt?b12=o4mgzz2kk", + "threat.indicator.url.path": "/ko6/4rtt", + "threat.indicator.url.query": "b12=o4mgzz2kk", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 48, + "anomali.threatstream.detail2": "imported by user 137", + "anomali.threatstream.id": "2195098028", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:886x", + "anomali.threatstream.md5": "7f4", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P39956518309/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1936", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "469" + ], + "anomali.threatstream.update_id": "1238197737", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1869,35 +2017,38 @@ "service.type": "threatintel", "tags": [ "e3mm2h", + "forwarded", "knjq-wt", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 48, - "threatintel.anomalithreatstream.detail2": "imported by user 137", - "threatintel.anomalithreatstream.id": 2195098028, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:886x", - "threatintel.anomalithreatstream.md5": "7f4", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P39956518309/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1936, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "469" - ], - "threatintel.anomalithreatstream.update_id": 1238197737, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:33:24.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:24.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:24.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:24.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 62, + "anomali.threatstream.detail2": "imported by user 76", + "anomali.threatstream.id": "2273277634", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:eem8vy0", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P28216636081/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2583", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "143", + "22" + ], + "anomali.threatstream.update_id": "3547953290", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1909,43 +2060,45 @@ "log.offset": 23077, "service.type": "threatintel", "tags": [ + "forwarded", "rb2my5u7", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 62, - "threatintel.anomalithreatstream.detail2": "imported by user 76", - "threatintel.anomalithreatstream.id": 2273277634, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:eem8vy0", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P28216636081/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2583, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "143", - "22" - ], - "threatintel.anomalithreatstream.update_id": 3547953290, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:33:26.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.228", - "threatintel.indicator.last_seen": "2020-10-09T18:33:26.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:26.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.228", + "threat.indicator.last_seen": "2020-10-09T18:33:26.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "6ygk0y.example.com", - "threatintel.indicator.url.full": "http://6ygk0y.example.com/t520/4twe?ql4bhkpop=yfpkef", - "threatintel.indicator.url.original": "http://6ygk0y.example.com/t520/4twe?ql4bhkpop=yfpkef", - "threatintel.indicator.url.path": "/t520/4twe", - "threatintel.indicator.url.query": "ql4bhkpop=yfpkef", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "6ygk0y.example.com", + "threat.indicator.url.full": "http://6ygk0y.example.com/t520/4twe?ql4bhkpop=yfpkef", + "threat.indicator.url.original": "http://6ygk0y.example.com/t520/4twe?ql4bhkpop=yfpkef", + "threat.indicator.url.path": "/t520/4twe", + "threat.indicator.url.query": "ql4bhkpop=yfpkef", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 47, + "anomali.threatstream.detail2": "imported by user 304", + "anomali.threatstream.id": "1593951372", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:lrfqa", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P18416887501/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1922", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "281" + ], + "anomali.threatstream.update_id": "3726618139", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -1958,41 +2111,47 @@ "service.type": "threatintel", "tags": [ "3jujb6j", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 47, - "threatintel.anomalithreatstream.detail2": "imported by user 304", - "threatintel.anomalithreatstream.id": 1593951372, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:lrfqa", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P18416887501/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1922, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "281" - ], - "threatintel.anomalithreatstream.update_id": 3726618139, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:33:27.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.38", - "threatintel.indicator.last_seen": "2020-10-09T18:33:27.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:27.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.38", + "threat.indicator.last_seen": "2020-10-09T18:33:27.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "rcsr9o.example.net", - "threatintel.indicator.url.full": "http://rcsr9o.example.net/e6f/08b?8d2y=d-42fr-", - "threatintel.indicator.url.original": "http://rcsr9o.example.net/e6f/08b?8d2y=d-42fr-", - "threatintel.indicator.url.path": "/e6f/08b", - "threatintel.indicator.url.query": "8d2y=d-42fr-", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "rcsr9o.example.net", + "threat.indicator.url.full": "http://rcsr9o.example.net/e6f/08b?8d2y=d-42fr-", + "threat.indicator.url.original": "http://rcsr9o.example.net/e6f/08b?8d2y=d-42fr-", + "threat.indicator.url.path": "/e6f/08b", + "threat.indicator.url.query": "8d2y=d-42fr-", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 578", + "anomali.threatstream.id": "2881597176", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:wpo", + "anomali.threatstream.md5": "89a0a684", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P37162617510/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1312", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "450", + "588", + "873" + ], + "anomali.threatstream.update_id": "2444963851", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2006,35 +2165,39 @@ "tags": [ "2uu9b", "f7ciq9", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 578", - "threatintel.anomalithreatstream.id": 2881597176, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:wpo", - "threatintel.anomalithreatstream.md5": "89a0a684", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P37162617510/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1312, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "450", - "588", - "873" - ], - "threatintel.anomalithreatstream.update_id": 2444963851, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.first_seen": "2020-10-09T18:33:29.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:29.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:33:29.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:29.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 51, + "anomali.threatstream.detail2": "imported by user 347", + "anomali.threatstream.id": "1789877636", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:f7l", + "anomali.threatstream.md5": "a41f", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P15884312830/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1250", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "299", + "501", + "551" + ], + "anomali.threatstream.update_id": "3210446946", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2047,36 +2210,39 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 51, - "threatintel.anomalithreatstream.detail2": "imported by user 347", - "threatintel.anomalithreatstream.id": 1789877636, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:f7l", - "threatintel.anomalithreatstream.md5": "a41f", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P15884312830/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1250, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "299", - "501", - "551" - ], - "threatintel.anomalithreatstream.update_id": 3210446946, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:33:43.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:43.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:43.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:43.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 56, + "anomali.threatstream.detail2": "imported by user 182", + "anomali.threatstream.id": "1300434967", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:5kjd", + "anomali.threatstream.md5": "d0f5f32", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P44427200974/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1603", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "122", + "460", + "615" + ], + "anomali.threatstream.update_id": "2994196701", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2089,37 +2255,38 @@ "service.type": "threatintel", "tags": [ "f5c6pl", + "forwarded", "kpjt", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 56, - "threatintel.anomalithreatstream.detail2": "imported by user 182", - "threatintel.anomalithreatstream.id": 1300434967, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:5kjd", - "threatintel.anomalithreatstream.md5": "d0f5f32", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P44427200974/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1603, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "122", - "460", - "615" - ], - "threatintel.anomalithreatstream.update_id": 2994196701, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:33:45.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:45.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:45.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:45.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 79, + "anomali.threatstream.detail2": "imported by user 976", + "anomali.threatstream.id": "2448066635", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:7x9cgytj", + "anomali.threatstream.md5": "4f984375b", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P15169037907/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "814", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "804" + ], + "anomali.threatstream.update_id": "2396481494", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2132,34 +2299,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 79, - "threatintel.anomalithreatstream.detail2": "imported by user 976", - "threatintel.anomalithreatstream.id": 2448066635, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:7x9cgytj", - "threatintel.anomalithreatstream.md5": "4f984375b", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P15169037907/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 814, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "804" - ], - "threatintel.anomalithreatstream.update_id": 2396481494, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2020-10-09T18:33:45.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:45.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:33:45.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:45.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 15, + "anomali.threatstream.detail2": "imported by user 408", + "anomali.threatstream.id": "1693329110", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:1l5tib0", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P46598563676/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3431", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "301", + "374" + ], + "anomali.threatstream.update_id": "1425004305", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2172,42 +2342,47 @@ "service.type": "threatintel", "tags": [ "5w8i", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 15, - "threatintel.anomalithreatstream.detail2": "imported by user 408", - "threatintel.anomalithreatstream.id": 1693329110, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:1l5tib0", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P46598563676/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3431, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "301", - "374" - ], - "threatintel.anomalithreatstream.update_id": 1425004305, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:33:48.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.115", - "threatintel.indicator.last_seen": "2020-10-09T18:33:48.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:33:48.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.115", + "threat.indicator.last_seen": "2020-10-09T18:33:48.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cc7d.example.com", - "threatintel.indicator.url.full": "https://cc7d.example.com/kxxwobg/hd6omn?tr8=essb", - "threatintel.indicator.url.original": "https://cc7d.example.com/kxxwobg/hd6omn?tr8=essb", - "threatintel.indicator.url.path": "/kxxwobg/hd6omn", - "threatintel.indicator.url.query": "tr8=essb", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cc7d.example.com", + "threat.indicator.url.full": "https://cc7d.example.com/kxxwobg/hd6omn?tr8=essb", + "threat.indicator.url.original": "https://cc7d.example.com/kxxwobg/hd6omn?tr8=essb", + "threat.indicator.url.path": "/kxxwobg/hd6omn", + "threat.indicator.url.query": "tr8=essb", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 35, + "anomali.threatstream.detail2": "imported by user 843", + "anomali.threatstream.id": "1522150430", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:8-8a", + "anomali.threatstream.md5": "9c67037e6", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P28645937174/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2342", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "27", + "396", + "989" + ], + "anomali.threatstream.update_id": "3573181354", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2220,36 +2395,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 35, - "threatintel.anomalithreatstream.detail2": "imported by user 843", - "threatintel.anomalithreatstream.id": 1522150430, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:8-8a", - "threatintel.anomalithreatstream.md5": "9c67037e6", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P28645937174/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2342, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "27", - "396", - "989" - ], - "threatintel.anomalithreatstream.update_id": 3573181354, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 4, - "threatintel.indicator.first_seen": "2020-10-09T18:33:51.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:33:51.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:33:51.000Z", + "threat.indicator.last_seen": "2020-10-09T18:33:51.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 71, + "anomali.threatstream.detail2": "imported by user 831", + "anomali.threatstream.id": "1760436567", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:vy02k4", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P14276852864/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "271", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "342", + "504" + ], + "anomali.threatstream.update_id": "1253389383", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2262,36 +2438,38 @@ "service.type": "threatintel", "tags": [ "f3ctz7j", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 71, - "threatintel.anomalithreatstream.detail2": "imported by user 831", - "threatintel.anomalithreatstream.id": 1760436567, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:vy02k4", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P14276852864/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 271, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "342", - "504" - ], - "threatintel.anomalithreatstream.update_id": 1253389383, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:33:57.000Z", - "threatintel.indicator.geo.country_iso_code": "VN", - "threatintel.indicator.ip": "192.0.2.61", - "threatintel.indicator.last_seen": "2020-10-09T18:33:57.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:33:57.000Z", + "threat.indicator.geo.country_iso_code": "VN", + "threat.indicator.ip": "192.0.2.61", + "threat.indicator.last_seen": "2020-10-09T18:33:57.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 85, + "anomali.threatstream.detail2": "imported by user 650", + "anomali.threatstream.id": "1925240476", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:2bnikxoma", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P15033658538/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1067", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "51" + ], + "anomali.threatstream.update_id": "1098288836", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2304,35 +2482,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 85, - "threatintel.anomalithreatstream.detail2": "imported by user 650", - "threatintel.anomalithreatstream.id": 1925240476, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:2bnikxoma", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P15033658538/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1067, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "51" - ], - "threatintel.anomalithreatstream.update_id": 1098288836, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.geo.country_iso_code": "DE", - "threatintel.indicator.ip": "192.0.2.233", - "threatintel.indicator.last_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.geo.country_iso_code": "DE", + "threat.indicator.ip": "192.0.2.233", + "threat.indicator.last_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 91, + "anomali.threatstream.detail2": "imported by user 489", + "anomali.threatstream.id": "3001806953", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:ak63t", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P34696300225/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "782", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "484" + ], + "anomali.threatstream.update_id": "2722308334", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2344,42 +2525,45 @@ "log.offset": 28355, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream", "v9ycq" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 91, - "threatintel.anomalithreatstream.detail2": "imported by user 489", - "threatintel.anomalithreatstream.id": 3001806953, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:ak63t", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P34696300225/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 782, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "484" - ], - "threatintel.anomalithreatstream.update_id": 2722308334, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "2001:db8:9850:9607:e204:423b:cade:837e", - "threatintel.indicator.last_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "2001:db8:9850:9607:e204:423b:cade:837e", + "threat.indicator.last_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "v9aqrp81q.example.net", - "threatintel.indicator.url.full": "http://v9aqrp81q.example.net/psuj4bs/rvp?qufy=ymryh", - "threatintel.indicator.url.original": "http://v9aqrp81q.example.net/psuj4bs/rvp?qufy=ymryh", - "threatintel.indicator.url.path": "/psuj4bs/rvp", - "threatintel.indicator.url.query": "qufy=ymryh", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "v9aqrp81q.example.net", + "threat.indicator.url.full": "http://v9aqrp81q.example.net/psuj4bs/rvp?qufy=ymryh", + "threat.indicator.url.original": "http://v9aqrp81q.example.net/psuj4bs/rvp?qufy=ymryh", + "threat.indicator.url.path": "/psuj4bs/rvp", + "threat.indicator.url.query": "qufy=ymryh", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 453", + "anomali.threatstream.id": "3933431319", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:ejrypgr", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P46019487828/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1904", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "444" + ], + "anomali.threatstream.update_id": "3520784497", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2392,34 +2576,40 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 453", - "threatintel.anomalithreatstream.id": 3933431319, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:ejrypgr", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P46019487828/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1904, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "444" - ], - "threatintel.anomalithreatstream.update_id": 3520784497, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.first_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.geo.country_iso_code": "IN", - "threatintel.indicator.ip": "192.0.2.234", - "threatintel.indicator.last_seen": "2020-10-09T18:34:00.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.geo.country_iso_code": "IN", + "threat.indicator.ip": "192.0.2.234", + "threat.indicator.last_seen": "2020-10-09T18:34:00.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 95, + "anomali.threatstream.detail2": "imported by user 722", + "anomali.threatstream.id": "1356788940", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:q4a", + "anomali.threatstream.md5": "a4fa", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P30118085912/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3698", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "743", + "936" + ], + "anomali.threatstream.update_id": "3707298072", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2431,37 +2621,41 @@ "log.offset": 29493, "service.type": "threatintel", "tags": [ + "forwarded", "qxwn7lw", "threatintel-anomalithreatstream", "xva1ki" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 95, - "threatintel.anomalithreatstream.detail2": "imported by user 722", - "threatintel.anomalithreatstream.id": 1356788940, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:q4a", - "threatintel.anomalithreatstream.md5": "a4fa", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P30118085912/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3698, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "743", - "936" - ], - "threatintel.anomalithreatstream.update_id": 3707298072, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 10, - "threatintel.indicator.first_seen": "2020-10-09T18:34:02.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:02.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:02.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:02.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 6, + "anomali.threatstream.detail2": "imported by user 236", + "anomali.threatstream.id": "3804309005", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:2sclqws1s", + "anomali.threatstream.md5": "5e11299", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P14689465586/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "342", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "50", + "642", + "948" + ], + "anomali.threatstream.update_id": "3749914856", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2473,38 +2667,39 @@ "log.offset": 29986, "service.type": "threatintel", "tags": [ + "forwarded", "r81f4", "threatintel-anomalithreatstream", "wwsw" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 6, - "threatintel.anomalithreatstream.detail2": "imported by user 236", - "threatintel.anomalithreatstream.id": 3804309005, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:2sclqws1s", - "threatintel.anomalithreatstream.md5": "5e11299", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P14689465586/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 342, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "50", - "642", - "948" - ], - "threatintel.anomalithreatstream.update_id": 3749914856, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:34:05.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:05.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:05.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:05.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 15, + "anomali.threatstream.detail2": "imported by user 488", + "anomali.threatstream.id": "1022859708", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:9cfecc", + "anomali.threatstream.md5": "22315f8", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P33092174596/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2811", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "1" + ], + "anomali.threatstream.update_id": "1637146862", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2517,34 +2712,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 15, - "threatintel.anomalithreatstream.detail2": "imported by user 488", - "threatintel.anomalithreatstream.id": 1022859708, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:9cfecc", - "threatintel.anomalithreatstream.md5": "22315f8", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P33092174596/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2811, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "1" - ], - "threatintel.anomalithreatstream.update_id": 1637146862, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:34:11.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:11.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:11.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:11.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 54, + "anomali.threatstream.detail2": "imported by user 310", + "anomali.threatstream.id": "1581368214", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:r7vbej", + "anomali.threatstream.md5": "d4a", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P28408487114/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1371", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "810", + "910" + ], + "anomali.threatstream.update_id": "1671617316", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2557,35 +2756,36 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 54, - "threatintel.anomalithreatstream.detail2": "imported by user 310", - "threatintel.anomalithreatstream.id": 1581368214, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:r7vbej", - "threatintel.anomalithreatstream.md5": "d4a", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P28408487114/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1371, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "810", - "910" - ], - "threatintel.anomalithreatstream.update_id": 1671617316, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:34:12.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:12.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:34:12.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:12.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 376", + "anomali.threatstream.id": "3576055846", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:0qqrz", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P27429039546/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1808", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "660" + ], + "anomali.threatstream.update_id": "2477226249", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2597,41 +2797,48 @@ "log.offset": 31451, "service.type": "threatintel", "tags": [ + "forwarded", "gry2doqf", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 376", - "threatintel.anomalithreatstream.id": 3576055846, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:0qqrz", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P27429039546/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1808, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "660" - ], - "threatintel.anomalithreatstream.update_id": 2477226249, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.first_seen": "2020-10-09T18:34:17.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.83", - "threatintel.indicator.last_seen": "2020-10-09T18:34:17.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:34:17.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.83", + "threat.indicator.last_seen": "2020-10-09T18:34:17.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "o4kqv8b8.example.net", - "threatintel.indicator.url.full": "https://o4kqv8b8.example.net/gm4d-9gt/v2iqt?x65ry67ao=skta9rp", - "threatintel.indicator.url.original": "https://o4kqv8b8.example.net/gm4d-9gt/v2iqt?x65ry67ao=skta9rp", - "threatintel.indicator.url.path": "/gm4d-9gt/v2iqt", - "threatintel.indicator.url.query": "x65ry67ao=skta9rp", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "o4kqv8b8.example.net", + "threat.indicator.url.full": "https://o4kqv8b8.example.net/gm4d-9gt/v2iqt?x65ry67ao=skta9rp", + "threat.indicator.url.original": "https://o4kqv8b8.example.net/gm4d-9gt/v2iqt?x65ry67ao=skta9rp", + "threat.indicator.url.path": "/gm4d-9gt/v2iqt", + "threat.indicator.url.query": "x65ry67ao=skta9rp", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 89, + "anomali.threatstream.detail2": "imported by user 748", + "anomali.threatstream.id": "1315247197", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:r38g5hbgx", + "anomali.threatstream.md5": "3eac", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P15092591036/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "206", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "19", + "6", + "954" + ], + "anomali.threatstream.update_id": "1760504719", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2644,37 +2851,39 @@ "service.type": "threatintel", "tags": [ "1l9tule2", + "forwarded", "k6p", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 89, - "threatintel.anomalithreatstream.detail2": "imported by user 748", - "threatintel.anomalithreatstream.id": 1315247197, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:r38g5hbgx", - "threatintel.anomalithreatstream.md5": "3eac", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P15092591036/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 206, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "19", - "6", - "954" - ], - "threatintel.anomalithreatstream.update_id": 1760504719, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:34:20.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:20.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:20.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:20.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 25, + "anomali.threatstream.detail2": "imported by user 380", + "anomali.threatstream.id": "1562423716", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:882dlx", + "anomali.threatstream.md5": "59893613", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P35184012550/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3446", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "392", + "581" + ], + "anomali.threatstream.update_id": "2530088908", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2687,36 +2896,40 @@ "service.type": "threatintel", "tags": [ "d9qquxe", + "forwarded", "threatintel-anomalithreatstream", "ulx" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 25, - "threatintel.anomalithreatstream.detail2": "imported by user 380", - "threatintel.anomalithreatstream.id": 1562423716, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:882dlx", - "threatintel.anomalithreatstream.md5": "59893613", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P35184012550/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3446, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "392", - "581" - ], - "threatintel.anomalithreatstream.update_id": 2530088908, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:34:20.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:20.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:20.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:20.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 4, + "anomali.threatstream.detail2": "imported by user 423", + "anomali.threatstream.id": "1470897088", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:rwo6s", + "anomali.threatstream.md5": "5facf1f", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P10368659748/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "599", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "591", + "663", + "848" + ], + "anomali.threatstream.update_id": "1937893007", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2728,38 +2941,39 @@ "log.offset": 33043, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream", "wsu7l1", "zrb" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 4, - "threatintel.anomalithreatstream.detail2": "imported by user 423", - "threatintel.anomalithreatstream.id": 1470897088, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:rwo6s", - "threatintel.anomalithreatstream.md5": "5facf1f", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P10368659748/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 599, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "591", - "663", - "848" - ], - "threatintel.anomalithreatstream.update_id": 1937893007, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 0, - "threatintel.indicator.first_seen": "2020-10-09T18:34:32.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:32.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:32.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:32.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 9, + "anomali.threatstream.detail2": "imported by user 983", + "anomali.threatstream.id": "1205553827", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:-pbnrmv", + "anomali.threatstream.md5": "708b2c", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P41514908414/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3751", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "299" + ], + "anomali.threatstream.update_id": "3858315866", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2772,34 +2986,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 9, - "threatintel.anomalithreatstream.detail2": "imported by user 983", - "threatintel.anomalithreatstream.id": 1205553827, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:-pbnrmv", - "threatintel.anomalithreatstream.md5": "708b2c", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P41514908414/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3751, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "299" - ], - "threatintel.anomalithreatstream.update_id": 3858315866, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2020-10-09T18:34:32.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:32.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:32.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:32.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 314", + "anomali.threatstream.id": "1744295971", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:uqw", + "anomali.threatstream.md5": "0df", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P36955243007/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "2305", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "556" + ], + "anomali.threatstream.update_id": "2655715062", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2812,33 +3029,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 314", - "threatintel.anomalithreatstream.id": 1744295971, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:uqw", - "threatintel.anomalithreatstream.md5": "0df", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P36955243007/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 2305, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "556" - ], - "threatintel.anomalithreatstream.update_id": 2655715062, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.first_seen": "2020-10-09T18:34:39.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:39.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:34:39.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:39.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 45, + "anomali.threatstream.detail2": "imported by user 986", + "anomali.threatstream.id": "1782793990", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:mkctzuaaf", + "anomali.threatstream.md5": "770", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P41751433270/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "3513", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "445" + ], + "anomali.threatstream.update_id": "2172945223", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2850,36 +3071,38 @@ "log.offset": 34489, "service.type": "threatintel", "tags": [ + "forwarded", "ps2", "qr2wno4", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 45, - "threatintel.anomalithreatstream.detail2": "imported by user 986", - "threatintel.anomalithreatstream.id": 1782793990, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:mkctzuaaf", - "threatintel.anomalithreatstream.md5": "770", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P41751433270/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 3513, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "445" - ], - "threatintel.anomalithreatstream.update_id": 2172945223, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:34:40.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:40.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:34:40.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:40.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 98, + "anomali.threatstream.detail2": "imported by user 615", + "anomali.threatstream.id": "1130190904", + "anomali.threatstream.itype": "scan_ip", + "anomali.threatstream.maltype": "malware:3zu2d2", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P13755730530/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1192", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "88" + ], + "anomali.threatstream.update_id": "1575621349", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2892,35 +3115,39 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 98, - "threatintel.anomalithreatstream.detail2": "imported by user 615", - "threatintel.anomalithreatstream.id": 1130190904, - "threatintel.anomalithreatstream.itype": "scan_ip", - "threatintel.anomalithreatstream.maltype": "malware:3zu2d2", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P13755730530/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1192, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "88" - ], - "threatintel.anomalithreatstream.update_id": 1575621349, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 10, - "threatintel.indicator.first_seen": "2020-10-09T18:34:41.000Z", - "threatintel.indicator.geo.country_iso_code": "VN", - "threatintel.indicator.ip": "192.0.2.88", - "threatintel.indicator.last_seen": "2020-10-09T18:34:41.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:41.000Z", + "threat.indicator.geo.country_iso_code": "VN", + "threat.indicator.ip": "192.0.2.88", + "threat.indicator.last_seen": "2020-10-09T18:34:41.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 17, + "anomali.threatstream.detail2": "imported by user 202", + "anomali.threatstream.id": "2499059829", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:86-jrf6o", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P43937262060/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "852", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "308", + "949" + ], + "anomali.threatstream.update_id": "2450069481", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2933,42 +3160,45 @@ "service.type": "threatintel", "tags": [ "ao6", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 17, - "threatintel.anomalithreatstream.detail2": "imported by user 202", - "threatintel.anomalithreatstream.id": 2499059829, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:86-jrf6o", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P43937262060/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 852, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "308", - "949" - ], - "threatintel.anomalithreatstream.update_id": 2450069481, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:34:43.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.111", - "threatintel.indicator.last_seen": "2020-10-09T18:34:43.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:43.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.111", + "threat.indicator.last_seen": "2020-10-09T18:34:43.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "91p0p.example.com", - "threatintel.indicator.url.full": "https://91p0p.example.com/easx3j6iy/xvnchuoa?dvkljl=h21", - "threatintel.indicator.url.original": "https://91p0p.example.com/easx3j6iy/xvnchuoa?dvkljl=h21", - "threatintel.indicator.url.path": "/easx3j6iy/xvnchuoa", - "threatintel.indicator.url.query": "dvkljl=h21", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "91p0p.example.com", + "threat.indicator.url.full": "https://91p0p.example.com/easx3j6iy/xvnchuoa?dvkljl=h21", + "threat.indicator.url.original": "https://91p0p.example.com/easx3j6iy/xvnchuoa?dvkljl=h21", + "threat.indicator.url.path": "/easx3j6iy/xvnchuoa", + "threat.indicator.url.query": "dvkljl=h21", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 67, + "anomali.threatstream.detail2": "imported by user 421", + "anomali.threatstream.id": "2799251412", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:91o2", + "anomali.threatstream.md5": "f9edba87a", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P31632809876/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3756", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "776" + ], + "anomali.threatstream.update_id": "3951093865", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -2981,34 +3211,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 67, - "threatintel.anomalithreatstream.detail2": "imported by user 421", - "threatintel.anomalithreatstream.id": 2799251412, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:91o2", - "threatintel.anomalithreatstream.md5": "f9edba87a", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P31632809876/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3756, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "776" - ], - "threatintel.anomalithreatstream.update_id": 3951093865, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:34:48.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:48.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:34:48.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:48.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 22, + "anomali.threatstream.detail2": "imported by user 807", + "anomali.threatstream.id": "3711409360", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:yakt8pe9r", + "anomali.threatstream.md5": "c3b497", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P37263483140/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3903", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "35" + ], + "anomali.threatstream.update_id": "3046847198", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3021,34 +3254,38 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 22, - "threatintel.anomalithreatstream.detail2": "imported by user 807", - "threatintel.anomalithreatstream.id": 3711409360, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:yakt8pe9r", - "threatintel.anomalithreatstream.md5": "c3b497", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P37263483140/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3903, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "35" - ], - "threatintel.anomalithreatstream.update_id": 3046847198, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:34:53.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:53.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:53.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:53.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 20, + "anomali.threatstream.detail2": "imported by user 298", + "anomali.threatstream.id": "3346530445", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:jfje", + "anomali.threatstream.md5": "ec57713c", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P10248765051/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1239", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "196", + "775" + ], + "anomali.threatstream.update_id": "2946803375", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3061,35 +3298,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 20, - "threatintel.anomalithreatstream.detail2": "imported by user 298", - "threatintel.anomalithreatstream.id": 3346530445, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:jfje", - "threatintel.anomalithreatstream.md5": "ec57713c", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P10248765051/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1239, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "196", - "775" - ], - "threatintel.anomalithreatstream.update_id": 2946803375, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:34:53.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:53.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:34:53.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:53.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": -1, + "anomali.threatstream.detail2": "imported by user 345", + "anomali.threatstream.id": "2804727563", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:c7e", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P11093591971/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2617", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "131", + "793" + ], + "anomali.threatstream.update_id": "1687817836", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3102,41 +3341,45 @@ "service.type": "threatintel", "tags": [ "-g6", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": -1, - "threatintel.anomalithreatstream.detail2": "imported by user 345", - "threatintel.anomalithreatstream.id": 2804727563, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:c7e", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P11093591971/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2617, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "131", - "793" - ], - "threatintel.anomalithreatstream.update_id": 1687817836, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.first_seen": "2020-10-09T18:34:54.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.133", - "threatintel.indicator.last_seen": "2020-10-09T18:34:54.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "None", + "threat.indicator.first_seen": "2020-10-09T18:34:54.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.133", + "threat.indicator.last_seen": "2020-10-09T18:34:54.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "lzr6.example.org", - "threatintel.indicator.url.full": "https://lzr6.example.org/a7og/4vpv?e7k5=wun", - "threatintel.indicator.url.original": "https://lzr6.example.org/a7og/4vpv?e7k5=wun", - "threatintel.indicator.url.path": "/a7og/4vpv", - "threatintel.indicator.url.query": "e7k5=wun", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "lzr6.example.org", + "threat.indicator.url.full": "https://lzr6.example.org/a7og/4vpv?e7k5=wun", + "threat.indicator.url.original": "https://lzr6.example.org/a7og/4vpv?e7k5=wun", + "threat.indicator.url.path": "/a7og/4vpv", + "threat.indicator.url.query": "e7k5=wun", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 84, + "anomali.threatstream.detail2": "imported by user 747", + "anomali.threatstream.id": "2229747614", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:0d7cxf", + "anomali.threatstream.md5": "bde", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P12084157836/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1620", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "30" + ], + "anomali.threatstream.update_id": "2339220849", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3149,34 +3392,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 84, - "threatintel.anomalithreatstream.detail2": "imported by user 747", - "threatintel.anomalithreatstream.id": 2229747614, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:0d7cxf", - "threatintel.anomalithreatstream.md5": "bde", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P12084157836/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1620, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "30" - ], - "threatintel.anomalithreatstream.update_id": 2339220849, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2020-10-09T18:34:55.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:34:55.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:34:55.000Z", + "threat.indicator.last_seen": "2020-10-09T18:34:55.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 54, + "anomali.threatstream.detail2": "imported by user 832", + "anomali.threatstream.id": "2821279948", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:-farvj0e", + "anomali.threatstream.md5": "aa674f5f", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P43981956471/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2038", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "908" + ], + "anomali.threatstream.update_id": "2083515068", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3189,34 +3435,39 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 54, - "threatintel.anomalithreatstream.detail2": "imported by user 832", - "threatintel.anomalithreatstream.id": 2821279948, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:-farvj0e", - "threatintel.anomalithreatstream.md5": "aa674f5f", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P43981956471/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2038, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "908" - ], - "threatintel.anomalithreatstream.update_id": 2083515068, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:35:01.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:35:01.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:35:01.000Z", + "threat.indicator.last_seen": "2020-10-09T18:35:01.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 63, + "anomali.threatstream.detail2": "imported by user 217", + "anomali.threatstream.id": "3118884222", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:23xfw4nyi", + "anomali.threatstream.md5": "48721c98", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P20451120036/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "1492", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "207", + "501", + "993" + ], + "anomali.threatstream.update_id": "3429396478", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3229,36 +3480,36 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 63, - "threatintel.anomalithreatstream.detail2": "imported by user 217", - "threatintel.anomalithreatstream.id": 3118884222, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:23xfw4nyi", - "threatintel.anomalithreatstream.md5": "48721c98", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P20451120036/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 1492, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "207", - "501", - "993" - ], - "threatintel.anomalithreatstream.update_id": 3429396478, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:35:01.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:35:01.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:35:01.000Z", + "threat.indicator.last_seen": "2020-10-09T18:35:01.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 72, + "anomali.threatstream.detail2": "imported by user 402", + "anomali.threatstream.id": "3912225830", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:dto", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P16185398807/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1594", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "439" + ], + "anomali.threatstream.update_id": "3320773285", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3270,42 +3521,46 @@ "log.offset": 39578, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream", "y7d71" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 72, - "threatintel.anomalithreatstream.detail2": "imported by user 402", - "threatintel.anomalithreatstream.id": 3912225830, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:dto", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P16185398807/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1594, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "439" - ], - "threatintel.anomalithreatstream.update_id": 3320773285, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:35:04.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.177", - "threatintel.indicator.last_seen": "2020-10-09T18:35:04.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:35:04.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.177", + "threat.indicator.last_seen": "2020-10-09T18:35:04.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "932.example.com", - "threatintel.indicator.url.full": "http://932.example.com/1xmdjyom/tf3inx1?s6zgr=ajgw", - "threatintel.indicator.url.original": "http://932.example.com/1xmdjyom/tf3inx1?s6zgr=ajgw", - "threatintel.indicator.url.path": "/1xmdjyom/tf3inx1", - "threatintel.indicator.url.query": "s6zgr=ajgw", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "932.example.com", + "threat.indicator.url.full": "http://932.example.com/1xmdjyom/tf3inx1?s6zgr=ajgw", + "threat.indicator.url.original": "http://932.example.com/1xmdjyom/tf3inx1?s6zgr=ajgw", + "threat.indicator.url.path": "/1xmdjyom/tf3inx1", + "threat.indicator.url.query": "s6zgr=ajgw", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 34, + "anomali.threatstream.detail2": "imported by user 626", + "anomali.threatstream.id": "2591984894", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:7nq6far", + "anomali.threatstream.md5": "114bd63e0", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P19612019110/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "1579", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "669" + ], + "anomali.threatstream.update_id": "2275758319", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3317,36 +3572,40 @@ "log.offset": 40161, "service.type": "threatintel", "tags": [ + "forwarded", "hlq", "nknea", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 34, - "threatintel.anomalithreatstream.detail2": "imported by user 626", - "threatintel.anomalithreatstream.id": 2591984894, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:7nq6far", - "threatintel.anomalithreatstream.md5": "114bd63e0", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P19612019110/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 1579, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "669" - ], - "threatintel.anomalithreatstream.update_id": 2275758319, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:35:06.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:35:06.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:35:06.000Z", + "threat.indicator.last_seen": "2020-10-09T18:35:06.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 53, + "anomali.threatstream.detail2": "imported by user 756", + "anomali.threatstream.id": "2589012476", + "anomali.threatstream.itype": "mal_md5", + "anomali.threatstream.maltype": "malware:c1z0qya", + "anomali.threatstream.md5": "636cd4267", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P47658489795/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "3665", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "835", + "850" + ], + "anomali.threatstream.update_id": "2399518196", + "anomali.threatstream.value_type": "md5", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3359,35 +3618,37 @@ "service.type": "threatintel", "tags": [ "", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 53, - "threatintel.anomalithreatstream.detail2": "imported by user 756", - "threatintel.anomalithreatstream.id": 2589012476, - "threatintel.anomalithreatstream.itype": "mal_md5", - "threatintel.anomalithreatstream.maltype": "malware:c1z0qya", - "threatintel.anomalithreatstream.md5": "636cd4267", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P47658489795/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 3665, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "835", - "850" - ], - "threatintel.anomalithreatstream.update_id": 2399518196, - "threatintel.anomalithreatstream.value_type": "md5", - "threatintel.indicator.confidence": 5, - "threatintel.indicator.first_seen": "2020-10-09T18:35:22.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:35:22.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:35:22.000Z", + "threat.indicator.last_seen": "2020-10-09T18:35:22.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "file" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "file" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 57, + "anomali.threatstream.detail2": "imported by user 893", + "anomali.threatstream.id": "2677187012", + "anomali.threatstream.itype": "mal_url", + "anomali.threatstream.maltype": "malware:qtp", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P28161033466/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "3395", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "234", + "909" + ], + "anomali.threatstream.update_id": "3342338979", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3403,44 +3664,48 @@ "5z6", "IP=192.0.2.45", "first_seen=2020-11-24T05:32:17", + "forwarded", "mask=2001:db8:6d86:4a6:af9b:4385:14d6:b714", "popularity=high", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 57, - "threatintel.anomalithreatstream.detail2": "imported by user 893", - "threatintel.anomalithreatstream.id": 2677187012, - "threatintel.anomalithreatstream.itype": "mal_url", - "threatintel.anomalithreatstream.maltype": "malware:qtp", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P28161033466/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 3395, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "234", - "909" - ], - "threatintel.anomalithreatstream.update_id": 3342338979, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:44:01.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.71", - "threatintel.indicator.last_seen": "2020-10-09T18:44:01.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:44:01.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.71", + "threat.indicator.last_seen": "2020-10-09T18:44:01.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "0te9x75e.example.net", - "threatintel.indicator.url.full": "https://0te9x75e.example.net/y2cbl5ov5/u-s9?vhppw120=bt0ze0du3", - "threatintel.indicator.url.original": "https://0te9x75e.example.net/y2cbl5ov5/u-s9?vhppw120=bt0ze0du3", - "threatintel.indicator.url.path": "/y2cbl5ov5/u-s9", - "threatintel.indicator.url.query": "vhppw120=bt0ze0du3", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "0te9x75e.example.net", + "threat.indicator.url.full": "https://0te9x75e.example.net/y2cbl5ov5/u-s9?vhppw120=bt0ze0du3", + "threat.indicator.url.original": "https://0te9x75e.example.net/y2cbl5ov5/u-s9?vhppw120=bt0ze0du3", + "threat.indicator.url.path": "/y2cbl5ov5/u-s9", + "threat.indicator.url.query": "vhppw120=bt0ze0du3", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 31, + "anomali.threatstream.detail2": "imported by user 450", + "anomali.threatstream.id": "3137219963", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:nosy8", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P33588463803/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "2108", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "755", + "843", + "943" + ], + "anomali.threatstream.update_id": "1484831936", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3453,43 +3718,45 @@ "service.type": "threatintel", "tags": [ "06epx", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 31, - "threatintel.anomalithreatstream.detail2": "imported by user 450", - "threatintel.anomalithreatstream.id": 3137219963, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:nosy8", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P33588463803/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 2108, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "755", - "843", - "943" - ], - "threatintel.anomalithreatstream.update_id": 1484831936, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 3, - "threatintel.indicator.first_seen": "2020-10-09T18:44:04.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.180", - "threatintel.indicator.last_seen": "2020-10-09T18:44:04.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:44:04.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.180", + "threat.indicator.last_seen": "2020-10-09T18:44:04.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "b7qdtnl8f.example.org", - "threatintel.indicator.url.full": "http://b7qdtnl8f.example.org/z2a-tx3ip/7cv?9a67ct3mb=ijse", - "threatintel.indicator.url.original": "http://b7qdtnl8f.example.org/z2a-tx3ip/7cv?9a67ct3mb=ijse", - "threatintel.indicator.url.path": "/z2a-tx3ip/7cv", - "threatintel.indicator.url.query": "9a67ct3mb=ijse", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "b7qdtnl8f.example.org", + "threat.indicator.url.full": "http://b7qdtnl8f.example.org/z2a-tx3ip/7cv?9a67ct3mb=ijse", + "threat.indicator.url.original": "http://b7qdtnl8f.example.org/z2a-tx3ip/7cv?9a67ct3mb=ijse", + "threat.indicator.url.path": "/z2a-tx3ip/7cv", + "threat.indicator.url.query": "9a67ct3mb=ijse", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 19, + "anomali.threatstream.detail2": "imported by user 479", + "anomali.threatstream.id": "2506436592", + "anomali.threatstream.itype": "mal_domain", + "anomali.threatstream.maltype": "malware:4okr", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P42606732542/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "393", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "324", + "63" + ], + "anomali.threatstream.update_id": "1826833096", + "anomali.threatstream.value_type": "domain", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3501,37 +3768,40 @@ "log.offset": 42447, "service.type": "threatintel", "tags": [ + "forwarded", "jjz8e", "n5okkr7mg", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 19, - "threatintel.anomalithreatstream.detail2": "imported by user 479", - "threatintel.anomalithreatstream.id": 2506436592, - "threatintel.anomalithreatstream.itype": "mal_domain", - "threatintel.anomalithreatstream.maltype": "malware:4okr", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P42606732542/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 393, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "324", - "63" - ], - "threatintel.anomalithreatstream.update_id": 1826833096, - "threatintel.anomalithreatstream.value_type": "domain", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:44:19.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:44:19.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:44:19.000Z", + "threat.indicator.last_seen": "2020-10-09T18:44:19.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "4gtq1n.example.net" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "4gtq1n.example.net" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 83, + "anomali.threatstream.detail2": "imported by user 969", + "anomali.threatstream.id": "1214135687", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.maltype": "malware:h68c70o", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P25206292349/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "425", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "324", + "474" + ], + "anomali.threatstream.update_id": "2101635974", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3545,40 +3815,43 @@ "tags": [ "IP=203.0.113.163", "first_seen=2020-02-14T13:46:51", + "forwarded", "gnz6", "mask=203.0.113.12", "popularity=high", "threatintel-anomalithreatstream", "u96h" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 83, - "threatintel.anomalithreatstream.detail2": "imported by user 969", - "threatintel.anomalithreatstream.id": 1214135687, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.maltype": "malware:h68c70o", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P25206292349/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 425, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "324", - "474" - ], - "threatintel.anomalithreatstream.update_id": 2101635974, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2020-10-09T18:44:27.000Z", - "threatintel.indicator.geo.country_iso_code": "RU", - "threatintel.indicator.ip": "192.0.2.17", - "threatintel.indicator.last_seen": "2020-10-09T18:44:27.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:44:27.000Z", + "threat.indicator.geo.country_iso_code": "RU", + "threat.indicator.ip": "192.0.2.17", + "threat.indicator.last_seen": "2020-10-09T18:44:27.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 15, + "anomali.threatstream.detail2": "imported by user 501", + "anomali.threatstream.id": "1632578144", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:y9xovpr2", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P21633460934/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "1114", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "615", + "818" + ], + "anomali.threatstream.update_id": "1949050295", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3590,43 +3863,47 @@ "log.offset": 43582, "service.type": "threatintel", "tags": [ + "forwarded", "t37z5d2", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 15, - "threatintel.anomalithreatstream.detail2": "imported by user 501", - "threatintel.anomalithreatstream.id": 1632578144, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:y9xovpr2", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P21633460934/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 1114, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "615", - "818" - ], - "threatintel.anomalithreatstream.update_id": 1949050295, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:44:35.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.183", - "threatintel.indicator.last_seen": "2020-10-09T18:44:35.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:44:35.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.183", + "threat.indicator.last_seen": "2020-10-09T18:44:35.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "tfva.example.org", - "threatintel.indicator.url.full": "https://tfva.example.org/iih3qkj/b04g7?dwosh0qmt=wi9ao", - "threatintel.indicator.url.original": "https://tfva.example.org/iih3qkj/b04g7?dwosh0qmt=wi9ao", - "threatintel.indicator.url.path": "/iih3qkj/b04g7", - "threatintel.indicator.url.query": "dwosh0qmt=wi9ao", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "tfva.example.org", + "threat.indicator.url.full": "https://tfva.example.org/iih3qkj/b04g7?dwosh0qmt=wi9ao", + "threat.indicator.url.original": "https://tfva.example.org/iih3qkj/b04g7?dwosh0qmt=wi9ao", + "threat.indicator.url.path": "/iih3qkj/b04g7", + "threat.indicator.url.query": "dwosh0qmt=wi9ao", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 85, + "anomali.threatstream.detail2": "imported by user 149", + "anomali.threatstream.id": "3098969355", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:wxbuhcov9", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P30134520108/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "398", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "597", + "913", + "946" + ], + "anomali.threatstream.update_id": "2645963867", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3638,44 +3915,47 @@ "log.offset": 44184, "service.type": "threatintel", "tags": [ + "forwarded", "rprsi-", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 85, - "threatintel.anomalithreatstream.detail2": "imported by user 149", - "threatintel.anomalithreatstream.id": 3098969355, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:wxbuhcov9", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P30134520108/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 398, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "597", - "913", - "946" - ], - "threatintel.anomalithreatstream.update_id": 2645963867, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:44:36.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "203.0.113.149", - "threatintel.indicator.last_seen": "2020-10-09T18:44:36.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:44:36.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "203.0.113.149", + "threat.indicator.last_seen": "2020-10-09T18:44:36.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "erg2.example.com", - "threatintel.indicator.url.full": "https://erg2.example.com/4ys/vywa93c?7oru=evpi", - "threatintel.indicator.url.original": "https://erg2.example.com/4ys/vywa93c?7oru=evpi", - "threatintel.indicator.url.path": "/4ys/vywa93c", - "threatintel.indicator.url.query": "7oru=evpi", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "erg2.example.com", + "threat.indicator.url.full": "https://erg2.example.com/4ys/vywa93c?7oru=evpi", + "threat.indicator.url.original": "https://erg2.example.com/4ys/vywa93c?7oru=evpi", + "threat.indicator.url.path": "/4ys/vywa93c", + "threat.indicator.url.query": "7oru=evpi", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 64, + "anomali.threatstream.detail2": "imported by user 59", + "anomali.threatstream.id": "2035701780", + "anomali.threatstream.itype": "mal_url", + "anomali.threatstream.maltype": "malware:xn2a", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P10508749376/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "2760", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "600", + "673", + "990" + ], + "anomali.threatstream.update_id": "2806149730", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3690,46 +3970,49 @@ "-jj", "IP=203.0.113.22", "first_seen=2020-12-24T20:20:31", + "forwarded", "gogpcno", "mask=2001:db8:bdc6:400b:c095:41c7:1d54:8ff6", "popularity=low", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 64, - "threatintel.anomalithreatstream.detail2": "imported by user 59", - "threatintel.anomalithreatstream.id": 2035701780, - "threatintel.anomalithreatstream.itype": "mal_url", - "threatintel.anomalithreatstream.maltype": "malware:xn2a", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P10508749376/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 2760, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "600", - "673", - "990" - ], - "threatintel.anomalithreatstream.update_id": 2806149730, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 6, - "threatintel.indicator.first_seen": "2020-10-09T18:44:37.000Z", - "threatintel.indicator.geo.country_iso_code": "IN", - "threatintel.indicator.ip": "203.0.113.27", - "threatintel.indicator.last_seen": "2020-10-09T18:44:37.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:44:37.000Z", + "threat.indicator.geo.country_iso_code": "IN", + "threat.indicator.ip": "203.0.113.27", + "threat.indicator.last_seen": "2020-10-09T18:44:37.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "0elz6c.example.com", - "threatintel.indicator.url.full": "https://0elz6c.example.com/3nhx/cadsn6?kfcj94=gnl", - "threatintel.indicator.url.original": "https://0elz6c.example.com/3nhx/cadsn6?kfcj94=gnl", - "threatintel.indicator.url.path": "/3nhx/cadsn6", - "threatintel.indicator.url.query": "kfcj94=gnl", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "0elz6c.example.com", + "threat.indicator.url.full": "https://0elz6c.example.com/3nhx/cadsn6?kfcj94=gnl", + "threat.indicator.url.original": "https://0elz6c.example.com/3nhx/cadsn6?kfcj94=gnl", + "threat.indicator.url.path": "/3nhx/cadsn6", + "threat.indicator.url.query": "kfcj94=gnl", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 44, + "anomali.threatstream.detail2": "imported by user 134", + "anomali.threatstream.id": "2120958409", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:cu6f11gp1", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P46535027346/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1973", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "125", + "279", + "552" + ], + "anomali.threatstream.update_id": "3490786662", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3741,44 +4024,46 @@ "log.offset": 45480, "service.type": "threatintel", "tags": [ + "forwarded", "qztcai", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 44, - "threatintel.anomalithreatstream.detail2": "imported by user 134", - "threatintel.anomalithreatstream.id": 2120958409, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:cu6f11gp1", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P46535027346/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1973, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "125", - "279", - "552" - ], - "threatintel.anomalithreatstream.update_id": 3490786662, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 4, - "threatintel.indicator.first_seen": "2020-10-09T18:44:45.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "2001:db8:129e:7520:8797:95ca:a4d1:3011", - "threatintel.indicator.last_seen": "2020-10-09T18:44:45.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:44:45.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "2001:db8:129e:7520:8797:95ca:a4d1:3011", + "threat.indicator.last_seen": "2020-10-09T18:44:45.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "6i0-utr.example.com", - "threatintel.indicator.url.full": "https://6i0-utr.example.com/hsv/50qcugwt?xcl=ofr", - "threatintel.indicator.url.original": "https://6i0-utr.example.com/hsv/50qcugwt?xcl=ofr", - "threatintel.indicator.url.path": "/hsv/50qcugwt", - "threatintel.indicator.url.query": "xcl=ofr", - "threatintel.indicator.url.scheme": "https" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "6i0-utr.example.com", + "threat.indicator.url.full": "https://6i0-utr.example.com/hsv/50qcugwt?xcl=ofr", + "threat.indicator.url.original": "https://6i0-utr.example.com/hsv/50qcugwt?xcl=ofr", + "threat.indicator.url.path": "/hsv/50qcugwt", + "threat.indicator.url.query": "xcl=ofr", + "threat.indicator.url.scheme": "https" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 94, + "anomali.threatstream.detail2": "imported by user 914", + "anomali.threatstream.id": "1139990065", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.maltype": "malware:9pyy91p7", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P20277063326/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "2363", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "346", + "610" + ], + "anomali.threatstream.update_id": "2750333841", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3793,39 +4078,41 @@ "IP=203.0.113.155", "ail6s", "first_seen=2020-11-23T17:11:50", + "forwarded", "mask=203.0.113.23", "popularity=medium", "q0n", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 94, - "threatintel.anomalithreatstream.detail2": "imported by user 914", - "threatintel.anomalithreatstream.id": 1139990065, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.maltype": "malware:9pyy91p7", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P20277063326/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 2363, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "346", - "610" - ], - "threatintel.anomalithreatstream.update_id": 2750333841, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:44:47.000Z", - "threatintel.indicator.geo.country_iso_code": "CN", - "threatintel.indicator.ip": "203.0.113.128", - "threatintel.indicator.last_seen": "2020-10-09T18:44:47.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:44:47.000Z", + "threat.indicator.geo.country_iso_code": "CN", + "threat.indicator.ip": "203.0.113.128", + "threat.indicator.last_seen": "2020-10-09T18:44:47.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 69, + "anomali.threatstream.detail2": "imported by user 886", + "anomali.threatstream.id": "2453026318", + "anomali.threatstream.itype": "mal_domain", + "anomali.threatstream.maltype": "malware:c0-a", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P26988858868/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1281", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "391" + ], + "anomali.threatstream.update_id": "3315952704", + "anomali.threatstream.value_type": "domain", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3839,39 +4126,44 @@ "tags": [ "0a3p", "first_seen=2020-03-11T09:04:13", + "forwarded", "mask=2001:db8:7aae:f1e6:e8b3:5702:40ea:29f0", "popularity=high", "smh", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 69, - "threatintel.anomalithreatstream.detail2": "imported by user 886", - "threatintel.anomalithreatstream.id": 2453026318, - "threatintel.anomalithreatstream.itype": "mal_domain", - "threatintel.anomalithreatstream.maltype": "malware:c0-a", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P26988858868/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1281, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "391" - ], - "threatintel.anomalithreatstream.update_id": 3315952704, - "threatintel.anomalithreatstream.value_type": "domain", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:44:50.000Z", - "threatintel.indicator.geo.country_iso_code": "HK", - "threatintel.indicator.ip": "203.0.113.16", - "threatintel.indicator.last_seen": "2020-10-09T18:44:50.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Med", + "threat.indicator.first_seen": "2020-10-09T18:44:50.000Z", + "threat.indicator.geo.country_iso_code": "HK", + "threat.indicator.ip": "203.0.113.16", + "threat.indicator.last_seen": "2020-10-09T18:44:50.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "ztpyt.example.org" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "ztpyt.example.org" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 88, + "anomali.threatstream.detail2": "imported by user 268", + "anomali.threatstream.id": "3554643386", + "anomali.threatstream.itype": "mal_url", + "anomali.threatstream.maltype": "malware:ai7s5vg01", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P48225335605/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "744", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "258", + "75", + "806" + ], + "anomali.threatstream.update_id": "3898530792", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3884,45 +4176,46 @@ "service.type": "threatintel", "tags": [ "first_seen=2020-07-17T00:42:30", + "forwarded", "mask=192.0.2.22", "mdedohd", "popularity=high", "sv5lmqoo", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 88, - "threatintel.anomalithreatstream.detail2": "imported by user 268", - "threatintel.anomalithreatstream.id": 3554643386, - "threatintel.anomalithreatstream.itype": "mal_url", - "threatintel.anomalithreatstream.maltype": "malware:ai7s5vg01", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P48225335605/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 744, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "258", - "75", - "806" - ], - "threatintel.anomalithreatstream.update_id": 3898530792, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 9, - "threatintel.indicator.first_seen": "2020-10-09T18:44:50.000Z", - "threatintel.indicator.last_seen": "2020-10-09T18:44:50.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:44:50.000Z", + "threat.indicator.last_seen": "2020-10-09T18:44:50.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "e5el.example.net", - "threatintel.indicator.url.full": "http://e5el.example.net/rncer/fky?8tc53bbz=1pd-6w5", - "threatintel.indicator.url.original": "http://e5el.example.net/rncer/fky?8tc53bbz=1pd-6w5", - "threatintel.indicator.url.path": "/rncer/fky", - "threatintel.indicator.url.query": "8tc53bbz=1pd-6w5", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "e5el.example.net", + "threat.indicator.url.full": "http://e5el.example.net/rncer/fky?8tc53bbz=1pd-6w5", + "threat.indicator.url.original": "http://e5el.example.net/rncer/fky?8tc53bbz=1pd-6w5", + "threat.indicator.url.path": "/rncer/fky", + "threat.indicator.url.query": "8tc53bbz=1pd-6w5", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 73, + "anomali.threatstream.detail2": "imported by user 737", + "anomali.threatstream.id": "2781657405", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:6faja4zy-", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P13788530147/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "518", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "259" + ], + "anomali.threatstream.update_id": "1423149268", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3934,42 +4227,47 @@ "log.offset": 47992, "service.type": "threatintel", "tags": [ + "forwarded", "l019r8", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 73, - "threatintel.anomalithreatstream.detail2": "imported by user 737", - "threatintel.anomalithreatstream.id": 2781657405, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:6faja4zy-", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P13788530147/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 518, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "259" - ], - "threatintel.anomalithreatstream.update_id": 1423149268, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2020-10-09T18:44:54.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.226", - "threatintel.indicator.last_seen": "2020-10-09T18:44:54.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2020-10-09T18:44:54.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.226", + "threat.indicator.last_seen": "2020-10-09T18:44:54.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "eryz36i.example.net", - "threatintel.indicator.url.full": "http://eryz36i.example.net/9a86hdj/zti5r9fx?ahz=l7dsg01qo", - "threatintel.indicator.url.original": "http://eryz36i.example.net/9a86hdj/zti5r9fx?ahz=l7dsg01qo", - "threatintel.indicator.url.path": "/9a86hdj/zti5r9fx", - "threatintel.indicator.url.query": "ahz=l7dsg01qo", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "eryz36i.example.net", + "threat.indicator.url.full": "http://eryz36i.example.net/9a86hdj/zti5r9fx?ahz=l7dsg01qo", + "threat.indicator.url.original": "http://eryz36i.example.net/9a86hdj/zti5r9fx?ahz=l7dsg01qo", + "threat.indicator.url.path": "/9a86hdj/zti5r9fx", + "threat.indicator.url.query": "ahz=l7dsg01qo", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 22, + "anomali.threatstream.detail2": "imported by user 703", + "anomali.threatstream.id": "1875325904", + "anomali.threatstream.itype": "phish_url", + "anomali.threatstream.maltype": "malware:rrcnb", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P12535858975/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "417", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "114", + "792", + "802" + ], + "anomali.threatstream.update_id": "2621256767", + "anomali.threatstream.value_type": "url", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -3982,43 +4280,45 @@ "service.type": "threatintel", "tags": [ "4yqbj3b", + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 22, - "threatintel.anomalithreatstream.detail2": "imported by user 703", - "threatintel.anomalithreatstream.id": 1875325904, - "threatintel.anomalithreatstream.itype": "phish_url", - "threatintel.anomalithreatstream.maltype": "malware:rrcnb", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P12535858975/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 417, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "114", - "792", - "802" - ], - "threatintel.anomalithreatstream.update_id": 2621256767, - "threatintel.anomalithreatstream.value_type": "url", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:44:58.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.ip": "192.0.2.25", - "threatintel.indicator.last_seen": "2020-10-09T18:44:58.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:44:58.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.ip": "192.0.2.25", + "threat.indicator.last_seen": "2020-10-09T18:44:58.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "i-pb.example.com", - "threatintel.indicator.url.full": "http://i-pb.example.com/pjmy3/w0tgzb?noe1pr9=eiwcfihd", - "threatintel.indicator.url.original": "http://i-pb.example.com/pjmy3/w0tgzb?noe1pr9=eiwcfihd", - "threatintel.indicator.url.path": "/pjmy3/w0tgzb", - "threatintel.indicator.url.query": "noe1pr9=eiwcfihd", - "threatintel.indicator.url.scheme": "http" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "i-pb.example.com", + "threat.indicator.url.full": "http://i-pb.example.com/pjmy3/w0tgzb?noe1pr9=eiwcfihd", + "threat.indicator.url.original": "http://i-pb.example.com/pjmy3/w0tgzb?noe1pr9=eiwcfihd", + "threat.indicator.url.path": "/pjmy3/w0tgzb", + "threat.indicator.url.query": "noe1pr9=eiwcfihd", + "threat.indicator.url.scheme": "http" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 19, + "anomali.threatstream.detail2": "imported by user 846", + "anomali.threatstream.id": "2684776210", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.maltype": "malware:zfd", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P45743905551/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "965", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "641", + "697" + ], + "anomali.threatstream.update_id": "1171583779", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4032,40 +4332,44 @@ "tags": [ "IP=2001:db8:61be:1efa:290:c941:bef8:3803", "first_seen=2020-12-01T02:16:04", + "forwarded", "j6vwgb6", "mask=2001:db8:fc83:375e:9c60:3d50:1dc1:9f89", "popularity=medium", "qqo5fg", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 19, - "threatintel.anomalithreatstream.detail2": "imported by user 846", - "threatintel.anomalithreatstream.id": 2684776210, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.maltype": "malware:zfd", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P45743905551/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 965, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "641", - "697" - ], - "threatintel.anomalithreatstream.update_id": 1171583779, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 2, - "threatintel.indicator.first_seen": "2020-10-09T18:45:05.000Z", - "threatintel.indicator.geo.country_iso_code": "IN", - "threatintel.indicator.ip": "2001:db8:79d3:9083:95f2:a6fd:e475:4956", - "threatintel.indicator.last_seen": "2020-10-09T18:45:05.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2020-10-09T18:45:05.000Z", + "threat.indicator.geo.country_iso_code": "IN", + "threat.indicator.ip": "2001:db8:79d3:9083:95f2:a6fd:e475:4956", + "threat.indicator.last_seen": "2020-10-09T18:45:05.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv6-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv6-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 14, + "anomali.threatstream.detail2": "imported by user 812", + "anomali.threatstream.id": "1705726884", + "anomali.threatstream.import_session_id": "2813", + "anomali.threatstream.itype": "mal_ip", + "anomali.threatstream.maltype": "malware:ib0ezg", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P12586136986/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "632", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "459", + "936" + ], + "anomali.threatstream.update_id": "3651210157", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4077,41 +4381,42 @@ "log.offset": 49879, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 14, - "threatintel.anomalithreatstream.detail2": "imported by user 812", - "threatintel.anomalithreatstream.id": 1705726884, - "threatintel.anomalithreatstream.import_session_id": 2813, - "threatintel.anomalithreatstream.itype": "mal_ip", - "threatintel.anomalithreatstream.maltype": "malware:ib0ezg", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P12586136986/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 632, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "459", - "936" - ], - "threatintel.anomalithreatstream.update_id": 3651210157, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.as.number": 3356, - "threatintel.indicator.as.organization.name": "Level 3 Communications", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2021-04-07T13:10:07.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.geo.location.lat": 5.6, - "threatintel.indicator.geo.location.lon": 112.8, - "threatintel.indicator.ip": "192.0.2.12", - "threatintel.indicator.last_seen": "2021-04-19T08:57:46.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.as.number": 3356, + "threat.indicator.as.organization.name": "Level 3 Communications", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2021-04-07T13:10:07.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.geo.location.lat": 5.6, + "threat.indicator.geo.location.lon": 112.8, + "threat.indicator.ip": "192.0.2.12", + "threat.indicator.last_seen": "2021-04-19T08:57:46.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 81, + "anomali.threatstream.detail2": "imported by user 411", + "anomali.threatstream.id": "1502608684", + "anomali.threatstream.itype": "apt_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P46655498126/", + "anomali.threatstream.severity": "very-high", + "anomali.threatstream.source_feed_id": "2891", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "474", + "601" + ], + "anomali.threatstream.update_id": "1170853028", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4123,34 +4428,36 @@ "log.offset": 50468, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 81, - "threatintel.anomalithreatstream.detail2": "imported by user 411", - "threatintel.anomalithreatstream.id": 1502608684, - "threatintel.anomalithreatstream.itype": "apt_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P46655498126/", - "threatintel.anomalithreatstream.severity": "very-high", - "threatintel.anomalithreatstream.source_feed_id": 2891, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "474", - "601" - ], - "threatintel.anomalithreatstream.update_id": 1170853028, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2021-04-29T16:02:17.000Z", - "threatintel.indicator.ip": "203.0.113.5", - "threatintel.indicator.last_seen": "2021-04-29T16:02:17.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2021-04-29T16:02:17.000Z", + "threat.indicator.ip": "203.0.113.5", + "threat.indicator.last_seen": "2021-04-29T16:02:17.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 14, + "anomali.threatstream.detail2": "imported by user 601", + "anomali.threatstream.id": "1171635730", + "anomali.threatstream.itype": "ssh_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P24647878518/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "822", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "749" + ], + "anomali.threatstream.update_id": "1026394470", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4162,33 +4469,37 @@ "log.offset": 50919, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 14, - "threatintel.anomalithreatstream.detail2": "imported by user 601", - "threatintel.anomalithreatstream.id": 1171635730, - "threatintel.anomalithreatstream.itype": "ssh_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P24647878518/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 822, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "749" - ], - "threatintel.anomalithreatstream.update_id": 1026394470, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2021-04-29T16:02:23.000Z", - "threatintel.indicator.ip": "192.0.2.68", - "threatintel.indicator.last_seen": "2021-04-29T16:02:23.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2021-04-29T16:02:23.000Z", + "threat.indicator.ip": "192.0.2.68", + "threat.indicator.last_seen": "2021-04-29T16:02:23.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 70, + "anomali.threatstream.detail2": "imported by user 964", + "anomali.threatstream.id": "2251817936", + "anomali.threatstream.itype": "i2p_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P47421535249/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "3194", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "235", + "630" + ], + "anomali.threatstream.update_id": "3118045359", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4200,34 +4511,37 @@ "log.offset": 51361, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 70, - "threatintel.anomalithreatstream.detail2": "imported by user 964", - "threatintel.anomalithreatstream.id": 2251817936, - "threatintel.anomalithreatstream.itype": "i2p_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P47421535249/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 3194, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "235", - "630" - ], - "threatintel.anomalithreatstream.update_id": 3118045359, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 7, - "threatintel.indicator.first_seen": "2021-04-29T16:02:24.000Z", - "threatintel.indicator.ip": "203.0.113.54", - "threatintel.indicator.last_seen": "2021-04-29T16:02:24.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2021-04-29T16:02:24.000Z", + "threat.indicator.ip": "203.0.113.54", + "threat.indicator.last_seen": "2021-04-29T16:02:24.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 77, + "anomali.threatstream.detail2": "imported by user 137", + "anomali.threatstream.id": "1966380326", + "anomali.threatstream.itype": "parked_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P19479436344/", + "anomali.threatstream.severity": "low", + "anomali.threatstream.source_feed_id": "229", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "303", + "461" + ], + "anomali.threatstream.update_id": "1757326916", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4239,34 +4553,38 @@ "log.offset": 51809, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 77, - "threatintel.anomalithreatstream.detail2": "imported by user 137", - "threatintel.anomalithreatstream.id": 1966380326, - "threatintel.anomalithreatstream.itype": "parked_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P19479436344/", - "threatintel.anomalithreatstream.severity": "low", - "threatintel.anomalithreatstream.source_feed_id": 229, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "303", - "461" - ], - "threatintel.anomalithreatstream.update_id": 1757326916, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 8, - "threatintel.indicator.first_seen": "2021-04-29T16:02:25.000Z", - "threatintel.indicator.ip": "203.0.113.195", - "threatintel.indicator.last_seen": "2021-04-29T16:02:25.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "High", + "threat.indicator.first_seen": "2021-04-29T16:02:25.000Z", + "threat.indicator.ip": "203.0.113.195", + "threat.indicator.last_seen": "2021-04-29T16:02:25.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "private", + "anomali.threatstream.confidence": 14, + "anomali.threatstream.detail2": "imported by user 997", + "anomali.threatstream.id": "3377960871", + "anomali.threatstream.itype": "tor_ip", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P25503355951/", + "anomali.threatstream.severity": "medium", + "anomali.threatstream.source_feed_id": "1710", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "13", + "657", + "879" + ], + "anomali.threatstream.update_id": "1469037378", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4278,35 +4596,38 @@ "log.offset": 52257, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream" ], - "threatintel.anomalithreatstream.classification": "private", - "threatintel.anomalithreatstream.confidence": 14, - "threatintel.anomalithreatstream.detail2": "imported by user 997", - "threatintel.anomalithreatstream.id": 3377960871, - "threatintel.anomalithreatstream.itype": "tor_ip", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P25503355951/", - "threatintel.anomalithreatstream.severity": "medium", - "threatintel.anomalithreatstream.source_feed_id": 1710, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "13", - "657", - "879" - ], - "threatintel.anomalithreatstream.update_id": 1469037378, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2021-04-29T16:02:25.000Z", - "threatintel.indicator.ip": "192.0.2.239", - "threatintel.indicator.last_seen": "2021-04-29T16:02:25.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2021-04-29T16:02:25.000Z", + "threat.indicator.ip": "192.0.2.239", + "threat.indicator.last_seen": "2021-04-29T16:02:25.000Z", + "threat.indicator.marking.tlp": [ "Amber" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" }, { + "anomali.threatstream.classification": "public", + "anomali.threatstream.confidence": 12, + "anomali.threatstream.detail2": "imported by user 445", + "anomali.threatstream.id": "1049633552", + "anomali.threatstream.itype": "c2_ip", + "anomali.threatstream.maltype": "malware:tos5xne", + "anomali.threatstream.resource_uri": "/api/v1/intelligence/P17175297976/", + "anomali.threatstream.severity": "high", + "anomali.threatstream.source_feed_id": "274", + "anomali.threatstream.state": "active", + "anomali.threatstream.trusted_circle_ids": [ + "683", + "719" + ], + "anomali.threatstream.update_id": "1541655552", + "anomali.threatstream.value_type": "ip", "event.category": "threat", "event.dataset": "threatintel.anomalithreatstream", "event.kind": "enrichment", @@ -4318,33 +4639,20 @@ "log.offset": 52708, "service.type": "threatintel", "tags": [ + "forwarded", "threatintel-anomalithreatstream", "vjb9lmpcf" ], - "threatintel.anomalithreatstream.classification": "public", - "threatintel.anomalithreatstream.confidence": 12, - "threatintel.anomalithreatstream.detail2": "imported by user 445", - "threatintel.anomalithreatstream.id": 1049633552, - "threatintel.anomalithreatstream.itype": "c2_ip", - "threatintel.anomalithreatstream.maltype": "malware:tos5xne", - "threatintel.anomalithreatstream.resource_uri": "/api/v1/intelligence/P17175297976/", - "threatintel.anomalithreatstream.severity": "high", - "threatintel.anomalithreatstream.source_feed_id": 274, - "threatintel.anomalithreatstream.state": "active", - "threatintel.anomalithreatstream.trusted_circle_ids": [ - "683", - "719" - ], - "threatintel.anomalithreatstream.update_id": 1541655552, - "threatintel.anomalithreatstream.value_type": "ip", - "threatintel.indicator.confidence": 1, - "threatintel.indicator.first_seen": "2021-04-29T16:02:26.000Z", - "threatintel.indicator.ip": "192.0.2.169", - "threatintel.indicator.last_seen": "2021-04-29T16:02:26.000Z", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Anomali ThreatStream", + "threat.indicator.confidence": "Low", + "threat.indicator.first_seen": "2021-04-29T16:02:26.000Z", + "threat.indicator.ip": "192.0.2.169", + "threat.indicator.last_seen": "2021-04-29T16:02:26.000Z", + "threat.indicator.marking.tlp": [ "White" ], - "threatintel.indicator.provider": "Default Organization", - "threatintel.indicator.type": "ipv4-addr" + "threat.indicator.provider": "Default Organization", + "threat.indicator.type": "ipv4-addr" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/fields.go b/x-pack/filebeat/module/threatintel/fields.go index 4f915c83f55e..d0fa140db906 100644 --- a/x-pack/filebeat/module/threatintel/fields.go +++ b/x-pack/filebeat/module/threatintel/fields.go @@ -19,5 +19,5 @@ func init() { // AssetThreatintel returns asset data. // This is the base64 encoded zlib format compressed contents of module/threatintel. func AssetThreatintel() string { - return "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" + return "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" } diff --git a/x-pack/filebeat/module/threatintel/malwarebazaar/_meta/fields.yml b/x-pack/filebeat/module/threatintel/malwarebazaar/_meta/fields.yml index 16a50f3a0ff4..ea68e4c23cb8 100644 --- a/x-pack/filebeat/module/threatintel/malwarebazaar/_meta/fields.yml +++ b/x-pack/filebeat/module/threatintel/malwarebazaar/_meta/fields.yml @@ -1,4 +1,4 @@ -- name: malwarebazaar +- name: abusech.malwarebazaar type: group description: > Fields for Malware Bazaar Threat Intel diff --git a/x-pack/filebeat/module/threatintel/malwarebazaar/config/config.yml b/x-pack/filebeat/module/threatintel/malwarebazaar/config/config.yml index a8cbef0b52b4..6c90f1d86dc5 100644 --- a/x-pack/filebeat/module/threatintel/malwarebazaar/config/config.yml +++ b/x-pack/filebeat/module/threatintel/malwarebazaar/config/config.yml @@ -5,19 +5,14 @@ interval: {{ .interval }} request.method: POST {{ if .ssl }} - request.ssl: {{ .ssl | tojson }} {{ end }} {{ if .proxy_url }} request.proxy_url: {{ .proxy_url }} {{ end }} request.url: {{ .url }} -#request.encode_as: application/x-www-form-encoded - +request.encode_as: application/x-www-form-urlencoded request.transforms: -- set: - target: header.Content-Type - value: application/x-www-form-urlencoded - set: target: url.params.query value: get_recent @@ -39,17 +34,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: ["json.md5_hash"] - target_field: "@metadata._id" - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/malwarebazaar/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/malwarebazaar/ingest/pipeline.yml index c2c4b51810d4..0a5aca9dbb34 100644 --- a/x-pack/filebeat/module/threatintel/malwarebazaar/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/malwarebazaar/ingest/pipeline.yml @@ -1,4 +1,5 @@ -description: Pipeline for parsing Malware Bazaar Threat Intel +--- +description: Pipeline for parsing Abuse.ch URL Threat Intel processors: #################### # Event ECS fields # @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -20,148 +24,182 @@ processors: # General ECS fields # ###################### - rename: - field: json - target_field: threatintel.malwarebazaar - ignore_missing: true + field: message + target_field: event.original + ignore_missing: true + - json: + field: event.original + target_field: abusech.malwarebazaar + - fingerprint: + fields: + - abusech.malwarebazaar.md5_hash + - abusech.malwarebazaar.sha256_hash + target_field: "_id" ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] AbuseCH MalwareBazaar" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" - date: - field: threatintel.malwarebazaar.first_seen - target_field: threatintel.indicator.first_seen + field: abusech.malwarebazaar.first_seen + target_field: threat.indicator.first_seen formats: - "yyyy-MM-dd HH:mm:ss z" - "yyyy-MM-dd HH:mm:ss Z" - "yyyy-MM-dd HH:mm:ss" - if: "ctx?.threatintel?.malwarebazaar.first_seen != null" + if: "ctx.abusech?.malwarebazaar?.first_seen != null" - date: - field: threatintel.malwarebazaar.last_seen - target_field: threatintel.indicator.last_seen + field: abusech.malwarebazaar.last_seen + target_field: threat.indicator.last_seen formats: - "yyyy-MM-dd HH:mm:ss z" - "yyyy-MM-dd HH:mm:ss Z" - "yyyy-MM-dd HH:mm:ss" - if: "ctx?.threatintel?.malwarebazaar.last_seen != null" + if: "ctx.abusech?.malwarebazaar?.last_seen != null" - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - rename: - field: threatintel.malwarebazaar.file_name - target_field: threatintel.indicator.file.name + field: abusech.malwarebazaar.file_name + target_field: threat.indicator.file.name ignore_missing: true - rename: - field: threatintel.malwarebazaar.file_type_mime - target_field: threatintel.indicator.file.mime_type + field: abusech.malwarebazaar.file_type_mime + target_field: threat.indicator.file.mime_type ignore_missing: true - rename: - field: threatintel.malwarebazaar.reporter - target_field: threatintel.indicator.provider + field: abusech.malwarebazaar.reporter + target_field: threat.indicator.provider ignore_missing: true - rename: - field: threatintel.malwarebazaar.origin_country - target_field: threatintel.indicator.geo.country_iso_code + field: abusech.malwarebazaar.origin_country + target_field: threat.indicator.geo.country_iso_code ignore_missing: true - rename: - field: threatintel.malwarebazaar.signature - target_field: threatintel.indicator.signature + field: abusech.malwarebazaar.signature + target_field: threat.software.alias ignore_missing: true - foreach: - field: threatintel.malwarebazaar.code_sign + field: abusech.malwarebazaar.code_sign ignore_missing: true processor: rename: - field: subject_cn - target_field: threatintel.indicator.file.x509.subject.common_name + field: _ingest._value.subject_cn + target_field: threat.indicator.file.x509.subject.common_name + - foreach: + field: abusech.malwarebazaar.code_sign + ignore_missing: true + processor: rename: - field: issuer_cn - target_field: threatintel.indicator.file.x509.issuer.common_name + field: _ingest._value.issuer_cn + target_field: threat.indicator.file.x509.issuer.common_name + - foreach: + field: abusech.malwarebazaar.code_sign + ignore_missing: true + processor: rename: - field: algorithm - target_field: threatintel.indicator.file.x509.public_key_algorithm + field: _ingest._value.algorithm + target_field: threat.indicator.file.x509.public_key_algorithm + - foreach: + field: abusech.malwarebazaar.code_sign + ignore_missing: true + processor: rename: - field: valid_from - target_field: threatintel.indicator.file.x509.not_before + field: _ingest._value.valid_from + target_field: threat.indicator.file.x509.not_before + - foreach: + field: abusech.malwarebazaar.code_sign + ignore_missing: true + processor: rename: - field: valid_to - target_field: threatintel.indicator.file.x509.not_after + field: _ingest._value.valid_to + target_field: threat.indicator.file.x509.not_after + - foreach: + field: abusech.malwarebazaar.code_sign + ignore_missing: true + processor: rename: - field: serial_number - target_field: threatintel.indicator.file.x509.serial_number + field: _ingest._value.serial_number + target_field: threat.indicator.file.x509.serial_number - rename: - field: threatintel.malwarebazaar.file_size - target_field: threatintel.indicator.file.size + field: abusech.malwarebazaar.file_size + target_field: threat.indicator.file.size ignore_missing: true - rename: - field: threatintel.malwarebazaar.file_type - target_field: threatintel.indicator.file.extension + field: abusech.malwarebazaar.file_type + target_field: threat.indicator.file.extension ignore_missing: true - rename: - field: threatintel.malwarebazaar.md5_hash - target_field: threatintel.indicator.file.hash.md5 + field: abusech.malwarebazaar.md5_hash + target_field: threat.indicator.file.hash.md5 ignore_missing: true - rename: - field: threatintel.malwarebazaar.sha256_hash - target_field: threatintel.indicator.file.hash.sha256 + field: abusech.malwarebazaar.sha256_hash + target_field: threat.indicator.file.hash.sha256 ignore_missing: true - rename: - field: threatintel.malwarebazaar.sha1_hash - target_field: threatintel.indicator.file.hash.sha1 + field: abusech.malwarebazaar.sha1_hash + target_field: threat.indicator.file.hash.sha1 ignore_missing: true - rename: - field: threatintel.malwarebazaar.sha3_384_hash - target_field: threatintel.indicator.file.hash.sha384 + field: abusech.malwarebazaar.sha3_384_hash + target_field: threat.indicator.file.hash.sha384 ignore_missing: true - rename: - field: threatintel.malwarebazaar.imphash - target_field: threatintel.indicator.file.pe.imphash + field: abusech.malwarebazaar.imphash + target_field: threat.indicator.file.pe.imphash ignore_missing: true - rename: - field: threatintel.malwarebazaar.ssdeep - target_field: threatintel.indicator.file.hash.ssdeep + field: abusech.malwarebazaar.ssdeep + target_field: threat.indicator.file.hash.ssdeep ignore_missing: true - rename: - field: threatintel.malwarebazaar.tlsh - target_field: threatintel.indicator.file.hash.tlsh + field: abusech.malwarebazaar.tlsh + target_field: threat.indicator.file.hash.tlsh ignore_missing: true - rename: - field: threatintel.malwarebazaar.telfhash - target_field: threatintel.indicator.file.elf.telfhash + field: abusech.malwarebazaar.telfhash + target_field: threat.indicator.file.elf.telfhash ignore_missing: true - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.md5 }}" - if: ctx?.threatintel?.indicator?.file?.hash?.md5 != null + value: "{{ threat.indicator.file.hash.md5 }}" + if: ctx?.threat?.indicator?.file?.hash?.md5 != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.sha256 }}" - if: ctx?.threatintel?.indicator?.file?.hash?.sha256 != null + value: "{{ threat.indicator.file.hash.sha256 }}" + if: ctx?.threat?.indicator?.file?.hash?.sha256 != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.ssdeep }}" - if: ctx?.threatintel?.indicator?.file?.hash?.ssdeep != null + value: "{{ threat.indicator.file.hash.ssdeep }}" + if: ctx?.threat?.indicator?.file?.hash?.ssdeep != null - append: field: related.hash - value: "{{ threatintel.indicator.file.pe.imphash }}" - if: ctx?.threatintel?.indicator?.file?.pe?.imphash != null + value: "{{ threat.indicator.file.pe.imphash }}" + if: ctx?.threat?.indicator?.file?.pe?.imphash != null - append: field: related.hash - value: "{{ threatintel.indicator.file.elf.telfhash }}" - if: ctx?.threatintel?.indicator?.file?.elf?.telfhash != null + value: "{{ threat.indicator.file.elf.telfhash }}" + if: ctx?.threat?.indicator?.file?.elf?.telfhash != null - append: field: related.hash - value: "{{ threatintel.indicator.file.hash.tlsh }}" - if: ctx?.threatintel?.indicator?.file?.hash?.tlsh != null + value: "{{ threat.indicator.file.hash.tlsh }}" + if: ctx?.threat?.indicator?.file?.hash?.tlsh != null - convert: - field: threatintel.indicator.file.size + field: threat.indicator.file.size type: long ignore_missing: true - convert: - field: threatintel.malwarebazaar.intelligence.downloads + field: abusech.malwarebazaar.intelligence.downloads type: long ignore_missing: true - convert: - field: threatintel.malwarebazaar.intelligence.uploads + field: abusech.malwarebazaar.intelligence.uploads type: long ignore_missing: true @@ -169,12 +207,12 @@ processors: # Cleanup processors # ###################### - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx?.threat?.indicator?.type == null - script: lang: painless - if: ctx?.threatintel != null + if: ctx?.abusech != null source: | void handleMap(Map map) { for (def x : map.values()) { @@ -196,10 +234,15 @@ processors: } } handleMap(ctx); + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - remove: field: - - threatintel.malwarebazaar.first_seen - - threatintel.malwarebazaar.last_seen + - abusech.malwarebazaar.first_seen + - abusech.malwarebazaar.last_seen - message ignore_missing: true on_failure: diff --git a/x-pack/filebeat/module/threatintel/malwarebazaar/manifest.yml b/x-pack/filebeat/module/threatintel/malwarebazaar/manifest.yml index e9294ca9e2e2..b90ea0d95628 100644 --- a/x-pack/filebeat/module/threatintel/malwarebazaar/manifest.yml +++ b/x-pack/filebeat/module/threatintel/malwarebazaar/manifest.yml @@ -11,6 +11,8 @@ var: - name: tags default: [threatintel-malwarebazaar, forwarded] - name: proxy_url + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/malwarebazaar/test/malwarebazaar.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/malwarebazaar/test/malwarebazaar.ndjson.log-expected.json index 1d84eda36cb2..40b3f4289ec1 100644 --- a/x-pack/filebeat/module/threatintel/malwarebazaar/test/malwarebazaar.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/malwarebazaar/test/malwarebazaar.ndjson.log-expected.json @@ -1,5 +1,12 @@ [ { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 15, + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "exe" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -20,30 +27,29 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "exe", - "threatintel.indicator.file.hash.md5": "0af07660056a692b7cb82fa329221ddd", - "threatintel.indicator.file.hash.sha1": "a71fd0504821092e003f350080a6bcc5fa6a972e", - "threatintel.indicator.file.hash.sha256": "5bce7d528c1363104a93fbb5a7fa9bdd991ce929cc09cc7fb29052a68d4fd24b", - "threatintel.indicator.file.hash.sha384": "3b454eb6421d17d093f19292b64d30bf918cb91e9322d0e2d2512857997f574ea2ca5b005133c16f6c33c7cee9c1bd0e", - "threatintel.indicator.file.hash.ssdeep": "3072:DsPPK3p+8r5igrL1Tq50cVBDmDJhE9yV4veedHrP6FXK7:D+PL8bronBDmDJ69JeedHriFG", - "threatintel.indicator.file.hash.tlsh": "F9848B24AF932F9BC6CCC1FE50C2D165C9A9F85DD2B1251A73B6CB89FE00544ED2C686", - "threatintel.indicator.file.mime_type": "application/x-dosexec", - "threatintel.indicator.file.name": "SALM0BRU.exe", - "threatintel.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", - "threatintel.indicator.file.size": 399872, - "threatintel.indicator.first_seen": "2021-04-06T20:34:58.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.provider": "James_inthe_box", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 15, - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "exe" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "exe", + "threat.indicator.file.hash.md5": "0af07660056a692b7cb82fa329221ddd", + "threat.indicator.file.hash.sha1": "a71fd0504821092e003f350080a6bcc5fa6a972e", + "threat.indicator.file.hash.sha256": "5bce7d528c1363104a93fbb5a7fa9bdd991ce929cc09cc7fb29052a68d4fd24b", + "threat.indicator.file.hash.sha384": "3b454eb6421d17d093f19292b64d30bf918cb91e9322d0e2d2512857997f574ea2ca5b005133c16f6c33c7cee9c1bd0e", + "threat.indicator.file.hash.ssdeep": "3072:DsPPK3p+8r5igrL1Tq50cVBDmDJhE9yV4veedHrP6FXK7:D+PL8bronBDmDJ69JeedHriFG", + "threat.indicator.file.hash.tlsh": "F9848B24AF932F9BC6CCC1FE50C2D165C9A9F85DD2B1251A73B6CB89FE00544ED2C686", + "threat.indicator.file.mime_type": "application/x-dosexec", + "threat.indicator.file.name": "SALM0BRU.exe", + "threat.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", + "threat.indicator.file.size": 399872, + "threat.indicator.first_seen": "2021-04-06T20:34:58.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.provider": "James_inthe_box", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 11, + "abusech.malwarebazaar.intelligence.uploads": 1, "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -63,26 +69,31 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "zip", - "threatintel.indicator.file.hash.md5": "296aad7075596d21516b30bfbc17fcac", - "threatintel.indicator.file.hash.sha1": "c454be4eb0892d61a4ad6bac16f97724e73cd795", - "threatintel.indicator.file.hash.sha256": "83d0429a2c5f1b611ebc30391eeeb75bebb51212ee1af51dbcf2624b48f9d27f", - "threatintel.indicator.file.hash.sha384": "0a1536add280715320040d5ac5340d3b205d90045ff5c90993b8e909edb9b3e9338b3ffbb3febcaf82584d00d516e8c7", - "threatintel.indicator.file.hash.ssdeep": "12288:j++y4mulTPaYJSaHwvJblQpLGwYeHU9vPpNGd+Zr:j3HPaMtQxblje01pNHZr", - "threatintel.indicator.file.hash.tlsh": "74A4233B9A6D5CA02B224AA69F37537D13A8406300944EAEFD375CA431583056B9F6FF", - "threatintel.indicator.file.mime_type": "application/zip", - "threatintel.indicator.file.name": "PO_NO.ENQUIRY-210604.zip", - "threatintel.indicator.file.size": 476768, - "threatintel.indicator.first_seen": "2021-04-06T20:32:25.000Z", - "threatintel.indicator.geo.country_iso_code": "US", - "threatintel.indicator.provider": "GovCERT_CH", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 11, - "threatintel.malwarebazaar.intelligence.uploads": 1 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "zip", + "threat.indicator.file.hash.md5": "296aad7075596d21516b30bfbc17fcac", + "threat.indicator.file.hash.sha1": "c454be4eb0892d61a4ad6bac16f97724e73cd795", + "threat.indicator.file.hash.sha256": "83d0429a2c5f1b611ebc30391eeeb75bebb51212ee1af51dbcf2624b48f9d27f", + "threat.indicator.file.hash.sha384": "0a1536add280715320040d5ac5340d3b205d90045ff5c90993b8e909edb9b3e9338b3ffbb3febcaf82584d00d516e8c7", + "threat.indicator.file.hash.ssdeep": "12288:j++y4mulTPaYJSaHwvJblQpLGwYeHU9vPpNGd+Zr:j3HPaMtQxblje01pNHZr", + "threat.indicator.file.hash.tlsh": "74A4233B9A6D5CA02B224AA69F37537D13A8406300944EAEFD375CA431583056B9F6FF", + "threat.indicator.file.mime_type": "application/zip", + "threat.indicator.file.name": "PO_NO.ENQUIRY-210604.zip", + "threat.indicator.file.size": 476768, + "threat.indicator.first_seen": "2021-04-06T20:32:25.000Z", + "threat.indicator.geo.country_iso_code": "US", + "threat.indicator.provider": "GovCERT_CH", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 30, + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "Hancitor" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -103,31 +114,34 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "dll", - "threatintel.indicator.file.hash.md5": "a4838dd31c672122441bebcbf7e9d277", - "threatintel.indicator.file.hash.sha1": "bf103996196df8255881127dee103c22fc12bef3", - "threatintel.indicator.file.hash.sha256": "f4910ea08d14eeb634084de47cf590d4dc5e554552f111da20d22ae71d7b425b", - "threatintel.indicator.file.hash.sha384": "ee7586cb085fde3c14c9c1bea4635ccb30b1af2020f64e87a9983e61b05026ec9b35255670a3d9ecaab436c4ba302dcc", - "threatintel.indicator.file.hash.ssdeep": "12288:L2X/txpFDEVkUNglTovKfoLy+hqK/cEUMMlGOG:RzglgLm/9lGOG", - "threatintel.indicator.file.hash.tlsh": "0C947D11BA96C473E572163008399F6A17BE7A900B704BDBE3CC097E4E755C24B36BA7", - "threatintel.indicator.file.mime_type": "application/x-dosexec", - "threatintel.indicator.file.name": "DropDll.dat", - "threatintel.indicator.file.pe.imphash": "0b5a952a025c2783c3126cdb9bef2844", - "threatintel.indicator.file.size": 435926, - "threatintel.indicator.first_seen": "2021-04-06T20:12:29.000Z", - "threatintel.indicator.geo.country_iso_code": "DE", - "threatintel.indicator.provider": "DmitriyMelikov", - "threatintel.indicator.signature": "Hancitor", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 30, - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "Hancitor" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "dll", + "threat.indicator.file.hash.md5": "a4838dd31c672122441bebcbf7e9d277", + "threat.indicator.file.hash.sha1": "bf103996196df8255881127dee103c22fc12bef3", + "threat.indicator.file.hash.sha256": "f4910ea08d14eeb634084de47cf590d4dc5e554552f111da20d22ae71d7b425b", + "threat.indicator.file.hash.sha384": "ee7586cb085fde3c14c9c1bea4635ccb30b1af2020f64e87a9983e61b05026ec9b35255670a3d9ecaab436c4ba302dcc", + "threat.indicator.file.hash.ssdeep": "12288:L2X/txpFDEVkUNglTovKfoLy+hqK/cEUMMlGOG:RzglgLm/9lGOG", + "threat.indicator.file.hash.tlsh": "0C947D11BA96C473E572163008399F6A17BE7A900B704BDBE3CC097E4E755C24B36BA7", + "threat.indicator.file.mime_type": "application/x-dosexec", + "threat.indicator.file.name": "DropDll.dat", + "threat.indicator.file.pe.imphash": "0b5a952a025c2783c3126cdb9bef2844", + "threat.indicator.file.size": 435926, + "threat.indicator.first_seen": "2021-04-06T20:12:29.000Z", + "threat.indicator.geo.country_iso_code": "DE", + "threat.indicator.provider": "DmitriyMelikov", + "threat.indicator.type": "file", + "threat.software.alias": "Hancitor" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 27, + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "backdoor", + "python" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -147,30 +161,31 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "unknown", - "threatintel.indicator.file.hash.md5": "8d7c8b55ac49d241fb7f75a27a5ef8d5", - "threatintel.indicator.file.hash.sha1": "a68ca1b41cb93fe2879bb3baeb8e19990758f099", - "threatintel.indicator.file.hash.sha256": "e45ffc61a85c2f5c0cbe9376ff215cad324bf14f925bf52ec0d2949f7d235a00", - "threatintel.indicator.file.hash.sha384": "788f61cf45bbc8cad5775de18d0d5f42c4e028af0aaa34c570645efc96af8ebc3d7fe330aaf22ef34d35360bbd4a708c", - "threatintel.indicator.file.hash.ssdeep": "192:z7X/yHo/yz/yBKiSOINLyhQMYd+LiTfq6LTf3ZoTta3Grj6rg2:z7CIKnNNLwufPfAPq7", - "threatintel.indicator.file.hash.tlsh": "AE3222515C6A881A03B3C66F7992B844FB588303C7116607F6FC86782F79568CAF1BBD", - "threatintel.indicator.file.mime_type": "text/x-script.python", - "threatintel.indicator.file.name": "vabsheche.py", - "threatintel.indicator.file.size": 11717, - "threatintel.indicator.first_seen": "2021-04-06T20:07:59.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.provider": "ArkbirdDevil", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 27, - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "backdoor", - "python" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "unknown", + "threat.indicator.file.hash.md5": "8d7c8b55ac49d241fb7f75a27a5ef8d5", + "threat.indicator.file.hash.sha1": "a68ca1b41cb93fe2879bb3baeb8e19990758f099", + "threat.indicator.file.hash.sha256": "e45ffc61a85c2f5c0cbe9376ff215cad324bf14f925bf52ec0d2949f7d235a00", + "threat.indicator.file.hash.sha384": "788f61cf45bbc8cad5775de18d0d5f42c4e028af0aaa34c570645efc96af8ebc3d7fe330aaf22ef34d35360bbd4a708c", + "threat.indicator.file.hash.ssdeep": "192:z7X/yHo/yz/yBKiSOINLyhQMYd+LiTfq6LTf3ZoTta3Grj6rg2:z7CIKnNNLwufPfAPq7", + "threat.indicator.file.hash.tlsh": "AE3222515C6A881A03B3C66F7992B844FB588303C7116607F6FC86782F79568CAF1BBD", + "threat.indicator.file.mime_type": "text/x-script.python", + "threat.indicator.file.name": "vabsheche.py", + "threat.indicator.file.size": 11717, + "threat.indicator.first_seen": "2021-04-06T20:07:59.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.provider": "ArkbirdDevil", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 21, + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "maldoc" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -190,29 +205,32 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "docx", - "threatintel.indicator.file.hash.md5": "fe185f106730583156f39233f77f8019", - "threatintel.indicator.file.hash.sha1": "e8378aede9f26f09b7d503d79a05d67612be15f6", - "threatintel.indicator.file.hash.sha256": "42f5f5474431738f91f612d9765b3fc9b85a547274ea64aa034298ad97ad28f4", - "threatintel.indicator.file.hash.sha384": "752e5d56a166227d06f8cbd40cd3f693f543f9c3f798c673c1430957bb7e149a12d9158138fa449479105f472e70f68f", - "threatintel.indicator.file.hash.ssdeep": "196608:KQaeKLOiBEp+uc+iuYmbMdHmN1Rwyd2jecXeaH1pHE+2:oeIOTp+p+iNJC1ChjhXZ1pHz2", - "threatintel.indicator.file.hash.tlsh": "13863341B085EE2EE2CA41BA0DA9C2BD43B63D131E054F677269B72D3EB76E0E7D4144", - "threatintel.indicator.file.mime_type": "application/msword", - "threatintel.indicator.file.name": "42f5f5474431738f91f612d9765b3fc9b85a547274ea64aa034298ad97ad28f4.bin", - "threatintel.indicator.file.size": 7929856, - "threatintel.indicator.first_seen": "2021-04-06T20:00:48.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.provider": "ArkbirdDevil", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 21, - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "maldoc" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "docx", + "threat.indicator.file.hash.md5": "fe185f106730583156f39233f77f8019", + "threat.indicator.file.hash.sha1": "e8378aede9f26f09b7d503d79a05d67612be15f6", + "threat.indicator.file.hash.sha256": "42f5f5474431738f91f612d9765b3fc9b85a547274ea64aa034298ad97ad28f4", + "threat.indicator.file.hash.sha384": "752e5d56a166227d06f8cbd40cd3f693f543f9c3f798c673c1430957bb7e149a12d9158138fa449479105f472e70f68f", + "threat.indicator.file.hash.ssdeep": "196608:KQaeKLOiBEp+uc+iuYmbMdHmN1Rwyd2jecXeaH1pHE+2:oeIOTp+p+iNJC1ChjhXZ1pHz2", + "threat.indicator.file.hash.tlsh": "13863341B085EE2EE2CA41BA0DA9C2BD43B63D131E054F677269B72D3EB76E0E7D4144", + "threat.indicator.file.mime_type": "application/msword", + "threat.indicator.file.name": "42f5f5474431738f91f612d9765b3fc9b85a547274ea64aa034298ad97ad28f4.bin", + "threat.indicator.file.size": 7929856, + "threat.indicator.first_seen": "2021-04-06T20:00:48.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.provider": "ArkbirdDevil", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 30, + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "apt", + "tonto" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -233,31 +251,29 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "dll", - "threatintel.indicator.file.hash.md5": "70da6872b6b2da9ddc94d14b02302917", - "threatintel.indicator.file.hash.sha1": "b2da45913353bfc66d189455f9ad80ef26968143", - "threatintel.indicator.file.hash.sha256": "2d705f0b76f24a18e08163db2f187140ee9f03e43697a9ea0d840c829692d43c", - "threatintel.indicator.file.hash.sha384": "c82132559381b7b3b184b4ce8c7a58c301a46001621f346b637139f5987dee968ae2ef009a17b2388852b2db15a45b58", - "threatintel.indicator.file.hash.ssdeep": "1536:2NVi7z0r0lJRn6I8+YDgr1fnWG5Ff0+adgBYlCtMiQMX1c0E4JsWjcdonPv870E1:YM7zh8+Cofnp5eRm6riQ6OZoPv870E", - "threatintel.indicator.file.hash.tlsh": "A2D38C067790C071DAAF013908799E624B7F7D70DDB49D8B77841A8E69342D0AF3AB27", - "threatintel.indicator.file.mime_type": "application/x-dosexec", - "threatintel.indicator.file.name": "winlog.wll", - "threatintel.indicator.file.pe.imphash": "6476b7c4dd55eafbdf922a7ba1e2d5f9", - "threatintel.indicator.file.size": 131584, - "threatintel.indicator.first_seen": "2021-04-06T19:58:50.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.provider": "ArkbirdDevil", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 30, - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "apt", - "tonto" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "dll", + "threat.indicator.file.hash.md5": "70da6872b6b2da9ddc94d14b02302917", + "threat.indicator.file.hash.sha1": "b2da45913353bfc66d189455f9ad80ef26968143", + "threat.indicator.file.hash.sha256": "2d705f0b76f24a18e08163db2f187140ee9f03e43697a9ea0d840c829692d43c", + "threat.indicator.file.hash.sha384": "c82132559381b7b3b184b4ce8c7a58c301a46001621f346b637139f5987dee968ae2ef009a17b2388852b2db15a45b58", + "threat.indicator.file.hash.ssdeep": "1536:2NVi7z0r0lJRn6I8+YDgr1fnWG5Ff0+adgBYlCtMiQMX1c0E4JsWjcdonPv870E1:YM7zh8+Cofnp5eRm6riQ6OZoPv870E", + "threat.indicator.file.hash.tlsh": "A2D38C067790C071DAAF013908799E624B7F7D70DDB49D8B77841A8E69342D0AF3AB27", + "threat.indicator.file.mime_type": "application/x-dosexec", + "threat.indicator.file.name": "winlog.wll", + "threat.indicator.file.pe.imphash": "6476b7c4dd55eafbdf922a7ba1e2d5f9", + "threat.indicator.file.size": 131584, + "threat.indicator.first_seen": "2021-04-06T19:58:50.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.provider": "ArkbirdDevil", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 32, + "abusech.malwarebazaar.intelligence.uploads": 1, "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -277,26 +293,33 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "docx", - "threatintel.indicator.file.hash.md5": "de80e1d7d9f5b1c64ec9f8d4f5063989", - "threatintel.indicator.file.hash.sha1": "3d613d5678e43faeea1c636185a0b4c3ec80e742", - "threatintel.indicator.file.hash.sha256": "30787f32adc487311d764b19d4504fdeab08c0d385e2fa065bd8d5836c031606", - "threatintel.indicator.file.hash.sha384": "a3ec981ed158fe08cc2cd97303807cfbed147e59ccfd92fcaa9395c5718b4d9b892d6e9fa6337f5976dc1bd042562fe4", - "threatintel.indicator.file.hash.ssdeep": "24576:WKEiZxl3A4yJJG2dPQQCthXzglgLm/9lGO:WKEGByvGOQQC/XElga/9lGO", - "threatintel.indicator.file.hash.tlsh": "8635D001BA82C573D5621A35083ADBAA177E7D604F704ADBB3C83B2E5D355C14B32BA7", - "threatintel.indicator.file.mime_type": "application/msword", - "threatintel.indicator.file.name": "30787f32adc487311d764b19d4504fdeab08c0d385e2fa065bd8d5836c031606.bin.sample", - "threatintel.indicator.file.size": 1088000, - "threatintel.indicator.first_seen": "2021-04-06T19:58:44.000Z", - "threatintel.indicator.geo.country_iso_code": "DE", - "threatintel.indicator.provider": "DmitriyMelikov", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 32, - "threatintel.malwarebazaar.intelligence.uploads": 1 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "docx", + "threat.indicator.file.hash.md5": "de80e1d7d9f5b1c64ec9f8d4f5063989", + "threat.indicator.file.hash.sha1": "3d613d5678e43faeea1c636185a0b4c3ec80e742", + "threat.indicator.file.hash.sha256": "30787f32adc487311d764b19d4504fdeab08c0d385e2fa065bd8d5836c031606", + "threat.indicator.file.hash.sha384": "a3ec981ed158fe08cc2cd97303807cfbed147e59ccfd92fcaa9395c5718b4d9b892d6e9fa6337f5976dc1bd042562fe4", + "threat.indicator.file.hash.ssdeep": "24576:WKEiZxl3A4yJJG2dPQQCthXzglgLm/9lGO:WKEGByvGOQQC/XElga/9lGO", + "threat.indicator.file.hash.tlsh": "8635D001BA82C573D5621A35083ADBAA177E7D604F704ADBB3C83B2E5D355C14B32BA7", + "threat.indicator.file.mime_type": "application/msword", + "threat.indicator.file.name": "30787f32adc487311d764b19d4504fdeab08c0d385e2fa065bd8d5836c031606.bin.sample", + "threat.indicator.file.size": 1088000, + "threat.indicator.first_seen": "2021-04-06T19:58:44.000Z", + "threat.indicator.geo.country_iso_code": "DE", + "threat.indicator.provider": "DmitriyMelikov", + "threat.indicator.type": "file" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 38, + "abusech.malwarebazaar.intelligence.mail.Generic": "low", + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "SnakeKeylogger", + "exe" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -317,33 +340,35 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "exe", - "threatintel.indicator.file.hash.md5": "2759c73c986c6a757bf9d25621c5595a", - "threatintel.indicator.file.hash.sha1": "00b52e8ca1785d5086703ad8cff1d28fc3354934", - "threatintel.indicator.file.hash.sha256": "84f983067868de50e5b1553782c056c1f5b5118bb2084473ca4b6908f221cd3b", - "threatintel.indicator.file.hash.sha384": "138dc28a74d15c1f9797ce732e99097c8c6db4549cb17cb7b20c1c6738a170328e45aea2d4c3b593912f14a97f521c1d", - "threatintel.indicator.file.hash.ssdeep": "12288:8t11ulRZRLZNh4YeX6f6XmwNShqE73YXy7moh:S11gZpZNmBX06WmAcy7m0", - "threatintel.indicator.file.hash.tlsh": "23F4AE212684C9C0D93E67B4D43584F003BABD16D631F69F6E887C693EB32D2D63B646", - "threatintel.indicator.file.mime_type": "application/x-dosexec", - "threatintel.indicator.file.name": "Purchase Order.8000.scan.pdf...exe", - "threatintel.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", - "threatintel.indicator.file.size": 752128, - "threatintel.indicator.first_seen": "2021-04-06T19:52:32.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.provider": "James_inthe_box", - "threatintel.indicator.signature": "SnakeKeylogger", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 38, - "threatintel.malwarebazaar.intelligence.mail.Generic": "low", - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "SnakeKeylogger", - "exe" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "exe", + "threat.indicator.file.hash.md5": "2759c73c986c6a757bf9d25621c5595a", + "threat.indicator.file.hash.sha1": "00b52e8ca1785d5086703ad8cff1d28fc3354934", + "threat.indicator.file.hash.sha256": "84f983067868de50e5b1553782c056c1f5b5118bb2084473ca4b6908f221cd3b", + "threat.indicator.file.hash.sha384": "138dc28a74d15c1f9797ce732e99097c8c6db4549cb17cb7b20c1c6738a170328e45aea2d4c3b593912f14a97f521c1d", + "threat.indicator.file.hash.ssdeep": "12288:8t11ulRZRLZNh4YeX6f6XmwNShqE73YXy7moh:S11gZpZNmBX06WmAcy7m0", + "threat.indicator.file.hash.tlsh": "23F4AE212684C9C0D93E67B4D43584F003BABD16D631F69F6E887C693EB32D2D63B646", + "threat.indicator.file.mime_type": "application/x-dosexec", + "threat.indicator.file.name": "Purchase Order.8000.scan.pdf...exe", + "threat.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", + "threat.indicator.file.size": 752128, + "threat.indicator.first_seen": "2021-04-06T19:52:32.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.provider": "James_inthe_box", + "threat.indicator.type": "file", + "threat.software.alias": "SnakeKeylogger" }, { + "abusech.malwarebazaar.anonymous": 0, + "abusech.malwarebazaar.code_sign": [], + "abusech.malwarebazaar.intelligence.downloads": 40, + "abusech.malwarebazaar.intelligence.mail.Generic": "low", + "abusech.malwarebazaar.intelligence.uploads": 1, + "abusech.malwarebazaar.tags": [ + "AgentTesla", + "exe" + ], "event.category": "threat", "event.dataset": "threatintel.malwarebazaar", "event.kind": "enrichment", @@ -364,30 +389,23 @@ "forwarded", "threatintel-malwarebazaar" ], - "threatintel.indicator.file.extension": "exe", - "threatintel.indicator.file.hash.md5": "596b3dbf07a287dcf76860b5e54762c3", - "threatintel.indicator.file.hash.sha1": "a34fd5e57d75d17bc2d84055ca4752e5ee2e92f5", - "threatintel.indicator.file.hash.sha256": "0661d87116f44cbd5b5c6bec7fb06c4e5cd5b6ecbc5455d959e65f1ee46c54c8", - "threatintel.indicator.file.hash.sha384": "ed5d03454121d81adf65a01ba90af81b1a7cea052709c22bb9170508069d17242861f85e5546b2cc3efb07c10926368c", - "threatintel.indicator.file.hash.ssdeep": "12288:qRedcNeqimzAEmN03VgdZfBOMx+RVBM7pdWje9ppB5nAZGNY2:ZaNeqikqN0udZfBFUYp55nFN", - "threatintel.indicator.file.hash.tlsh": "A505CF712694C9A4FABD53B80434403007F5FE42E232FA9A6FD17C993E72782DA3B655", - "threatintel.indicator.file.mime_type": "application/x-dosexec", - "threatintel.indicator.file.name": "New Order PO#121012020_____PDF_______.exe", - "threatintel.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", - "threatintel.indicator.file.size": 836096, - "threatintel.indicator.first_seen": "2021-04-06T19:47:13.000Z", - "threatintel.indicator.geo.country_iso_code": "FR", - "threatintel.indicator.provider": "James_inthe_box", - "threatintel.indicator.signature": "AgentTesla", - "threatintel.indicator.type": "file", - "threatintel.malwarebazaar.anonymous": 0, - "threatintel.malwarebazaar.code_sign": [], - "threatintel.malwarebazaar.intelligence.downloads": 40, - "threatintel.malwarebazaar.intelligence.mail.Generic": "low", - "threatintel.malwarebazaar.intelligence.uploads": 1, - "threatintel.malwarebazaar.tags": [ - "AgentTesla", - "exe" - ] + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] AbuseCH MalwareBazaar", + "threat.indicator.file.extension": "exe", + "threat.indicator.file.hash.md5": "596b3dbf07a287dcf76860b5e54762c3", + "threat.indicator.file.hash.sha1": "a34fd5e57d75d17bc2d84055ca4752e5ee2e92f5", + "threat.indicator.file.hash.sha256": "0661d87116f44cbd5b5c6bec7fb06c4e5cd5b6ecbc5455d959e65f1ee46c54c8", + "threat.indicator.file.hash.sha384": "ed5d03454121d81adf65a01ba90af81b1a7cea052709c22bb9170508069d17242861f85e5546b2cc3efb07c10926368c", + "threat.indicator.file.hash.ssdeep": "12288:qRedcNeqimzAEmN03VgdZfBOMx+RVBM7pdWje9ppB5nAZGNY2:ZaNeqikqN0udZfBFUYp55nFN", + "threat.indicator.file.hash.tlsh": "A505CF712694C9A4FABD53B80434403007F5FE42E232FA9A6FD17C993E72782DA3B655", + "threat.indicator.file.mime_type": "application/x-dosexec", + "threat.indicator.file.name": "New Order PO#121012020_____PDF_______.exe", + "threat.indicator.file.pe.imphash": "f34d5f2d4577ed6d9ceec516c1f5a744", + "threat.indicator.file.size": 836096, + "threat.indicator.first_seen": "2021-04-06T19:47:13.000Z", + "threat.indicator.geo.country_iso_code": "FR", + "threat.indicator.provider": "James_inthe_box", + "threat.indicator.type": "file", + "threat.software.alias": "AgentTesla" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/misp/config/config.yml b/x-pack/filebeat/module/threatintel/misp/config/config.yml index 922f794af204..53ce56b16a29 100644 --- a/x-pack/filebeat/module/threatintel/misp/config/config.yml +++ b/x-pack/filebeat/module/threatintel/misp/config/config.yml @@ -12,18 +12,24 @@ request.proxy_url: {{ .proxy_url }} {{ end }} request.url: {{ .url }} request.body: - limit: 100 - page: 1 - returnFormat: json -{{if .filters}} - {{ range $key, $value := .filters}}{{$key}}: {{$value | tojson}}{{end}} -{{end}} +{{ if .filters }} + {{ .filters | tojson}} +{{ end }} request.transforms: {{ if .api_token }} - set: target: header.Authorization value: {{ .api_token }} -{{end}} +{{ end }} +- set: + target: body.page + value: 1 +- set: + target: body.limit + value: 10 +- set: + target: body.returnFormat + value: json - set: target: body.timestamp value: '[[.cursor.timestamp]]' @@ -63,28 +69,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: - - json.Event.Attribute.uuid - - json.Event.Object.Attribute.uuid - ignore_missing: true - target_field: "@metadata._id" - encoding: base64 - - script: - lang: javascript - id: my_filter - source: > - function process(event) { - event.Put("@metadata.op_type", "index"); - } - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml index e64379422db6..f4f54c903b9b 100644 --- a/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml @@ -1,3 +1,4 @@ +--- description: Pipeline for parsing MISP Threat Intel processors: #################### @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -19,236 +23,253 @@ processors: ###################### # General ECS fields # ###################### + - rename: + field: message + target_field: event.original + ignore_missing: true + - json: + field: event.original + target_field: json + - fingerprint: + fields: + - json.Event.Attribute.uuid + - json.Event.Object.Attribute.uuid + target_field: "_id" + ignore_missing: true - rename: field: json.Event - target_field: threatintel.misp + target_field: misp ignore_missing: true - set: - field: threatintel.indicator.provider + field: threat.indicator.provider value: misp - if: ctx?.threatintel?.misp?.Orgc?.local != 'false' + if: ctx.misp?.Orgc?.local != 'false' - set: - field: threatintel.indicator.provider + field: threat.indicator.provider value: "{{misp.Orgc.name}}" - if: ctx?.threatintel?.misp?.Orgc?.local == 'false' + if: ctx.misp?.Orgc?.local == 'false' ignore_empty_value: true # Removing fields not needed anymore, either because its copied somewhere else, or is not relevant to this event - remove: field: - - threatintel.misp.ShadowAttribute - - threatintel.misp.RelatedEvent - - threatintel.misp.Galaxy - - threatintel.misp.Attribute.Galaxy - - threatintel.misp.Attribute.ShadowAttribute - - threatintel.misp.EventReport - - threatintel.misp.Object.Attribute.Galaxy - - threatintel.misp.Object.Attribute.ShadowAttribute - - message + - misp.ShadowAttribute + - misp.RelatedEvent + - misp.Galaxy + - misp.Attribute.Galaxy + - misp.Attribute.ShadowAttribute + - misp.EventReport + - misp.Object.Attribute.Galaxy + - misp.Object.Attribute.ShadowAttribute ignore_missing: true - remove: field: - - threatintel.misp.Attribute + - misp.Attribute ignore_missing: true - if: ctx?.threatintel?.misp?.Attribute.size() == 0 + if: ctx.misp?.Attribute.size() == 0 - remove: field: - - threatintel.misp.Object + - misp.Object ignore_missing: true - if: ctx?.threatintel?.misp?.Object.size() == 0 + if: ctx.misp?.Object.size() == 0 - date: - field: threatintel.misp.timestamp + field: misp.timestamp formats: - UNIX ignore_failure: true - rename: - field: threatintel.misp.Attribute - target_field: threatintel.misp.attribute + field: misp.Attribute + target_field: misp.attribute ignore_missing: true - rename: - field: threatintel.misp.Object - target_field: threatintel.misp.object + field: misp.Object + target_field: misp.object ignore_missing: true - rename: - field: threatintel.misp.object.Attribute - target_field: threatintel.misp.object.attribute + field: misp.object.Attribute + target_field: misp.object.attribute ignore_missing: true - rename: - field: threatintel.misp.Orgc - target_field: threatintel.misp.orgc + field: misp.Orgc + target_field: misp.orgc ignore_missing: true - rename: - field: threatintel.misp.Org - target_field: threatintel.misp.org + field: misp.Org + target_field: misp.org ignore_missing: true - rename: - field: threatintel.misp.Tag - target_field: threatintel.misp.tag + field: misp.Tag + target_field: misp.tag ignore_missing: true # # Dance around issue of not being able to split the document into two. # # Make the Object.Attribute field primary if it exists, but keep the # # outer Attribute as context. - rename: - field: threatintel.misp.attribute - target_field: threatintel.misp.context.attribute + field: misp.attribute + target_field: misp.context.attribute ignore_missing: true - if: ctx?.threatintel?.misp?.object != null + if: ctx.misp?.object != null - rename: - field: threatintel.misp.object.attribute - target_field: threatintel.misp.attribute + field: misp.object.attribute + target_field: misp.attribute ignore_missing: true - if: ctx?.threatintel?.misp?.object != null + if: ctx.misp?.object != null ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] MISP" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" - rename: - field: threatintel.misp.attribute.first_seen - target_field: threatintel.indicator.first_seen + field: misp.attribute.first_seen + target_field: threat.indicator.first_seen ignore_missing: true - rename: - field: threatintel.misp.attribute.last_seen - target_field: threatintel.indicator.last_seen + field: misp.attribute.last_seen + target_field: threat.indicator.last_seen ignore_missing: true - convert: - field: threatintel.misp.analysis + field: misp.analysis type: long - target_field: threatintel.indicator.scanner_stats + target_field: threat.indicator.scanner_stats ignore_missing: true - convert: - field: threatintel.misp.threat_level_id + field: misp.threat_level_id type: long ignore_missing: true ## File/Hash indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx?.threatintel?.misp?.attribute?.type != null && (['md5', 'impfuzzy', 'imphash', 'pehash', 'sha1', 'sha224', 'sha256', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'tlsh', 'vhash'].contains(ctx.threatintel?.misp?.attribute?.type) || ctx.threatintel?.misp?.attribute?.type.startsWith('filename'))" + if: "ctx.misp?.attribute?.type != null && (['md5', 'impfuzzy', 'imphash', 'pehash', 'sha1', 'sha224', 'sha256', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'tlsh', 'vhash'].contains(ctx.misp?.attribute?.type) || ctx.misp?.attribute?.type.startsWith('filename'))" - rename: - field: threatintel.misp.attribute.value - target_field: "threatintel.indicator.file.hash.{{threatintel.misp.attribute.type}}" + field: misp.attribute.value + target_field: "threat.indicator.file.hash.{{misp.attribute.type}}" ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'file' && ctx?.threatintel?.misp?.attribute?.type != null && !ctx?.threatintel?.misp?.attribute?.type.startsWith('filename')" + if: "ctx.threat?.indicator?.type == 'file' && ctx.misp?.attribute?.type != null && !ctx.misp?.attribute?.type.startsWith('filename')" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.file.name + field: misp.attribute.value + target_field: threat.indicator.file.name ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'file' && ctx?.threatintel?.misp?.attribute?.type == 'filename'" + if: "ctx.threat?.indicator?.type == 'file' && ctx.misp?.attribute?.type == 'filename'" - grok: - field: threatintel.misp.attribute.type + field: misp.attribute.type patterns: - "%{WORD}\\|%{WORD:_tmp.hashtype}" ignore_missing: true - if: ctx?.threatintel?.misp?.attribute?.type != null && ctx?.threatintel?.misp?.attribute?.type.startsWith('filename|') + if: ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type.startsWith('filename|') - grok: - field: threatintel.misp.attribute.value + field: misp.attribute.value patterns: - - "%{DATA:threatintel.indicator.file.name}\\|%{GREEDYDATA:_tmp.hashvalue}" + - "%{DATA:threat.indicator.file.name}\\|%{GREEDYDATA:_tmp.hashvalue}" ignore_missing: true - if: ctx?.threatintel?.misp?.attribute?.type != null && ctx?.threatintel?.misp?.attribute?.type.startsWith('filename|') + if: ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type.startsWith('filename|') - set: - field: threatintel.indicator.file.hash.{{_tmp.hashtype}} + field: threat.indicator.file.hash.{{_tmp.hashtype}} value: "{{_tmp.hashvalue}}" - if: "ctx?.threatintel?.misp?.attribute?.type != null && ctx?.threatintel?.misp?.attribute?.type.startsWith('filename|') && ctx?._tmp?.hashvalue != null && ctx?._tmp?.hashtype != null" + if: "ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type.startsWith('filename|') && ctx?._tmp?.hashvalue != null && ctx?._tmp?.hashtype != null" ## URL/URI indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: url - if: "ctx?.threatintel?.misp?.attribute?.type != null && ['url', 'link', 'uri'].contains(ctx?.threatintel?.misp?.attribute?.type)" + if: "ctx.misp?.attribute?.type != null && ['url', 'link', 'uri'].contains(ctx.misp?.attribute?.type)" - uri_parts: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.url + field: misp.attribute.value + target_field: threat.indicator.url keep_original: true remove_if_successful: true - if: ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.misp?.attribute?.type != 'uri' - + if: ctx.threat?.indicator?.type == 'url' && ctx.misp?.attribute?.type != 'uri' - set: - field: threatintel.indicator.url.full - value: "{{{threatintel.indicator.url.original}}}" + field: threat.indicator.url.full + value: "{{{threat.indicator.url.original}}}" ignore_empty_value: true - if: "ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.misp?.attribute?.type != 'uri'" + if: "ctx.threat?.indicator?.type == 'url' && ctx.misp?.attribute?.type != 'uri'" ## Regkey indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: windows-registry-key - if: "ctx?.threatintel?.misp?.attribute?.type != null && ctx?.threatintel?.misp?.attribute?.type.startsWith('regkey')" + if: "ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type.startsWith('regkey')" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.registry.key + field: misp.attribute.value + target_field: threat.indicator.registry.key ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'windows-registry-key' && ctx?.threatintel?.misp?.attribute?.type == 'regkey'" + if: "ctx.threat?.indicator?.type == 'windows-registry-key' && ctx.misp?.attribute?.type == 'regkey'" - grok: - field: threatintel.misp.attribute.value + field: misp.attribute.value patterns: - - "%{DATA:threatintel.indicator.registry.key}\\|%{DATA:threatintel.indicator.registry.value}" + - "%{DATA:threat.indicator.registry.key}\\|%{DATA:threat.indicator.registry.value}" ignore_missing: true - if: "ctx?.threatintel?.misp?.attribute?.type == 'regkey|value'" + if: "ctx.misp?.attribute?.type == 'regkey|value'" ## AS indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: autonomous-system - if: "ctx?.threatintel?.misp?.attribute?.type != null && ctx?.threatintel?.misp?.attribute?.type == 'AS'" + if: "ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type == 'AS'" - convert: - field: threatintel.misp.attribute.value + field: misp.attribute.value type: long - target_field: threatintel.indicator.as.number + target_field: threat.indicator.as.number ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'autonomous-system' + if: ctx.threat?.indicator?.type == 'autonomous-system' ## Domain/IP/Port indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: domain-name - if: "ctx?.threatintel?.misp?.attribute?.type != null && (ctx?.threatintel?.misp?.attribute?.type == 'hostname' || ctx?.threatintel?.misp?.attribute?.type.startsWith('domain'))" + if: "ctx.misp?.attribute?.type != null && (ctx.misp?.attribute?.type == 'hostname' || ctx.misp?.attribute?.type.startsWith('domain'))" - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv4-addr - if: "ctx?.threatintel?.misp?.attribute?.type != null && ['ip-src', 'ip-src|port', 'ip-dst', 'ip-dst|port'].contains(ctx?.threatintel?.misp?.attribute?.type)" + if: "ctx.misp?.attribute?.type != null && ['ip-src', 'ip-src|port', 'ip-dst', 'ip-dst|port'].contains(ctx.misp?.attribute?.type)" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.url.domain + field: misp.attribute.value + target_field: threat.indicator.url.domain ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'domain-name' && ctx?.threatintel?.misp?.attribute?.type != 'domain|ip' && ctx.threatintel?.indicator?.url?.domain == null" + if: "ctx.threat?.indicator?.type == 'domain-name' && ctx.misp?.attribute?.type != 'domain|ip' && ctx.threat?.indicator?.url?.domain == null" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.ip + field: misp.attribute.value + target_field: threat.indicator.ip ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'ipv4-addr' && ctx?.threatintel?.misp?.attribute?.type != 'domain|ip' && !['ip-src|port', 'ip-dst|port'].contains(ctx?.threatintel?.misp?.attribute?.type)" + if: "ctx.threat?.indicator?.type == 'ipv4-addr' && ctx.misp?.attribute?.type != 'domain|ip' && !['ip-src|port', 'ip-dst|port'].contains(ctx.misp?.attribute?.type)" - grok: - field: threatintel.misp.attribute.value + field: misp.attribute.value patterns: - - "%{DATA:threatintel.indicator.url.domain}\\|%{IP:threatintel.indicator.ip}" + - "%{DATA:threat.indicator.url.domain}\\|%{IP:threat.indicator.ip}" ignore_missing: true - if: ctx.threatintel?.misp?.attribute?.type == 'domain|ip' && ctx.threatintel?.indicator?.url?.domain == null + if: ctx.misp?.attribute?.type == 'domain|ip' && ctx.threat?.indicator?.url?.domain == null - grok: - field: threatintel.misp.attribute.value + field: misp.attribute.value patterns: - - "%{IP:threatintel.indicator.ip}\\|%{NUMBER:threatintel.indicator.port}" + - "%{IP:threat.indicator.ip}\\|%{NUMBER:threat.indicator.port}" ignore_missing: true - if: "['ip-src|port', 'ip-dst|port'].contains(ctx.threatintel?.misp?.attribute?.type)" + if: "['ip-src|port', 'ip-dst|port'].contains(ctx.misp?.attribute?.type)" ## Email indicator operations # Currently this ignores email-message, except setting the type it will leave the rest of the fields under misp. - set: - field: threatintel.indicator.type + field: threat.indicator.type value: email-addr - if: "ctx?.threatintel?.misp?.attribute?.type != null && ['email-dst', 'email-src'].contains(ctx.threatintel?.misp?.attribute?.type)" + if: "ctx.misp?.attribute?.type != null && ['email-dst', 'email-src'].contains(ctx.misp?.attribute?.type)" - set: - field: threatintel.indicator.type + field: threat.indicator.type value: email-message - if: "ctx?.threatintel?.misp?.attribute?.type != null && ctx.threatintel?.misp?.attribute?.type.startsWith('email') && !['email-dst', 'email-src'].contains(ctx.threatintel?.misp?.attribute?.type)" + if: "ctx.misp?.attribute?.type != null && ctx.misp?.attribute?.type.startsWith('email') && !['email-dst', 'email-src'].contains(ctx.misp?.attribute?.type)" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.email.address + field: misp.attribute.value + target_field: threat.indicator.email.address ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'email-addr' + if: ctx.threat?.indicator?.type == 'email-addr' - rename: - field: threatintel.misp.event_creator_email + field: misp.event_creator_email target_field: user.email ignore_missing: true - append: @@ -258,14 +279,14 @@ processors: ## MAC Address indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: mac-addr - if: "ctx?.threatintel?.misp?.attribute?.type != null && ['mac-address', 'mac-eui-64'].contains(ctx.threatintel?.misp?.attribute?.type)" + if: "ctx.misp?.attribute?.type != null && ['mac-address', 'mac-eui-64'].contains(ctx.misp?.attribute?.type)" - rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.mac + field: misp.attribute.value + target_field: threat.indicator.mac ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'mac-addr' + if: ctx.threat?.indicator?.type == 'mac-addr' ################### # Tags ECS fields # @@ -273,9 +294,9 @@ processors: # Stripping special characters from tags - script: lang: painless - if: ctx?.threatintel?.misp?.tag != null + if: ctx.misp?.tag != null source: | - def tags = ctx.threatintel.misp.tag.stream() + def tags = ctx.misp.tag.stream() .map(t -> t.name.replace('\\', '').replace('"', '')) .collect(Collectors.toList()); def tlpTags = tags.stream() @@ -284,20 +305,45 @@ processors: .collect(Collectors.toList()); ctx.tags = tags; - ctx.threatintel.indicator.marking = [ 'tlp': tlpTags ]; + ctx.threat.indicator.marking = [ 'tlp': tlpTags ]; # Setting indicator type to unknown if it does not match anything - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx.threat?.indicator?.type == null + + ################# + # Convert types # + ################# + - convert: + field: misp.attribute.distribution + type: long + ignore_missing: true + - convert: + field: misp.context.attribute.distribution + type: long + ignore_missing: true + - convert: + field: threat.indicator.port + type: long + ignore_missing: true + - convert: + field: misp.attribute_count + type: long + ignore_missing: true ###################### # Cleanup processors # ###################### + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - script: lang: painless - if: ctx?.threatintel != null + if: ctx?.misp != null source: | void handleMap(Map map) { for (def x : map.values()) { @@ -322,24 +368,24 @@ processors: # Removing fields not needed anymore, either because its copied somewhere else, or is not relevant to this event - remove: field: - - threatintel.misp.attribute.value + - misp.attribute.value ignore_missing: true - if: ctx?.threatintel?.indicator?.type != 'unknown' + if: ctx.threat?.indicator?.type != 'unknown' - remove: field: # This removes a number of fields that may be wanted in the future when - # threatintel.misp.attribute and threatintel.misp.object.attribute can + # misp.attribute and misp.object.attribute can # be separated. At the root of .object are fields that mirror fields at - # the root of threatintel.misp. - - threatintel.misp.object + # the root of misp. + - misp.object ignore_missing: true - remove: field: - - threatintel.misp.Attribute.timestamp - - threatintel.misp.timestamp - - threatintel.misp.tag - - threatintel.misp.org - - threatintel.misp.analysis + - misp.Attribute.timestamp + - misp.timestamp + - misp.tag + - misp.org + - misp.analysis - _tmp - json ignore_missing: true diff --git a/x-pack/filebeat/module/threatintel/misp/manifest.yml b/x-pack/filebeat/module/threatintel/misp/manifest.yml index 41443c01df8d..3a91b68f4fed 100644 --- a/x-pack/filebeat/module/threatintel/misp/manifest.yml +++ b/x-pack/filebeat/module/threatintel/misp/manifest.yml @@ -15,6 +15,8 @@ var: - name: tags default: [threatintel-misp, forwarded] - name: proxy_url + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/misp/test/misp_sample.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/misp/test/misp_sample.ndjson.log-expected.json index 9f4dbc50fc83..04e12fc0323d 100644 --- a/x-pack/filebeat/module/threatintel/misp/test/misp_sample.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/misp/test/misp_sample.ndjson.log-expected.json @@ -9,6 +9,39 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 0, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "- Xchecked via VT: a683494fc0d017fd3b4638f8b84caaaac145cc28bc211bd7361723368b4bb21e", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "5", + "misp.attribute.id": "351", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1503930272", + "misp.attribute.to_ids": true, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "59a427a0-f6f8-4178-9e7d-dfd702de0b81", + "misp.attribute_count": 7, + "misp.date": "2017-08-25", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "5", + "misp.info": "OSINT - New Arena Crysis Ransomware Variant Released", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CIRCL", + "misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1603226331", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "59a3d08d-5dc8-4153-bc7c-456d950d210f", "service.type": "threatintel", "tags": [ "malware_classification:malware-category=Ransomware", @@ -17,46 +50,15 @@ "tlp:white", "type:OSINT" ], - "threatintel.indicator.file.hash.md5": "f2679bdabe46e10edc6352fff3c829bc", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "f2679bdabe46e10edc6352fff3c829bc", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "- Xchecked via VT: a683494fc0d017fd3b4638f8b84caaaac145cc28bc211bd7361723368b4bb21e", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "5", - "threatintel.misp.attribute.id": "351", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1503930272", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "59a427a0-f6f8-4178-9e7d-dfd702de0b81", - "threatintel.misp.attribute_count": "7", - "threatintel.misp.date": "2017-08-25", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "5", - "threatintel.misp.info": "OSINT - New Arena Crysis Ransomware Variant Released", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CIRCL", - "threatintel.misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1603226331", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "59a3d08d-5dc8-4153-bc7c-456d950d210f" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "file" }, { "@timestamp": "2017-08-28T14:24:36.000Z", @@ -68,6 +70,39 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 8248, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "1st stage", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "14", + "misp.attribute.id": "10794", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1542652482", + "misp.attribute.to_ids": false, + "misp.attribute.type": "domain|ip", + "misp.attribute.uuid": "5bf30242-8ef4-4c52-a2d7-0b7b0a016219", + "misp.attribute_count": 7, + "misp.date": "2017-08-25", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "5", + "misp.info": "OSINT - New Arena Crysis Ransomware Variant Released", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CIRCL", + "misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1603226331", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "59a3d08d-5dc8-4153-bc7c-456d950d210f", "service.type": "threatintel", "tags": [ "malware_classification:malware-category=Ransomware", @@ -76,47 +111,16 @@ "tlp:white", "type:OSINT" ], - "threatintel.indicator.ip": "178.128.103.74", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.ip": "178.128.103.74", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "your-ip.getmyip.com", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "1st stage", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "14", - "threatintel.misp.attribute.id": "10794", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1542652482", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "domain|ip", - "threatintel.misp.attribute.uuid": "5bf30242-8ef4-4c52-a2d7-0b7b0a016219", - "threatintel.misp.attribute_count": "7", - "threatintel.misp.date": "2017-08-25", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "5", - "threatintel.misp.info": "OSINT - New Arena Crysis Ransomware Variant Released", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CIRCL", - "threatintel.misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1603226331", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "59a3d08d-5dc8-4153-bc7c-456d950d210f" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "your-ip.getmyip.com" }, { "@timestamp": "2017-04-28T18:23:44.000Z", @@ -128,55 +132,57 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 16434, + "misp.attribute.category": "External analysis", + "misp.attribute.comment": "Carbon sample - Xchecked via VT: a08b8371ead1919500a4759c2f46553620d5a9d9", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "4", + "misp.attribute.id": "342", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1490878550", + "misp.attribute.to_ids": false, + "misp.attribute.type": "link", + "misp.attribute.uuid": "58dd0056-6e74-43d5-b58b-494802de0b81", + "misp.attribute_count": 100, + "misp.date": "2017-03-30", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "4", + "misp.info": "OSINT - Carbon Paper: Peering into Turla\u2019s second stage backdoor", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CIRCL", + "misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1603226330", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "58dcfe62-ed84-4e5e-b293-4991950d210f", "service.type": "threatintel", "tags": [ "misp-galaxy:tool=Turla", "tlp:white" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "www.virustotal.com", - "threatintel.indicator.url.full": "https://www.virustotal.com/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", - "threatintel.indicator.url.original": "https://www.virustotal.com/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", - "threatintel.indicator.url.path": "/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", - "threatintel.indicator.url.scheme": "https", - "threatintel.misp.attribute.category": "External analysis", - "threatintel.misp.attribute.comment": "Carbon sample - Xchecked via VT: a08b8371ead1919500a4759c2f46553620d5a9d9", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "4", - "threatintel.misp.attribute.id": "342", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1490878550", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "link", - "threatintel.misp.attribute.uuid": "58dd0056-6e74-43d5-b58b-494802de0b81", - "threatintel.misp.attribute_count": "100", - "threatintel.misp.date": "2017-03-30", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "4", - "threatintel.misp.info": "OSINT - Carbon Paper: Peering into Turla\u2019s second stage backdoor", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CIRCL", - "threatintel.misp.orgc.uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1603226330", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "58dcfe62-ed84-4e5e-b293-4991950d210f" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "url", + "threat.indicator.url.domain": "www.virustotal.com", + "threat.indicator.url.full": "https://www.virustotal.com/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", + "threat.indicator.url.original": "https://www.virustotal.com/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", + "threat.indicator.url.path": "/file/7fa4482bfbca550ce296d8e791b1091d60d733ea8042167fd0eb853530584452/analysis/1486030116/", + "threat.indicator.url.scheme": "https" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -188,51 +194,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 20139, + "misp.attribute.category": "External analysis", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "2", + "misp.attribute.id": "1077", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1412579394", + "misp.attribute.to_ids": true, + "misp.attribute.type": "sha256", + "misp.attribute.uuid": "54324042-49fc-4628-a95e-44da950d210b", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.file.hash.sha256": "0a1103bc90725d4665b932f88e81d39eafa5823b0de3ab146e2d4548b7da79a0", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha256": "0a1103bc90725d4665b932f88e81d39eafa5823b0de3ab146e2d4548b7da79a0", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "External analysis", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "2", - "threatintel.misp.attribute.id": "1077", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1412579394", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "sha256", - "threatintel.misp.attribute.uuid": "54324042-49fc-4628-a95e-44da950d210b", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "file" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -244,51 +252,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 21711, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "2", + "misp.attribute.id": "1084", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1412579457", + "misp.attribute.to_ids": true, + "misp.attribute.type": "ip-dst", + "misp.attribute.uuid": "54324081-3308-4f1f-8674-4953950d210b", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.ip": "223.25.233.248", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.ip": "223.25.233.248", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "ipv4-addr", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "2", - "threatintel.misp.attribute.id": "1084", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1412579457", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "ip-dst", - "threatintel.misp.attribute.uuid": "54324081-3308-4f1f-8674-4953950d210b", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "ipv4-addr" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -300,51 +310,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 23232, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "2", + "misp.attribute.id": "1086", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1412579548", + "misp.attribute.to_ids": true, + "misp.attribute.type": "hostname", + "misp.attribute.uuid": "543240dc-f068-437a-baa9-48f2950d210b", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "xenserver.ddns.net", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "2", - "threatintel.misp.attribute.id": "1086", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1412579548", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "hostname", - "threatintel.misp.attribute.uuid": "543240dc-f068-437a-baa9-48f2950d210b", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "xenserver.ddns.net" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -356,51 +368,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 24759, + "misp.attribute.category": "External analysis", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "2", + "misp.attribute.id": "1089", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1412579577", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "543240f9-64e8-41f2-958f-4e21950d210b", + "misp.attribute.value": "Nitro", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "External analysis", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "2", - "threatintel.misp.attribute.id": "1089", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1412579577", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "543240f9-64e8-41f2-958f-4e21950d210b", - "threatintel.misp.attribute.value": "Nitro", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "unknown" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -412,51 +426,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 26271, + "misp.attribute.category": "External analysis", + "misp.attribute.comment": "Automatically added (via 7915aabb2e66ff14841e4ef0fbff7486)", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "2", + "misp.attribute.id": "1090", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1455826343", + "misp.attribute.to_ids": true, + "misp.attribute.type": "sha1", + "misp.attribute.uuid": "56c625a7-f31c-460c-9ea1-c652950d210f", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.file.hash.sha1": "0ea76f1586c008932d90c991dfdd5042f3aac8ea", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha1": "0ea76f1586c008932d90c991dfdd5042f3aac8ea", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "External analysis", - "threatintel.misp.attribute.comment": "Automatically added (via 7915aabb2e66ff14841e4ef0fbff7486)", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "2", - "threatintel.misp.attribute.id": "1090", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1455826343", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "sha1", - "threatintel.misp.attribute.uuid": "56c625a7-f31c-460c-9ea1-c652950d210f", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "file" }, { "@timestamp": "2014-10-06T07:12:57.000Z", @@ -468,51 +484,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 27875, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "22", + "misp.attribute.id": "12394", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1462454963", + "misp.attribute.to_ids": false, + "misp.attribute.type": "domain", + "misp.attribute.uuid": "572b4ab3-1af0-4d91-9cd5-07a1c0a8ab16", + "misp.attribute_count": 29, + "misp.date": "2014-10-03", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "2", + "misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "2", + "misp.orgc.local": false, + "misp.orgc.name": "CthulhuSPRL.be", + "misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", + "misp.orgc_id": "2", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610622316", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b", "service.type": "threatintel", "tags": [ "tlp:green", "type:OSINT" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "green" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "whatsapp.com", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "22", - "threatintel.misp.attribute.id": "12394", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1462454963", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "domain", - "threatintel.misp.attribute.uuid": "572b4ab3-1af0-4d91-9cd5-07a1c0a8ab16", - "threatintel.misp.attribute_count": "29", - "threatintel.misp.date": "2014-10-03", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "2", - "threatintel.misp.info": "OSINT New Indicators of Compromise for APT Group Nitro Uncovered blog post by Palo Alto Networks", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "2", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CthulhuSPRL.be", - "threatintel.misp.orgc.uuid": "55f6ea5f-fd34-43b8-ac1d-40cb950d210f", - "threatintel.misp.orgc_id": "2", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610622316", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "54323f2c-e50c-4268-896c-4867950d210b" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "whatsapp.com" }, { "@timestamp": "2018-08-28T13:20:17.000Z", @@ -524,57 +542,59 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 29397, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "Fake adobe URL", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "158", + "misp.attribute.id": "17299", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1515427692", + "misp.attribute.to_ids": false, + "misp.attribute.type": "url", + "misp.attribute.uuid": "5a53976c-e7c8-480d-a68a-2fc50a016219", + "misp.attribute_count": 61, + "misp.date": "2018-01-08", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "158", + "misp.info": "Turla: Mosquito Whitepaper", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "5", + "misp.orgc.local": false, + "misp.orgc.name": "ESET", + "misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", + "misp.orgc_id": "5", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637953", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219", "service.type": "threatintel", "tags": [ "Turla", "misp-galaxy:threat-actor=Turla Group", "tlp:white" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "get.adobe.com", - "threatintel.indicator.url.full": "http://get.adobe.com/stats/AbfFcBebD/?q=", - "threatintel.indicator.url.original": "http://get.adobe.com/stats/AbfFcBebD/?q=", - "threatintel.indicator.url.path": "/stats/AbfFcBebD/", - "threatintel.indicator.url.query": "q=", - "threatintel.indicator.url.scheme": "http", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "Fake adobe URL", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "158", - "threatintel.misp.attribute.id": "17299", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1515427692", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "url", - "threatintel.misp.attribute.uuid": "5a53976c-e7c8-480d-a68a-2fc50a016219", - "threatintel.misp.attribute_count": "61", - "threatintel.misp.date": "2018-01-08", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "158", - "threatintel.misp.info": "Turla: Mosquito Whitepaper", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "5", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "ESET", - "threatintel.misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", - "threatintel.misp.orgc_id": "5", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637953", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "url", + "threat.indicator.url.domain": "get.adobe.com", + "threat.indicator.url.full": "http://get.adobe.com/stats/AbfFcBebD/?q=", + "threat.indicator.url.original": "http://get.adobe.com/stats/AbfFcBebD/?q=", + "threat.indicator.url.path": "/stats/AbfFcBebD/", + "threat.indicator.url.query": "q=", + "threat.indicator.url.scheme": "http" }, { "@timestamp": "2018-08-28T13:20:17.000Z", @@ -586,51 +606,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 31486, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "Win32 backdoor C&C URI", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "158", + "misp.attribute.id": "17330", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1515429089", + "misp.attribute.to_ids": false, + "misp.attribute.type": "uri", + "misp.attribute.uuid": "5a539ce1-3de0-4e34-8fc4-2fc50a016219", + "misp.attribute_count": 61, + "misp.date": "2018-01-08", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "158", + "misp.info": "Turla: Mosquito Whitepaper", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "5", + "misp.orgc.local": false, + "misp.orgc.name": "ESET", + "misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", + "misp.orgc_id": "5", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637953", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219", "service.type": "threatintel", "tags": [ "Turla", "misp-galaxy:threat-actor=Turla Group", "tlp:white" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "url", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "Win32 backdoor C&C URI", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "158", - "threatintel.misp.attribute.id": "17330", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1515429089", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "uri", - "threatintel.misp.attribute.uuid": "5a539ce1-3de0-4e34-8fc4-2fc50a016219", - "threatintel.misp.attribute_count": "61", - "threatintel.misp.date": "2018-01-08", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "158", - "threatintel.misp.info": "Turla: Mosquito Whitepaper", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "5", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "ESET", - "threatintel.misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", - "threatintel.misp.orgc_id": "5", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637953", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "url" }, { "@timestamp": "2018-08-28T13:20:17.000Z", @@ -642,53 +664,55 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 33567, + "misp.attribute.category": "Artifacts dropped", + "misp.attribute.comment": "JavaScript backdoor", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "158", + "misp.attribute.id": "17322", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1515429089", + "misp.attribute.to_ids": false, + "misp.attribute.type": "filename|sha1", + "misp.attribute.uuid": "5a539ce1-e6a0-426a-942c-2fc50a016219", + "misp.attribute_count": 61, + "misp.date": "2018-01-08", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "158", + "misp.info": "Turla: Mosquito Whitepaper", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "5", + "misp.orgc.local": false, + "misp.orgc.name": "ESET", + "misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", + "misp.orgc_id": "5", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637953", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219", "service.type": "threatintel", "tags": [ "Turla", "misp-galaxy:threat-actor=Turla Group", "tlp:white" ], - "threatintel.indicator.file.hash.sha1": "c51d288469df9f25e2fb7ac491918b3e579282ea", - "threatintel.indicator.file.name": "google_update_checker.js", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha1": "c51d288469df9f25e2fb7ac491918b3e579282ea", + "threat.indicator.file.name": "google_update_checker.js", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Artifacts dropped", - "threatintel.misp.attribute.comment": "JavaScript backdoor", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "158", - "threatintel.misp.attribute.id": "17322", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1515429089", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "filename|sha1", - "threatintel.misp.attribute.uuid": "5a539ce1-e6a0-426a-942c-2fc50a016219", - "threatintel.misp.attribute_count": "61", - "threatintel.misp.date": "2018-01-08", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "158", - "threatintel.misp.info": "Turla: Mosquito Whitepaper", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "5", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "ESET", - "threatintel.misp.orgc.uuid": "55f6ea5e-51ac-4344-bc8c-4170950d210f", - "threatintel.misp.orgc_id": "5", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637953", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "5a5395d1-40a0-45fc-b692-334a0a016219" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file" }, { "@timestamp": "2018-01-23T16:09:56.000Z", @@ -700,50 +724,52 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 35697, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "22", + "misp.attribute.id": "12268", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1456266422", + "misp.attribute.to_ids": true, + "misp.attribute.type": "email-src", + "misp.attribute.uuid": "56ccdcb6-4d6c-4e48-b955-52849062e56a", + "misp.attribute_count": 133, + "misp.date": "2015-12-08", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "22", + "misp.info": "Packrat: Seven Years of a South American Threat Actor", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "4", + "misp.orgc.local": false, + "misp.orgc.name": "CUDESO", + "misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", + "misp.orgc_id": "4", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637901", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "56ccdcaf-f7e4-40d8-bca1-51299062e56a", "service.type": "threatintel", "tags": [ "tlp:white" ], - "threatintel.indicator.email.address": "claudiobonadio88@gmail.com", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.email.address": "claudiobonadio88@gmail.com", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "email-addr", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "22", - "threatintel.misp.attribute.id": "12268", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1456266422", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "email-src", - "threatintel.misp.attribute.uuid": "56ccdcb6-4d6c-4e48-b955-52849062e56a", - "threatintel.misp.attribute_count": "133", - "threatintel.misp.date": "2015-12-08", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "22", - "threatintel.misp.info": "Packrat: Seven Years of a South American Threat Actor", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "4", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CUDESO", - "threatintel.misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", - "threatintel.misp.orgc_id": "4", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637901", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "56ccdcaf-f7e4-40d8-bca1-51299062e56a" + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "email-addr" }, { "@timestamp": "2018-01-23T16:09:56.000Z", @@ -755,50 +781,52 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 37011, + "misp.attribute.category": "Artifacts dropped", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "22", + "misp.attribute.id": "12298", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1456266454", + "misp.attribute.to_ids": true, + "misp.attribute.type": "regkey", + "misp.attribute.uuid": "56ccdcd6-f4b8-4383-9624-52849062e56a", + "misp.attribute_count": 133, + "misp.date": "2015-12-08", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "22", + "misp.info": "Packrat: Seven Years of a South American Threat Actor", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "4", + "misp.orgc.local": false, + "misp.orgc.name": "CUDESO", + "misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", + "misp.orgc_id": "4", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637901", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "56ccdcaf-f7e4-40d8-bca1-51299062e56a", "service.type": "threatintel", "tags": [ "tlp:white" ], - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.registry.key": "HKLM\\SOFTWARE\\Microsoft\\Active", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "windows-registry-key", - "threatintel.misp.attribute.category": "Artifacts dropped", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "22", - "threatintel.misp.attribute.id": "12298", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1456266454", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "regkey", - "threatintel.misp.attribute.uuid": "56ccdcd6-f4b8-4383-9624-52849062e56a", - "threatintel.misp.attribute_count": "133", - "threatintel.misp.date": "2015-12-08", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "22", - "threatintel.misp.info": "Packrat: Seven Years of a South American Threat Actor", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "4", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CUDESO", - "threatintel.misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", - "threatintel.misp.orgc_id": "4", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637901", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "56ccdcaf-f7e4-40d8-bca1-51299062e56a" + "threat.indicator.provider": "misp", + "threat.indicator.registry.key": "HKLM\\SOFTWARE\\Microsoft\\Active", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "windows-registry-key" }, { "@timestamp": "2020-12-13T14:03:16.000Z", @@ -810,51 +838,53 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 38330, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "On port 2222", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "10", + "misp.attribute.id": "10686", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1607517728", + "misp.attribute.to_ids": true, + "misp.attribute.type": "ip-dst|port", + "misp.attribute.uuid": "5fd0c620-a844-4ace-9710-a37bc0a8ab16", + "misp.attribute_count": 15, + "misp.date": "2020-12-09", + "misp.disable_correlation": false, + "misp.distribution": "3", + "misp.extends_uuid": "", + "misp.id": "10", + "misp.info": "Recent Qakbot (Qbot) activity", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "4", + "misp.orgc.local": false, + "misp.orgc.name": "CUDESO", + "misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", + "misp.orgc_id": "4", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "1610637888", + "misp.published": true, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "5fd0c599-ab6c-4ba1-a69a-df9ec0a8ab16", "service.type": "threatintel", "tags": [ "misp-galaxy:banker=Qakbot", "tlp:white" ], - "threatintel.indicator.ip": "62.38.114.12", - "threatintel.indicator.marking.tlp": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.ip": "62.38.114.12", + "threat.indicator.marking.tlp": [ "white" ], - "threatintel.indicator.port": "2222", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 2, - "threatintel.indicator.type": "ipv4-addr", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "On port 2222", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "10", - "threatintel.misp.attribute.id": "10686", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1607517728", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "ip-dst|port", - "threatintel.misp.attribute.uuid": "5fd0c620-a844-4ace-9710-a37bc0a8ab16", - "threatintel.misp.attribute_count": "15", - "threatintel.misp.date": "2020-12-09", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "3", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "10", - "threatintel.misp.info": "Recent Qakbot (Qbot) activity", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "4", - "threatintel.misp.orgc.local": false, - "threatintel.misp.orgc.name": "CUDESO", - "threatintel.misp.orgc.uuid": "56c42374-fdb8-4544-a218-41ffc0a8ab16", - "threatintel.misp.orgc_id": "4", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "1610637888", - "threatintel.misp.published": true, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "5fd0c599-ab6c-4ba1-a69a-df9ec0a8ab16" + "threat.indicator.port": 2222, + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 2, + "threat.indicator.type": "ipv4-addr" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/misp/test/misp_sample_with_ext_attributes.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/misp/test/misp_sample_with_ext_attributes.ndjson.log-expected.json index 6db06ab777c0..ae03f9bce957 100644 --- a/x-pack/filebeat/module/threatintel/misp/test/misp_sample_with_ext_attributes.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/misp/test/misp_sample_with_ext_attributes.ndjson.log-expected.json @@ -9,48 +9,50 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 0, + "misp.attribute.category": "Payload installation", + "misp.attribute.comment": "Contextual comment for the file md5 attribute", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3631", + "misp.attribute.id": "266258", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621588162", + "misp.attribute.to_ids": false, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "34c59b06-d35d-4808-919c-4b452f185c52", + "misp.attribute_count": 1, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3631", + "misp.info": "Test event 1 just atrributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8ca56ae9-3747-4172-93d2-808da1a4eaf3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.md5": "70461da8b94c6ca5d2fda3260c5a8c3b", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload installation", - "threatintel.misp.attribute.comment": "Contextual comment for the file md5 attribute", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3631", - "threatintel.misp.attribute.id": "266258", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621588162", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "34c59b06-d35d-4808-919c-4b452f185c52", - "threatintel.misp.attribute_count": "1", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3631", - "threatintel.misp.info": "Test event 1 just atrributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8ca56ae9-3747-4172-93d2-808da1a4eaf3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "70461da8b94c6ca5d2fda3260c5a8c3b", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -66,48 +68,50 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 1614, + "misp.attribute.category": "Artifacts dropped", + "misp.attribute.comment": "Artefact dropped for test 2", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3632", + "misp.attribute.id": "266259", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621588675", + "misp.attribute.to_ids": true, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "73102a1c-7432-47b7-9644-6f9d46b6887c", + "misp.attribute_count": 4, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3632", + "misp.info": "Test event 2 just more atrributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.md5": "60461da8b94c6ca5d2fda3260c5a8c3b", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Artifacts dropped", - "threatintel.misp.attribute.comment": "Artefact dropped for test 2", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3632", - "threatintel.misp.attribute.id": "266259", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621588675", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "73102a1c-7432-47b7-9644-6f9d46b6887c", - "threatintel.misp.attribute_count": "4", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3632", - "threatintel.misp.info": "Test event 2 just more atrributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "60461da8b94c6ca5d2fda3260c5a8c3b", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -123,48 +127,50 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 3241, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "Conext for domain type attribute event 2", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3632", + "misp.attribute.id": "266260", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621588744", + "misp.attribute.to_ids": true, + "misp.attribute.type": "domain", + "misp.attribute.uuid": "a52a1b47-a580-4f33-96ba-939cf9146c9b", + "misp.attribute_count": 4, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3632", + "misp.info": "Test event 2 just more atrributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "baddom.madeup.local", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "Conext for domain type attribute event 2", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3632", - "threatintel.misp.attribute.id": "266260", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621588744", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "domain", - "threatintel.misp.attribute.uuid": "a52a1b47-a580-4f33-96ba-939cf9146c9b", - "threatintel.misp.attribute_count": "4", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3632", - "threatintel.misp.info": "Test event 2 just more atrributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "baddom.madeup.local", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -180,48 +186,50 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 4870, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "Ip-src attribute context for event2", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3632", + "misp.attribute.id": "266261", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621588800", + "misp.attribute.to_ids": false, + "misp.attribute.type": "ip-src", + "misp.attribute.uuid": "3dbf224b-7c84-4c4b-9f95-80f28954bd10", + "misp.attribute_count": 4, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3632", + "misp.info": "Test event 2 just more atrributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.ip": "10.0.0.1", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "ipv4-addr", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "Ip-src attribute context for event2", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3632", - "threatintel.misp.attribute.id": "266261", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621588800", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "ip-src", - "threatintel.misp.attribute.uuid": "3dbf224b-7c84-4c4b-9f95-80f28954bd10", - "threatintel.misp.attribute_count": "4", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3632", - "threatintel.misp.info": "Test event 2 just more atrributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.ip": "10.0.0.1", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "ipv4-addr", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -237,48 +245,50 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 6484, + "misp.attribute.category": "Network activity", + "misp.attribute.comment": "ip-dst context for event id 2", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3632", + "misp.attribute.id": "266262", + "misp.attribute.object_id": "0", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621588836", + "misp.attribute.to_ids": true, + "misp.attribute.type": "ip-dst", + "misp.attribute.uuid": "db4bfd36-7374-4f8c-9031-60e56d4bba30", + "misp.attribute_count": 4, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3632", + "misp.info": "Test event 2 just more atrributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 2, + "misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.ip": "192.168.1.50", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "ipv4-addr", - "threatintel.misp.attribute.category": "Network activity", - "threatintel.misp.attribute.comment": "ip-dst context for event id 2", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3632", - "threatintel.misp.attribute.id": "266262", - "threatintel.misp.attribute.object_id": "0", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621588836", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "ip-dst", - "threatintel.misp.attribute.uuid": "db4bfd36-7374-4f8c-9031-60e56d4bba30", - "threatintel.misp.attribute_count": "4", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3632", - "threatintel.misp.info": "Test event 2 just more atrributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 2, - "threatintel.misp.uuid": "efbca287-edb5-4ad7-b8e4-fe9da514a763", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.ip": "192.168.1.50", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "ipv4-addr", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -294,63 +304,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 8095, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3633", + "misp.attribute.id": "266267", + "misp.attribute.object_id": "18207", + "misp.attribute.object_relation": "fullpath", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621589548", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "ff97cc32-815e-4fc9-9d4b-cab9822027a6", + "misp.attribute.value": "\\the\\fullpath\\to the file\\filenameofobject.txt", + "misp.attribute_count": 6, + "misp.context.attribute.category": "Payload delivery", + "misp.context.attribute.comment": "filename contect for test event 3", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3633", + "misp.context.attribute.id": "266263", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1621589229", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "filename", + "misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", + "misp.context.attribute.value": "thetestfile.txt", + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3633", + "misp.info": "Test event 3 objects and attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3633", - "threatintel.misp.attribute.id": "266267", - "threatintel.misp.attribute.object_id": "18207", - "threatintel.misp.attribute.object_relation": "fullpath", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621589548", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "ff97cc32-815e-4fc9-9d4b-cab9822027a6", - "threatintel.misp.attribute.value": "\\the\\fullpath\\to the file\\filenameofobject.txt", - "threatintel.misp.attribute_count": "6", - "threatintel.misp.context.attribute.category": "Payload delivery", - "threatintel.misp.context.attribute.comment": "filename contect for test event 3", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3633", - "threatintel.misp.context.attribute.id": "266263", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1621589229", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "filename", - "threatintel.misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", - "threatintel.misp.context.attribute.value": "thetestfile.txt", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3633", - "threatintel.misp.info": "Test event 3 objects and attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -366,63 +378,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 10558, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3633", + "misp.attribute.id": "266268", + "misp.attribute.object_id": "18207", + "misp.attribute.object_relation": "size-in-bytes", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621589548", + "misp.attribute.to_ids": false, + "misp.attribute.type": "size-in-bytes", + "misp.attribute.uuid": "e378b4d9-43e1-4c64-bd4e-70fce2b4e581", + "misp.attribute.value": "505050", + "misp.attribute_count": 6, + "misp.context.attribute.category": "Payload delivery", + "misp.context.attribute.comment": "filename contect for test event 3", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3633", + "misp.context.attribute.id": "266263", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1621589229", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "filename", + "misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", + "misp.context.attribute.value": "thetestfile.txt", + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3633", + "misp.info": "Test event 3 objects and attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3633", - "threatintel.misp.attribute.id": "266268", - "threatintel.misp.attribute.object_id": "18207", - "threatintel.misp.attribute.object_relation": "size-in-bytes", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621589548", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "size-in-bytes", - "threatintel.misp.attribute.uuid": "e378b4d9-43e1-4c64-bd4e-70fce2b4e581", - "threatintel.misp.attribute.value": "505050", - "threatintel.misp.attribute_count": "6", - "threatintel.misp.context.attribute.category": "Payload delivery", - "threatintel.misp.context.attribute.comment": "filename contect for test event 3", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3633", - "threatintel.misp.context.attribute.id": "266263", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1621589229", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "filename", - "threatintel.misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", - "threatintel.misp.context.attribute.value": "thetestfile.txt", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3633", - "threatintel.misp.info": "Test event 3 objects and attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -438,63 +452,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 12990, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3633", + "misp.attribute.id": "266264", + "misp.attribute.object_id": "18207", + "misp.attribute.object_relation": "md5", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621589548", + "misp.attribute.to_ids": true, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "787b3822-0bec-4278-b34a-5d649e7bce05", + "misp.attribute_count": 6, + "misp.context.attribute.category": "Payload delivery", + "misp.context.attribute.comment": "filename contect for test event 3", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3633", + "misp.context.attribute.id": "266263", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1621589229", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "filename", + "misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", + "misp.context.attribute.value": "thetestfile.txt", + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3633", + "misp.info": "Test event 3 objects and attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.md5": "70461da8b94c6ca5d2fda3260c5a8c3b", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3633", - "threatintel.misp.attribute.id": "266264", - "threatintel.misp.attribute.object_id": "18207", - "threatintel.misp.attribute.object_relation": "md5", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621589548", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "787b3822-0bec-4278-b34a-5d649e7bce05", - "threatintel.misp.attribute_count": "6", - "threatintel.misp.context.attribute.category": "Payload delivery", - "threatintel.misp.context.attribute.comment": "filename contect for test event 3", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3633", - "threatintel.misp.context.attribute.id": "266263", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1621589229", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "filename", - "threatintel.misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", - "threatintel.misp.context.attribute.value": "thetestfile.txt", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3633", - "threatintel.misp.info": "Test event 3 objects and attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "70461da8b94c6ca5d2fda3260c5a8c3b", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -510,63 +526,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 15439, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3633", + "misp.attribute.id": "266265", + "misp.attribute.object_id": "18207", + "misp.attribute.object_relation": "sha256", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621589548", + "misp.attribute.to_ids": true, + "misp.attribute.type": "sha256", + "misp.attribute.uuid": "657c5f2b-9d68-4ff7-a9ad-ab9e6a6c953e", + "misp.attribute_count": 6, + "misp.context.attribute.category": "Payload delivery", + "misp.context.attribute.comment": "filename contect for test event 3", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3633", + "misp.context.attribute.id": "266263", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1621589229", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "filename", + "misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", + "misp.context.attribute.value": "thetestfile.txt", + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3633", + "misp.info": "Test event 3 objects and attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.sha256": "f33c27745f2bd87344be790465ef984a972fd539dc83bd4f61d4242c607ef1ee", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3633", - "threatintel.misp.attribute.id": "266265", - "threatintel.misp.attribute.object_id": "18207", - "threatintel.misp.attribute.object_relation": "sha256", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621589548", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "sha256", - "threatintel.misp.attribute.uuid": "657c5f2b-9d68-4ff7-a9ad-ab9e6a6c953e", - "threatintel.misp.attribute_count": "6", - "threatintel.misp.context.attribute.category": "Payload delivery", - "threatintel.misp.context.attribute.comment": "filename contect for test event 3", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3633", - "threatintel.misp.context.attribute.id": "266263", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1621589229", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "filename", - "threatintel.misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", - "threatintel.misp.context.attribute.value": "thetestfile.txt", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3633", - "threatintel.misp.info": "Test event 3 objects and attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha256": "f33c27745f2bd87344be790465ef984a972fd539dc83bd4f61d4242c607ef1ee", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -582,63 +600,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 17926, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3633", + "misp.attribute.id": "266266", + "misp.attribute.object_id": "18207", + "misp.attribute.object_relation": "filename", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621589548", + "misp.attribute.to_ids": true, + "misp.attribute.type": "filename", + "misp.attribute.uuid": "6648d129-9200-431b-9b41-263a84f7c9d2", + "misp.attribute_count": 6, + "misp.context.attribute.category": "Payload delivery", + "misp.context.attribute.comment": "filename contect for test event 3", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3633", + "misp.context.attribute.id": "266263", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1621589229", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "filename", + "misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", + "misp.context.attribute.value": "thetestfile.txt", + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3633", + "misp.info": "Test event 3 objects and attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.name": "filenameofobject.txt", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3633", - "threatintel.misp.attribute.id": "266266", - "threatintel.misp.attribute.object_id": "18207", - "threatintel.misp.attribute.object_relation": "filename", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621589548", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "filename", - "threatintel.misp.attribute.uuid": "6648d129-9200-431b-9b41-263a84f7c9d2", - "threatintel.misp.attribute_count": "6", - "threatintel.misp.context.attribute.category": "Payload delivery", - "threatintel.misp.context.attribute.comment": "filename contect for test event 3", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3633", - "threatintel.misp.context.attribute.id": "266263", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1621589229", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "filename", - "threatintel.misp.context.attribute.uuid": "3b322e1a-1dd8-490c-ab96-12e1bc3ee6a3", - "threatintel.misp.context.attribute.value": "thetestfile.txt", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3633", - "threatintel.misp.info": "Test event 3 objects and attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "4edb20c7-8175-484d-bdcd-fce6872c1ef3", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.name": "filenameofobject.txt", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -654,49 +674,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 20372, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3634", + "misp.attribute.id": "266269", + "misp.attribute.object_id": "18208", + "misp.attribute.object_relation": "text", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621591770", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "25d2f181-26ae-4d6f-b4fd-85b9d1f82e67", + "misp.attribute.value": "Free text in the file object", + "misp.attribute_count": 3, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3634", + "misp.info": "Test event 4 with object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3634", - "threatintel.misp.attribute.id": "266269", - "threatintel.misp.attribute.object_id": "18208", - "threatintel.misp.attribute.object_relation": "text", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621591770", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "25d2f181-26ae-4d6f-b4fd-85b9d1f82e67", - "threatintel.misp.attribute.value": "Free text in the file object", - "threatintel.misp.attribute_count": "3", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3634", - "threatintel.misp.info": "Test event 4 with object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -712,49 +734,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 21959, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3634", + "misp.attribute.id": "266270", + "misp.attribute.object_id": "18208", + "misp.attribute.object_relation": "sha256", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621591770", + "misp.attribute.to_ids": true, + "misp.attribute.type": "sha256", + "misp.attribute.uuid": "4e579782-346b-44b3-b72c-1cae8d87cb25", + "misp.attribute_count": 3, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3634", + "misp.info": "Test event 4 with object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.sha256": "567caa7653723f8818ec9eb6f2e27f6d9d8c0aca0c96fc457659340e7bbdc666", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3634", - "threatintel.misp.attribute.id": "266270", - "threatintel.misp.attribute.object_id": "18208", - "threatintel.misp.attribute.object_relation": "sha256", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621591770", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "sha256", - "threatintel.misp.attribute.uuid": "4e579782-346b-44b3-b72c-1cae8d87cb25", - "threatintel.misp.attribute_count": "3", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3634", - "threatintel.misp.info": "Test event 4 with object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha256": "567caa7653723f8818ec9eb6f2e27f6d9d8c0aca0c96fc457659340e7bbdc666", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -770,49 +794,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 23597, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3634", + "misp.attribute.id": "266271", + "misp.attribute.object_id": "18208", + "misp.attribute.object_relation": "filename", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621591770", + "misp.attribute.to_ids": true, + "misp.attribute.type": "filename", + "misp.attribute.uuid": "a40343b5-a480-4288-9b0c-7ae074a77140", + "misp.attribute_count": 3, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3634", + "misp.info": "Test event 4 with object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 3, + "misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.name": "filenameinmispobject.txt", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3634", - "threatintel.misp.attribute.id": "266271", - "threatintel.misp.attribute.object_id": "18208", - "threatintel.misp.attribute.object_relation": "filename", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621591770", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "filename", - "threatintel.misp.attribute.uuid": "a40343b5-a480-4288-9b0c-7ae074a77140", - "threatintel.misp.attribute_count": "3", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3634", - "threatintel.misp.info": "Test event 4 with object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 3, - "threatintel.misp.uuid": "d98a8418-9f90-4b50-a623-6921ca5b356d", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.name": "filenameinmispobject.txt", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -828,49 +854,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 25198, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3635", + "misp.attribute.id": "266272", + "misp.attribute.object_id": "18209", + "misp.attribute.object_relation": "text", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621592379", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "188a6a15-5704-4e4f-acba-22c55ab08fe8", + "misp.attribute.value": "Object 5 free text attribute in object", + "misp.attribute_count": 5, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3635", + "misp.info": "Test event 5 with an object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3635", - "threatintel.misp.attribute.id": "266272", - "threatintel.misp.attribute.object_id": "18209", - "threatintel.misp.attribute.object_relation": "text", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621592379", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "188a6a15-5704-4e4f-acba-22c55ab08fe8", - "threatintel.misp.attribute.value": "Object 5 free text attribute in object", - "threatintel.misp.attribute_count": "5", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3635", - "threatintel.misp.info": "Test event 5 with an object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -886,49 +914,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 26791, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3635", + "misp.attribute.id": "266275", + "misp.attribute.object_id": "18209", + "misp.attribute.object_relation": "entropy", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621592379", + "misp.attribute.to_ids": false, + "misp.attribute.type": "float", + "misp.attribute.uuid": "2400b103-4a33-4f92-ac04-a558b6c6e252", + "misp.attribute.value": "0.53535445", + "misp.attribute_count": 5, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3635", + "misp.info": "Test event 5 with an object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3635", - "threatintel.misp.attribute.id": "266275", - "threatintel.misp.attribute.object_id": "18209", - "threatintel.misp.attribute.object_relation": "entropy", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621592379", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "float", - "threatintel.misp.attribute.uuid": "2400b103-4a33-4f92-ac04-a558b6c6e252", - "threatintel.misp.attribute.value": "0.53535445", - "threatintel.misp.attribute_count": "5", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3635", - "threatintel.misp.info": "Test event 5 with an object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -944,49 +974,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 28360, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3635", + "misp.attribute.id": "266276", + "misp.attribute.object_id": "18209", + "misp.attribute.object_relation": "size-in-bytes", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621592379", + "misp.attribute.to_ids": false, + "misp.attribute.type": "size-in-bytes", + "misp.attribute.uuid": "e5ea3ec0-cdf4-4d3e-bd66-a7bf384fd3d7", + "misp.attribute.value": "55555", + "misp.attribute_count": 5, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3635", + "misp.info": "Test event 5 with an object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3635", - "threatintel.misp.attribute.id": "266276", - "threatintel.misp.attribute.object_id": "18209", - "threatintel.misp.attribute.object_relation": "size-in-bytes", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621592379", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "size-in-bytes", - "threatintel.misp.attribute.uuid": "e5ea3ec0-cdf4-4d3e-bd66-a7bf384fd3d7", - "threatintel.misp.attribute.value": "55555", - "threatintel.misp.attribute_count": "5", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3635", - "threatintel.misp.info": "Test event 5 with an object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1002,49 +1034,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 29938, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3635", + "misp.attribute.id": "266273", + "misp.attribute.object_id": "18209", + "misp.attribute.object_relation": "sha256", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621592379", + "misp.attribute.to_ids": true, + "misp.attribute.type": "sha256", + "misp.attribute.uuid": "803f10bd-9087-4169-8699-277579a92693", + "misp.attribute_count": 5, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3635", + "misp.info": "Test event 5 with an object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.sha256": "567caa7653723f8818ec9eb6f2e27f6d9d8c0aca0c96fc457659340e7bbdc665", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3635", - "threatintel.misp.attribute.id": "266273", - "threatintel.misp.attribute.object_id": "18209", - "threatintel.misp.attribute.object_relation": "sha256", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621592379", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "sha256", - "threatintel.misp.attribute.uuid": "803f10bd-9087-4169-8699-277579a92693", - "threatintel.misp.attribute_count": "5", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3635", - "threatintel.misp.info": "Test event 5 with an object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.sha256": "567caa7653723f8818ec9eb6f2e27f6d9d8c0aca0c96fc457659340e7bbdc665", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1060,49 +1094,51 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 31572, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3635", + "misp.attribute.id": "266274", + "misp.attribute.object_id": "18209", + "misp.attribute.object_relation": "filename", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1621592379", + "misp.attribute.to_ids": true, + "misp.attribute.type": "filename", + "misp.attribute.uuid": "e5c7a9f0-c0e1-4024-9ab8-de8a1b403e4f", + "misp.attribute_count": 5, + "misp.date": "2021-05-21", + "misp.disable_correlation": false, + "misp.distribution": "1", + "misp.extends_uuid": "", + "misp.id": "3635", + "misp.info": "Test event 5 with an object", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.name": "object5.txt", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3635", - "threatintel.misp.attribute.id": "266274", - "threatintel.misp.attribute.object_id": "18209", - "threatintel.misp.attribute.object_relation": "filename", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1621592379", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "filename", - "threatintel.misp.attribute.uuid": "e5c7a9f0-c0e1-4024-9ab8-de8a1b403e4f", - "threatintel.misp.attribute_count": "5", - "threatintel.misp.date": "2021-05-21", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "1", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3635", - "threatintel.misp.info": "Test event 5 with an object", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "8b8786f1-07f2-4bfc-a3f0-e63c22fcc25e", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.name": "object5.txt", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1118,63 +1154,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 33156, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266278", + "misp.attribute.object_id": "18210", + "misp.attribute.object_relation": "text", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200348", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "955e34a5-a630-42c9-868d-6e3dcb575987", + "misp.attribute.value": "Excutable create bad pipe", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266278", - "threatintel.misp.attribute.object_id": "18210", - "threatintel.misp.attribute.object_relation": "text", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200348", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "955e34a5-a630-42c9-868d-6e3dcb575987", - "threatintel.misp.attribute.value": "Excutable create bad pipe", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1190,63 +1228,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 35151, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266281", + "misp.attribute.object_id": "18211", + "misp.attribute.object_relation": "size-in-bytes", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200780", + "misp.attribute.to_ids": false, + "misp.attribute.type": "size-in-bytes", + "misp.attribute.uuid": "2fa7721b-ad73-4914-b082-8d44233ced98", + "misp.attribute.value": "3892", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266281", - "threatintel.misp.attribute.object_id": "18211", - "threatintel.misp.attribute.object_relation": "size-in-bytes", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200780", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "size-in-bytes", - "threatintel.misp.attribute.uuid": "2fa7721b-ad73-4914-b082-8d44233ced98", - "threatintel.misp.attribute.value": "3892", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1262,63 +1302,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 37149, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266283", + "misp.attribute.object_id": "18211", + "misp.attribute.object_relation": "name", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200780", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "d35c1ff8-a69c-482b-8fb0-1182988d9468", + "misp.attribute.value": ".data", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266283", - "threatintel.misp.attribute.object_id": "18211", - "threatintel.misp.attribute.object_relation": "name", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200780", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "d35c1ff8-a69c-482b-8fb0-1182988d9468", - "threatintel.misp.attribute.value": ".data", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1334,63 +1376,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 39130, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266284", + "misp.attribute.object_id": "18211", + "misp.attribute.object_relation": "text", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200780", + "misp.attribute.to_ids": false, + "misp.attribute.type": "text", + "misp.attribute.uuid": "dc11971a-a676-4676-b24c-a45a8791e0b0", + "misp.attribute.value": "Extracted zip archive data", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266284", - "threatintel.misp.attribute.object_id": "18211", - "threatintel.misp.attribute.object_relation": "text", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200780", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "text", - "threatintel.misp.attribute.uuid": "dc11971a-a676-4676-b24c-a45a8791e0b0", - "threatintel.misp.attribute.value": "Extracted zip archive data", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1406,63 +1450,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 41132, + "misp.attribute.category": "Other", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266285", + "misp.attribute.object_id": "18211", + "misp.attribute.object_relation": "entropy", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200780", + "misp.attribute.to_ids": false, + "misp.attribute.type": "float", + "misp.attribute.uuid": "a85c0cbb-25a8-4bc9-b146-3cba1020e5bb", + "misp.attribute.value": "7.93280431051", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "unknown", - "threatintel.misp.attribute.category": "Other", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266285", - "threatintel.misp.attribute.object_id": "18211", - "threatintel.misp.attribute.object_relation": "entropy", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200780", - "threatintel.misp.attribute.to_ids": false, - "threatintel.misp.attribute.type": "float", - "threatintel.misp.attribute.uuid": "a85c0cbb-25a8-4bc9-b146-3cba1020e5bb", - "threatintel.misp.attribute.value": "7.93280431051", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "unknown", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1478,63 +1524,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 43125, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266279", + "misp.attribute.object_id": "18210", + "misp.attribute.object_relation": "md5", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200348", + "misp.attribute.to_ids": true, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "1c97c043-5de2-41a1-b591-3237174cd290", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.md5": "7392463caf95534d56460bc9f360adc1", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266279", - "threatintel.misp.attribute.object_id": "18210", - "threatintel.misp.attribute.object_relation": "md5", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200348", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "1c97c043-5de2-41a1-b591-3237174cd290", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "7392463caf95534d56460bc9f360adc1", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1550,63 +1598,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 45136, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": false, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266282", + "misp.attribute.object_id": "18211", + "misp.attribute.object_relation": "md5", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200780", + "misp.attribute.to_ids": true, + "misp.attribute.type": "md5", + "misp.attribute.uuid": "f3b8696e-5390-4383-ace2-6e06bfae497d", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.hash.md5": "7295463caf95534d56460bc9f360adc1", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": false, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266282", - "threatintel.misp.attribute.object_id": "18211", - "threatintel.misp.attribute.object_relation": "md5", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200780", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "md5", - "threatintel.misp.attribute.uuid": "f3b8696e-5390-4383-ace2-6e06bfae497d", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.hash.md5": "7295463caf95534d56460bc9f360adc1", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" @@ -1622,63 +1672,65 @@ "fileset.name": "misp", "input.type": "log", "log.offset": 47153, + "misp.attribute.category": "Payload delivery", + "misp.attribute.comment": "", + "misp.attribute.deleted": false, + "misp.attribute.disable_correlation": true, + "misp.attribute.distribution": 5, + "misp.attribute.event_id": "3636", + "misp.attribute.id": "266280", + "misp.attribute.object_id": "18210", + "misp.attribute.object_relation": "filename", + "misp.attribute.sharing_group_id": "0", + "misp.attribute.timestamp": "1622200348", + "misp.attribute.to_ids": true, + "misp.attribute.type": "filename", + "misp.attribute.uuid": "2dfcb937-e6af-4b5d-ad50-f8eb975990f3", + "misp.attribute_count": 9, + "misp.context.attribute.category": "Artifacts dropped", + "misp.context.attribute.comment": "", + "misp.context.attribute.deleted": false, + "misp.context.attribute.disable_correlation": false, + "misp.context.attribute.distribution": 5, + "misp.context.attribute.event_id": "3636", + "misp.context.attribute.id": "266277", + "misp.context.attribute.object_id": "0", + "misp.context.attribute.sharing_group_id": "0", + "misp.context.attribute.timestamp": "1622200249", + "misp.context.attribute.to_ids": false, + "misp.context.attribute.type": "windows-service-name", + "misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", + "misp.context.attribute.value": "badmojopipe", + "misp.date": "2021-05-28", + "misp.disable_correlation": false, + "misp.distribution": "0", + "misp.extends_uuid": "", + "misp.id": "3636", + "misp.info": "Test event 6 with multiple objects and multiple attributes", + "misp.locked": false, + "misp.org_id": "1", + "misp.orgc.id": "1", + "misp.orgc.local": true, + "misp.orgc.name": "ORGNAME", + "misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", + "misp.orgc_id": "1", + "misp.proposal_email_lock": false, + "misp.publish_timestamp": "0", + "misp.published": false, + "misp.sharing_group_id": "0", + "misp.threat_level_id": 1, + "misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-misp" ], - "threatintel.indicator.file.name": "badmojopipe.exe", - "threatintel.indicator.provider": "misp", - "threatintel.indicator.scanner_stats": 0, - "threatintel.indicator.type": "file", - "threatintel.misp.attribute.category": "Payload delivery", - "threatintel.misp.attribute.comment": "", - "threatintel.misp.attribute.deleted": false, - "threatintel.misp.attribute.disable_correlation": true, - "threatintel.misp.attribute.distribution": "5", - "threatintel.misp.attribute.event_id": "3636", - "threatintel.misp.attribute.id": "266280", - "threatintel.misp.attribute.object_id": "18210", - "threatintel.misp.attribute.object_relation": "filename", - "threatintel.misp.attribute.sharing_group_id": "0", - "threatintel.misp.attribute.timestamp": "1622200348", - "threatintel.misp.attribute.to_ids": true, - "threatintel.misp.attribute.type": "filename", - "threatintel.misp.attribute.uuid": "2dfcb937-e6af-4b5d-ad50-f8eb975990f3", - "threatintel.misp.attribute_count": "9", - "threatintel.misp.context.attribute.category": "Artifacts dropped", - "threatintel.misp.context.attribute.comment": "", - "threatintel.misp.context.attribute.deleted": false, - "threatintel.misp.context.attribute.disable_correlation": false, - "threatintel.misp.context.attribute.distribution": "5", - "threatintel.misp.context.attribute.event_id": "3636", - "threatintel.misp.context.attribute.id": "266277", - "threatintel.misp.context.attribute.object_id": "0", - "threatintel.misp.context.attribute.sharing_group_id": "0", - "threatintel.misp.context.attribute.timestamp": "1622200249", - "threatintel.misp.context.attribute.to_ids": false, - "threatintel.misp.context.attribute.type": "windows-service-name", - "threatintel.misp.context.attribute.uuid": "3bd56a61-77f0-4885-8d1c-8bd2e39b65fb", - "threatintel.misp.context.attribute.value": "badmojopipe", - "threatintel.misp.date": "2021-05-28", - "threatintel.misp.disable_correlation": false, - "threatintel.misp.distribution": "0", - "threatintel.misp.extends_uuid": "", - "threatintel.misp.id": "3636", - "threatintel.misp.info": "Test event 6 with multiple objects and multiple attributes", - "threatintel.misp.locked": false, - "threatintel.misp.org_id": "1", - "threatintel.misp.orgc.id": "1", - "threatintel.misp.orgc.local": true, - "threatintel.misp.orgc.name": "ORGNAME", - "threatintel.misp.orgc.uuid": "78acad2d-cc2d-4785-94d6-b428a0070488", - "threatintel.misp.orgc_id": "1", - "threatintel.misp.proposal_email_lock": false, - "threatintel.misp.publish_timestamp": "0", - "threatintel.misp.published": false, - "threatintel.misp.sharing_group_id": "0", - "threatintel.misp.threat_level_id": 1, - "threatintel.misp.uuid": "81aea1d1-bb23-4bcd-9b0c-496e9ce028df", + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] MISP", + "threat.indicator.file.name": "badmojopipe.exe", + "threat.indicator.provider": "misp", + "threat.indicator.scanner_stats": 0, + "threat.indicator.type": "file", "user.email": "admin@admin.test", "user.roles": [ "reporting_user" diff --git a/x-pack/filebeat/module/threatintel/otx/config/config.yml b/x-pack/filebeat/module/threatintel/otx/config/config.yml index 9e2f5169e6f0..fe18e1141d3e 100644 --- a/x-pack/filebeat/module/threatintel/otx/config/config.yml +++ b/x-pack/filebeat/module/threatintel/otx/config/config.yml @@ -55,17 +55,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: ["json.id"] - target_field: "@metadata._id" - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml index 4cb3ed37aef7..4b3f6aeaea6a 100644 --- a/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml @@ -1,4 +1,5 @@ -description: Pipeline for parsing MISP Threat Intel +--- +description: Pipeline for parsing Abuse.ch URL Threat Intel processors: #################### # Event ECS fields # @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -20,108 +24,126 @@ processors: # General ECS fields # ###################### - rename: - field: json - target_field: threatintel.otx + field: message + target_field: event.original ignore_missing: true + - json: + field: event.original + target_field: otx + - fingerprint: + fields: + - otx.id + target_field: "_id" ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] Alienvault OTX" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" ## File indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx.threatintel?.otx?.type.startsWith('FileHash') || ctx.threatintel?.otx?.type == 'filepath'" + if: "ctx.otx?.type.startsWith('FileHash') || ctx.otx?.type == 'filepath'" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.file.hash.md5 + field: otx.indicator + target_field: threat.indicator.file.hash.md5 ignore_missing: true - if: "ctx.threatintel?.otx?.type == 'FileHash-MD5'" + if: "ctx.otx?.type == 'FileHash-MD5'" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.file.hash.sha1 + field: otx.indicator + target_field: threat.indicator.file.hash.sha1 ignore_missing: true - if: "ctx.threatintel?.otx?.type == 'FileHash-SHA1'" + if: "ctx.otx?.type == 'FileHash-SHA1'" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.file.hash.sha256 + field: otx.indicator + target_field: threat.indicator.file.hash.sha256 ignore_missing: true - if: "ctx.threatintel?.otx?.type == 'FileHash-SHA256'" + if: "ctx.otx?.type == 'FileHash-SHA256'" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.file.hash.pehash + field: otx.indicator + target_field: threat.indicator.file.hash.pehash ignore_missing: true - if: "ctx.threatintel?.otx?.type == 'FileHash-PEHASH'" + if: "ctx.otx?.type == 'FileHash-PEHASH'" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.file.hash.imphash + field: otx.indicator + target_field: threat.indicator.file.hash.imphash ignore_missing: true - if: "ctx.threatintel?.otx?.type == 'FileHash-IMPHASH'" + if: "ctx.otx?.type == 'FileHash-IMPHASH'" ## IP indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv4-addr - if: ctx.threatintel?.otx?.type == 'IPv4' + if: ctx.otx?.type == 'IPv4' - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv6-addr - if: ctx.threatintel?.otx?.type == 'IPv6' + if: ctx.otx?.type == 'IPv6' - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.ip + field: otx.indicator + target_field: threat.indicator.ip ignore_missing: true - if: "ctx?.threatintel?.indicator?.type != null && ['ipv4-addr', 'ipv6-addr'].contains(ctx?.threatintel?.indicator?.type)" + if: "ctx.threat?.indicator?.type != null && ['ipv4-addr', 'ipv6-addr'].contains(ctx.threat?.indicator?.type)" ## URL indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: url - if: "ctx?.threatintel?.indicator?.type == null && ['URL', 'URI'].contains(ctx.threatintel?.otx?.type)" + if: "ctx.threat?.indicator?.type == null && ['URL', 'URI'].contains(ctx.otx?.type)" - uri_parts: - field: threatintel.otx.indicator - target_field: threatintel.indicator.url + field: otx.indicator + target_field: threat.indicator.url keep_original: true remove_if_successful: true - if: ctx?.threatintel?.indicator?.type == 'url' + if: ctx.threat?.indicator?.type == 'url' - set: - field: threatintel.indicator.url.full - value: "{{{threatintel.indicator.url.original}}}" + field: threat.indicator.url.full + value: "{{{threat.indicator.url.original}}}" ignore_empty_value: true - if: "ctx?.threatintel?.otx?.type == 'URL'" + if: "ctx.otx?.type == 'URL'" ## Email indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: email-addr - if: ctx?.threatintel?.otx?.type == 'email' + if: ctx.otx?.type == 'email' - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.email.address + field: otx.indicator + target_field: threat.indicator.email.address ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'email-addr'" + if: "ctx.threat?.indicator?.type == 'email-addr'" ## Domain indicator operations - set: - field: threatintel.indicator.type + field: threat.indicator.type value: domain-name - if: "ctx?.threatintel?.indicator?.type == null && ['domain', 'hostname'].contains(ctx.threatintel?.otx?.type)" + if: "ctx.threat?.indicator?.type == null && ['domain', 'hostname'].contains(ctx.otx?.type)" - rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.url.domain + field: otx.indicator + target_field: threat.indicator.url.domain ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'domain-name' && ctx.threatintel?.indicator?.url?.domain == null" + if: "ctx.threat?.indicator?.type == 'domain-name' && ctx.threat?.indicator?.url?.domain == null" ###################### # Cleanup processors # ###################### + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx.threat?.indicator?.type == null - script: lang: painless - if: ctx?.threatintel != null + if: ctx.otx != null source: | void handleMap(Map map) { for (def x : map.values()) { @@ -145,16 +167,16 @@ processors: handleMap(ctx); - remove: field: - - threatintel.otx.content + - otx.content ignore_missing: true - if: ctx?.threatintel?.otx?.content == "" + if: ctx.otx?.content == "" - remove: field: - - threatintel.otx.type - - threatintel.otx.id + - otx.type + - otx.id - message ignore_missing: true - if: ctx?.threatintel?.indicator?.type != null + if: ctx.threat?.indicator?.type != null on_failure: - set: field: error.message diff --git a/x-pack/filebeat/module/threatintel/otx/manifest.yml b/x-pack/filebeat/module/threatintel/otx/manifest.yml index 0fdefa51d76e..728302249844 100644 --- a/x-pack/filebeat/module/threatintel/otx/manifest.yml +++ b/x-pack/filebeat/module/threatintel/otx/manifest.yml @@ -20,6 +20,8 @@ var: - name: tags default: [threatintel-otx, forwarded] - name: proxy_url + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log-expected.json index e56752d47c33..590bc64bfbc9 100644 --- a/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log-expected.json @@ -13,8 +13,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "86.104.194.30", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "86.104.194.30", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -25,15 +27,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 102, + "otx.description": "MD5 of a5725af4391d21a232dc6d4ad33d7d915bd190bdac9b1826b73f364dc5c1aa65", + "otx.title": "Win32:Hoblig-B", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "90421f8531f963d81cf54245b72cde80", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of a5725af4391d21a232dc6d4ad33d7d915bd190bdac9b1826b73f364dc5c1aa65", - "threatintel.otx.title": "Win32:Hoblig-B" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "90421f8531f963d81cf54245b72cde80", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -49,8 +53,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "ip.anysrc.net" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "ip.anysrc.net" }, { "event.category": "threat", @@ -66,8 +72,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "107.173.58.176", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "107.173.58.176", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -83,8 +91,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "d8c70ca70fd3555a0828fede6cc1f59e2c320ede80157039b6a2f09c336d5f7a", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "d8c70ca70fd3555a0828fede6cc1f59e2c320ede80157039b6a2f09c336d5f7a", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -95,14 +105,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 688, + "otx.description": "MD5 of df9b37477a83189cd4541674e64ce29bf7bf98338ed0d635276660e0c6419d09", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "f8e58af3ffefd4037fef246e93a55dc8", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of df9b37477a83189cd4541674e64ce29bf7bf98338ed0d635276660e0c6419d09" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "f8e58af3ffefd4037fef246e93a55dc8", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -118,8 +130,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "1c62f004d0c9b91d3467b1b8106772e667e7e2075470c2ec7982b63573c90c54", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "1c62f004d0c9b91d3467b1b8106772e667e7e2075470c2ec7982b63573c90c54", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -130,14 +144,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 1053, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "8d24a14f2600482d0231396b6350cf21773335ec2f0b8919763317fdab78baae", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "8d24a14f2600482d0231396b6350cf21773335ec2f0b8919763317fdab78baae", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -153,8 +169,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "213.252.244.38", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "213.252.244.38", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -170,8 +188,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "c758ec922b173820374e552c2f015ac53cc5d9f99cc92080e608652aaa63695b", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "c758ec922b173820374e552c2f015ac53cc5d9f99cc92080e608652aaa63695b", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -187,8 +207,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "0df586aa0334dcbe047d24ce859d00e537fdb5e0ca41886dab27479b6fc61ba6", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "0df586aa0334dcbe047d24ce859d00e537fdb5e0ca41886dab27479b6fc61ba6", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -199,14 +221,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 1671, + "otx.description": "MD5 of 0df586aa0334dcbe047d24ce859d00e537fdb5e0ca41886dab27479b6fc61ba6", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "aeb08b0651bc8a13dcf5e5f6c0d482f8", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 0df586aa0334dcbe047d24ce859d00e537fdb5e0ca41886dab27479b6fc61ba6" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "aeb08b0651bc8a13dcf5e5f6c0d482f8", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -222,8 +246,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "6df5e1a017dff52020c7ff6ad92fdd37494e31769e1be242f6b23d1ea2d60140", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "6df5e1a017dff52020c7ff6ad92fdd37494e31769e1be242f6b23d1ea2d60140", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -239,8 +265,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "c72fef3835f65cb380f6920b22c3488554d1af6d298562ccee92284f265c9619", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "c72fef3835f65cb380f6920b22c3488554d1af6d298562ccee92284f265c9619", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -256,8 +284,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "e711fcd0f182b214c6ec74011a395f4c853068d59eb7c57f90c4a3e1de64434a", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "e711fcd0f182b214c6ec74011a395f4c853068d59eb7c57f90c4a3e1de64434a", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -273,8 +303,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "d3ec8f4a46b21fb189fc3d58f3d87bf9897653ecdf90b7952dcc71f3b4023b4e", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "d3ec8f4a46b21fb189fc3d58f3d87bf9897653ecdf90b7952dcc71f3b4023b4e", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -290,8 +322,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "70447996722e5c04514d20b7a429d162b46546002fb0c87f512b40f16bac99bb", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "70447996722e5c04514d20b7a429d162b46546002fb0c87f512b40f16bac99bb", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -302,15 +336,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 2703, + "otx.description": "MD5 of 113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "29340643ca2e6677c19e1d3bf351d654", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "29340643ca2e6677c19e1d3bf351d654", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -321,15 +357,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 2919, + "otx.description": "MD5 of 9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "86c314bc2dc37ba84f7364acd5108c2b", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "86c314bc2dc37ba84f7364acd5108c2b", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -340,15 +378,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 3135, + "otx.description": "MD5 of 1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", + "otx.title": "Trojan:Win32/Occamy.B", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "cb0c1248d3899358a375888bb4e8f3fe", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", - "threatintel.otx.title": "Trojan:Win32/Occamy.B" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "cb0c1248d3899358a375888bb4e8f3fe", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -359,15 +399,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 3355, + "otx.description": "MD5 of 3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "d348f536e214a47655af387408b4fca5", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "d348f536e214a47655af387408b4fca5", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -378,14 +420,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 3571, + "otx.title": "vad_contains_network_strings", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "29ff1903832827e328ad9ec05fdf268eadd6db8b613597cf65f8740c211be413", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "vad_contains_network_strings" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "29ff1903832827e328ad9ec05fdf268eadd6db8b613597cf65f8740c211be413", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -401,8 +445,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "b105891f90b2a8730bbadf02b5adeccbba539883bf75dec2ff7a5a97625dd222", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "b105891f90b2a8730bbadf02b5adeccbba539883bf75dec2ff7a5a97625dd222", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -418,8 +464,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "e4db5405ac7ab517d43722e1ca8d653ea4a32802bc8a5410d032275eedc7b7ee", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "e4db5405ac7ab517d43722e1ca8d653ea4a32802bc8a5410d032275eedc7b7ee", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -430,14 +478,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 4098, + "otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -453,8 +503,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "5051906d6ed1b2ae9c9a9f070ef73c9be8f591d2e41d144649a0dc96e28d0400", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "5051906d6ed1b2ae9c9a9f070ef73c9be8f591d2e41d144649a0dc96e28d0400", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -465,15 +517,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 4470, + "otx.description": "MD5 of 465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", + "otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "14b74cb9be8cad8eb5fa8842d00bb692", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", - "threatintel.otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "14b74cb9be8cad8eb5fa8842d00bb692", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -484,15 +538,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 4709, + "otx.description": "SHA1 of 465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", + "otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "a5b59f7d133e354dfc73f40517aab730f322f0ef", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "SHA1 of 465e7c1e36899284da5c4425dfd687af2496f397fe60c85ea2b4d85dff5a08aa", - "threatintel.otx.title": "Win.Malware.TrickbotSystemInfo-6335590-0" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "a5b59f7d133e354dfc73f40517aab730f322f0ef", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -508,8 +564,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "8d3f68b16f0710f858d8c1d2c699260e6f43161a5510abb0e7ba567bd72c965b", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "8d3f68b16f0710f858d8c1d2c699260e6f43161a5510abb0e7ba567bd72c965b", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -520,15 +578,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 5125, + "otx.description": "MD5 of 5cb822616d2c9435c9ddd060d6abdbc286ab57cfcf6dc64768c52976029a925b", + "otx.title": "vad_contains_network_strings", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "ff2dcea4963e060a658f4dffbb119529", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 5cb822616d2c9435c9ddd060d6abdbc286ab57cfcf6dc64768c52976029a925b", - "threatintel.otx.title": "vad_contains_network_strings" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "ff2dcea4963e060a658f4dffbb119529", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -539,15 +599,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 5352, + "otx.description": "MD5 of 29ff1903832827e328ad9ec05fdf268eadd6db8b613597cf65f8740c211be413", + "otx.title": "vad_contains_network_strings", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "0d73f1a1c4b2f8723fffc83eb3d00f31", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 29ff1903832827e328ad9ec05fdf268eadd6db8b613597cf65f8740c211be413", - "threatintel.otx.title": "vad_contains_network_strings" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "0d73f1a1c4b2f8723fffc83eb3d00f31", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -563,8 +625,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "185.25.50.167", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "185.25.50.167", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -580,8 +644,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "d35a30264c0698709ad554489004e0077e263d354ced0c54552a0b500f91ecc0", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "d35a30264c0698709ad554489004e0077e263d354ced0c54552a0b500f91ecc0", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -597,8 +663,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "5264b455f453820be629a324196131492ff03c80491e823ac06657c9387250dd", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "5264b455f453820be629a324196131492ff03c80491e823ac06657c9387250dd", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -609,14 +677,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 6018, + "otx.title": "Trojan:Win32/Occamy.B", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Trojan:Win32/Occamy.B" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -627,14 +697,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 6204, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -650,8 +722,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "b8e463789a076b16a90d1aae73cea9d3880ac0ead1fd16587b8cd79e37a1a3d8", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "b8e463789a076b16a90d1aae73cea9d3880ac0ead1fd16587b8cd79e37a1a3d8", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -662,14 +736,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 6553, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -680,14 +756,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 6735, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -703,8 +781,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "c51024bb119211c335f95e731cfa9a744fcdb645a57d35fb379d01b7dbdd098e", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "c51024bb119211c335f95e731cfa9a744fcdb645a57d35fb379d01b7dbdd098e", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -715,15 +795,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 7084, + "otx.description": "SHA1 of 9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "ad20c6fac565f901c82a21b70f9739037eb54818", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "SHA1 of 9b86a50b36aea5cc4cb60573a3660cf799a9ec1f69a3d4572d3dc277361a0ad2", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "ad20c6fac565f901c82a21b70f9739037eb54818", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -734,15 +816,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 7310, + "otx.description": "SHA1 of 3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "13f11e273f9a4a56557f03821c3bfd591cca6ebc", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "SHA1 of 3012f472969327d5f8c9dac63b8ea9c5cb0de002d16c120a6bba4685120f58b4", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "13f11e273f9a4a56557f03821c3bfd591cca6ebc", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -753,15 +837,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 7536, + "otx.description": "SHA1 of 113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "1581fe76e3c96dc33182daafd09c8cf5c17004e0", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "SHA1 of 113af75f13547be184822f1268f984b79f35965a1b1f963d23b50a09741b0aec", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "1581fe76e3c96dc33182daafd09c8cf5c17004e0", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -772,15 +858,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 7762, + "otx.description": "SHA1 of 1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", + "otx.title": "Trojan:Win32/Occamy.B", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "b72e75e9e901a44b655a5cf89cf0eadcaff46037", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "SHA1 of 1455091954ecf9ccd6fe60cb8e982d9cfb4b3dc8414443ccfdfc444079829d56", - "threatintel.otx.title": "Trojan:Win32/Occamy.B" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "b72e75e9e901a44b655a5cf89cf0eadcaff46037", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -796,8 +884,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "maper.info" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "maper.info" }, { "event.category": "threat", @@ -813,8 +903,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "213.252.244.126", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "213.252.244.126", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -830,8 +922,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "78.129.139.131", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "78.129.139.131", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -842,14 +936,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 8309, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -860,14 +956,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 8498, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "be9fb556a3c7aef0329e768d7f903e7dd42a821abc663e11fb637ce33b007087", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "be9fb556a3c7aef0329e768d7f903e7dd42a821abc663e11fb637ce33b007087", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -878,14 +976,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 8687, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "3bfec096c4837d1e6485fe0ae0ea6f1c0b44edc611d4f2204cc9cf73c985cbc2", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "3bfec096c4837d1e6485fe0ae0ea6f1c0b44edc611d4f2204cc9cf73c985cbc2", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -896,14 +996,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 8876, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "dff2e39b2e008ea89a3d6b36dcd9b8c927fb501d60c1ad5a52ed1ffe225da2e2", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "dff2e39b2e008ea89a3d6b36dcd9b8c927fb501d60c1ad5a52ed1ffe225da2e2", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -914,14 +1016,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 9065, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "6b4d271a48d118843aee3dee4481fa2930732ed7075db3241a8991418f00d92b", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "6b4d271a48d118843aee3dee4481fa2930732ed7075db3241a8991418f00d92b", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -932,14 +1036,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 9254, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "26de4265303491bed1424d85b263481ac153c2b3513f9ee48ffb42c12312ac43", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "26de4265303491bed1424d85b263481ac153c2b3513f9ee48ffb42c12312ac43", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -950,14 +1056,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 9443, + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "02f54da6c6f2f87ff7b713d46e058dedac1cedabd693643bb7f6dfe994b2105d", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "02f54da6c6f2f87ff7b713d46e058dedac1cedabd693643bb7f6dfe994b2105d", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -973,8 +1081,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "103.13.67.4", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "103.13.67.4", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -990,8 +1100,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "80.90.87.201", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "80.90.87.201", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1007,8 +1119,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "80.80.163.182", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "80.80.163.182", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1024,8 +1138,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "91.187.114.210", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "91.187.114.210", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1041,8 +1157,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "170.238.117.187", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "170.238.117.187", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1058,8 +1176,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha256": "e999b83629355ec7ff3b6fda465ef53ce6992c9327344fbf124f7eb37808389d", - "threatintel.indicator.type": "file" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha256": "e999b83629355ec7ff3b6fda465ef53ce6992c9327344fbf124f7eb37808389d", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1075,8 +1195,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "103.84.238.3", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "103.84.238.3", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1092,8 +1214,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "179.43.158.171", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "179.43.158.171", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1109,8 +1233,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "198.211.116.199", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "198.211.116.199", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1121,14 +1247,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 10641, + "otx.title": "Trickbot", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "203.176.135.102", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.otx.title": "Trickbot" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "203.176.135.102", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1144,8 +1272,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "fotmailz.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "fotmailz.com" }, { "event.category": "threat", @@ -1161,8 +1291,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "pori89g5jqo3v8.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "pori89g5jqo3v8.com" }, { "event.category": "threat", @@ -1178,8 +1310,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "sebco.co.ke" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "sebco.co.ke" }, { "event.category": "threat", @@ -1190,14 +1324,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 11077, + "otx.title": "Trickbot", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "177.74.232.124", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.otx.title": "Trickbot" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "177.74.232.124", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1213,8 +1349,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "chishir.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "chishir.com" }, { "event.category": "threat", @@ -1230,8 +1368,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "kostunivo.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "kostunivo.com" }, { "event.category": "threat", @@ -1247,8 +1387,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "mangoclone.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "mangoclone.com" }, { "event.category": "threat", @@ -1264,8 +1406,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "onixcellent.com" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "onixcellent.com" }, { "event.category": "threat", @@ -1276,14 +1420,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 11618, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "fc0efd612ad528795472e99cae5944b68b8e26dc", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "fc0efd612ad528795472e99cae5944b68b8e26dc", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1294,14 +1440,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 11774, + "otx.title": "Sf:ShellCode-DZ\\ [Trj]", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "24d4bbc982a6a561f0426a683b9617de1a96a74a", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Sf:ShellCode-DZ\\ [Trj]" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "24d4bbc982a6a561f0426a683b9617de1a96a74a", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1312,14 +1460,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 11936, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "fa98074dc18ad7e2d357b5d168c00a91256d87d1", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "fa98074dc18ad7e2d357b5d168c00a91256d87d1", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1330,14 +1480,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 12092, + "otx.title": "Win64:Malware-gen", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.sha1": "e5dc7c8bfa285b61dda1618f0ade9c256be75d1a", - "threatintel.indicator.type": "file", - "threatintel.otx.title": "Win64:Malware-gen" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.sha1": "e5dc7c8bfa285b61dda1618f0ade9c256be75d1a", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1348,14 +1500,16 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 12248, + "otx.title": "Trickbot", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "96.9.77.142", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.otx.title": "Trickbot" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "96.9.77.142", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1371,8 +1525,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "36.89.106.69", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "36.89.106.69", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1388,8 +1544,10 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.ip": "96.9.73.73", - "threatintel.indicator.type": "ipv4-addr" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.ip": "96.9.73.73", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -1400,15 +1558,17 @@ "fileset.name": "otx", "input.type": "log", "log.offset": 12563, + "otx.description": "MD5 of 9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6", + "otx.title": "xor_0x20_xord_javascript", "service.type": "threatintel", "tags": [ "forwarded", "threatintel-otx" ], - "threatintel.indicator.file.hash.md5": "10ec3571596c30b9993b89f12d29d23c", - "threatintel.indicator.type": "file", - "threatintel.otx.description": "MD5 of 9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6", - "threatintel.otx.title": "xor_0x20_xord_javascript" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.file.hash.md5": "10ec3571596c30b9993b89f12d29d23c", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -1424,12 +1584,14 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "www.playboysplus.com", - "threatintel.indicator.url.full": "http://www.playboysplus.com", - "threatintel.indicator.url.original": "http://www.playboysplus.com", - "threatintel.indicator.url.path": "", - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "www.playboysplus.com", + "threat.indicator.url.full": "http://www.playboysplus.com", + "threat.indicator.url.original": "http://www.playboysplus.com", + "threat.indicator.url.path": "", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -1445,12 +1607,14 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "join.playboysplus.com", - "threatintel.indicator.url.full": "http://join.playboysplus.com/signup/", - "threatintel.indicator.url.original": "http://join.playboysplus.com/signup/", - "threatintel.indicator.url.path": "/signup/", - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "join.playboysplus.com", + "threat.indicator.url.full": "http://join.playboysplus.com/signup/", + "threat.indicator.url.original": "http://join.playboysplus.com/signup/", + "threat.indicator.url.path": "/signup/", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -1466,13 +1630,15 @@ "forwarded", "threatintel-otx" ], - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "api.vk.com", - "threatintel.indicator.url.extension": "get", - "threatintel.indicator.url.full": "http://api.vk.com/method/wall.get?count=1&owner_id=-81972386", - "threatintel.indicator.url.original": "http://api.vk.com/method/wall.get?count=1&owner_id=-81972386", - "threatintel.indicator.url.path": "/method/wall.get", - "threatintel.indicator.url.query": "count=1&owner_id=-81972386", - "threatintel.indicator.url.scheme": "http" + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] Alienvault OTX", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "api.vk.com", + "threat.indicator.url.extension": "get", + "threat.indicator.url.full": "http://api.vk.com/method/wall.get?count=1&owner_id=-81972386", + "threat.indicator.url.original": "http://api.vk.com/method/wall.get?count=1&owner_id=-81972386", + "threat.indicator.url.path": "/method/wall.get", + "threat.indicator.url.query": "count=1&owner_id=-81972386", + "threat.indicator.url.scheme": "http" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/config/config.yml b/x-pack/filebeat/module/threatintel/recordedfuture/config/config.yml index 08b2f682f3f9..2c610e5379dd 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/config/config.yml +++ b/x-pack/filebeat/module/threatintel/recordedfuture/config/config.yml @@ -38,27 +38,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - - fingerprint: - fields: - - event.dataset - - json.entity.id - target_field: "@metadata._id" - encoding: base64 - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 - - script: - lang: javascript - id: set_opt_type - source: > - function process(event) { - event.Put("@metadata.op_type", "index"); - } +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/recordedfuture/ingest/pipeline.yml index 8e0a6d4b3343..6247c0cd8829 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/recordedfuture/ingest/pipeline.yml @@ -1,19 +1,14 @@ description: Pipeline for parsing Recorded Future threat intel. processors: - # - # Safeguard against feeding the pipeline with documents other - # that the ones generated by Filebeat's httpjson input. - # - - fail: - if: "ctx.json == null || !(ctx.json instanceof Map)" - message: "missing json object in input document" - # # Set basic ECS fields. # - set: field: event.ingested - value: "{{{ _ingest.timestamp }}}" + value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -24,14 +19,29 @@ processors: field: event.type value: indicator + - rename: + field: message + target_field: event.original + ignore_missing: true + - json: + field: event.original + target_field: json + + - set: + field: threat.feed.name + value: "[Filebeat] RecordedFuture" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" + # - # Map itype field to STIX 2.0 Cyber Observable values (threatintel.indicator.type). + # Map itype field to STIX 2.0 Cyber Observable values (threat.indicator.type). # - script: lang: painless if: "ctx.json.entity?.type != null" description: > - Map entity.type field to STIX 2.0 Cyber Observable values (threatintel.indicator.type). + Map entity.type field to STIX 2.0 Cyber Observable values (threat.indicator.type). params: IpAddress: ipv4-addr InternetDomainName: domain-name @@ -40,7 +50,7 @@ processors: source: > String mapping = params[ctx.json.entity.type]; if (mapping != null) { - ctx["threatintel_indicator_type"] = mapping; + ctx["threat_indicator_type"] = mapping; } on_failure: - append: @@ -48,24 +58,24 @@ processors: value: 'Unable to determine indicator type from "{{{ json.entity.type }}}": {{{ _ingest.on_failure_message }}}' - rename: - field: threatintel_indicator_type - target_field: threatintel.indicator.type + field: threat_indicator_type + target_field: threat.indicator.type ignore_missing: true # # Detect ipv6 for ipv4-addr types. # - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv6-addr - if: 'ctx.threatintel?.indicator?.type == "ipv4-addr" && ctx.json.entity.name != null && ctx.json.entity.name.contains(":")' + if: 'ctx.threat?.indicator?.type == "ipv4-addr" && ctx.json.entity.name != null && ctx.json.entity.name.contains(":")' # # Map first and last seen dates. # - date: field: json.timestamps.firstSeen - target_field: threatintel.indicator.first_seen + target_field: threat.indicator.first_seen formats: - ISO8601 if: "ctx.json.timestamps?.firstSeen != null" @@ -75,7 +85,7 @@ processors: value: 'Error parsing firstSeen field value "{{{ json.timestamps.firstSeen }}}": {{{ _ingest.on_failure_message }}}' - date: field: json.timestamps.lastSeen - target_field: threatintel.indicator.last_seen + target_field: threat.indicator.last_seen formats: - ISO8601 if: "ctx.json.timestamps?.lastSeen != null" @@ -89,20 +99,20 @@ processors: # - rename: field: json.location.location.city - target_field: threatintel.indicator.geo.city_name + target_field: threat.indicator.geo.city_name ignore_missing: true - rename: field: json.location.location.continent - target_field: threatintel.indicator.geo.continent_name + target_field: threat.indicator.geo.continent_name ignore_missing: true - rename: field: json.location.location.country - target_field: threatintel.indicator.geo.country_name + target_field: threat.indicator.geo.country_name ignore_missing: true - grok: field: json.location.asn patterns: - - "^(?:[Aa][Ss])?%{NUMBER:threatintel.indicator.as.number:long}$" + - "^(?:[Aa][Ss])?%{NUMBER:threat.indicator.as.number:long}$" ignore_missing: true on_failure: - append: @@ -110,10 +120,10 @@ processors: value: "Cannot parse asn field `{{{ json.location.asn }}}`: {{{ _ingest.on_failure_message }}}" - rename: field: json.location.organization - target_field: threatintel.indicator.as.organization.name + target_field: threat.indicator.as.organization.name ignore_missing: true - set: - field: threatintel.indicator.reference + field: threat.indicator.reference value: "{{{ json.intelCard }}}" ignore_empty_value: true - set: @@ -123,30 +133,30 @@ processors: - set: field: json.ip_range value: "{{{ json.entity.name }}}/32" - if: 'ctx.threatintel?.indicator?.type == "ipv4-addr" && ctx.json.entity.name != null && !ctx.json.entity.name.contains("/")' + if: 'ctx.threat?.indicator?.type == "ipv4-addr" && ctx.json.entity.name != null && !ctx.json.entity.name.contains("/")' - set: field: json.ip_range value: "{{{ json.entity.name }}}/128" - if: 'ctx.threatintel?.indicator?.type == "ipv6-addr" && ctx.json.entity.name != null && !ctx.json.entity.name.contains("/")' + if: 'ctx.threat?.indicator?.type == "ipv6-addr" && ctx.json.entity.name != null && !ctx.json.entity.name.contains("/")' - set: field: json.ip_range value: "{{{json.entity.name}}}" if: 'ctx.json.entity?.type == "IpAddress" && ctx.json.entity.name != null && ctx.json.entity.name.contains("/")' - rename: field: json.entity.name - target_field: threatintel.indicator.ip + target_field: threat.indicator.ip if: 'ctx.json.entity?.type == "IpAddress" && ctx.json.entity.name != null && !ctx.json.entity.name.contains("/")' - rename: field: json.entity.name - target_field: threatintel.indicator.url.domain + target_field: threat.indicator.url.domain ignore_missing: true - if: 'ctx.threatintel?.indicator?.type == "domain-name" && ctx.threatintel?.indicator?.url?.domain == null' + if: 'ctx.threat?.indicator?.type == "domain-name" && ctx.threat?.indicator?.url?.domain == null' - uri_parts: field: json.entity.name - target_field: threatintel.indicator.url + target_field: threat.indicator.url keep_original: true remove_if_successful: true - if: 'ctx.threatintel?.indicator?.type == "url"' + if: 'ctx.threat?.indicator?.type == "url"' on_failure: - append: field: error.message @@ -157,10 +167,10 @@ processors: field: json.fileHashes value: "{{{ json.entity.name }}}" allow_duplicates: false - if: 'ctx.threatintel?.indicator?.type == "file"' + if: 'ctx.threat?.indicator?.type == "file"' - remove: field: json.entity.name - if: 'ctx.threatintel?.indicator?.type == "file"' + if: 'ctx.threat?.indicator?.type == "file"' - script: lang: painless description: > @@ -187,7 +197,7 @@ processors: value: "Failed to map fileHashes field: {{ _ingest.on_failure_message }}" - rename: field: _hashes - target_field: threatintel.indicator.file.hash + target_field: threat.indicator.file.hash ignore_missing: true # @@ -213,11 +223,48 @@ processors: - message ignore_missing: true # - # Save fields without an ECS mapping under `threatintel.recordedfuture`. + # Save fields without an ECS mapping under `recordedfuture`. # - rename: field: json - target_field: threatintel.recordedfuture + target_field: recordedfuture + + ###################### + # Cleanup processors # + ###################### + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true + - set: + field: threat.indicator.type + value: unknown + if: ctx.threat?.indicator?.type == null + - script: + lang: painless + if: ctx.recordedfuture != null + source: | + void handleMap(Map map) { + for (def x : map.values()) { + if (x instanceof Map) { + handleMap(x); + } else if (x instanceof List) { + handleList(x); + } + } + map.values().removeIf(v -> v == null); + } + void handleList(List list) { + for (def x : list) { + if (x instanceof Map) { + handleMap(x); + } else if (x instanceof List) { + handleList(x); + } + } + } + handleMap(ctx); on_failure: - append: field: error.message diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/manifest.yml b/x-pack/filebeat/module/threatintel/recordedfuture/manifest.yml index 93df3884160a..da8a88e19dab 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/manifest.yml +++ b/x-pack/filebeat/module/threatintel/recordedfuture/manifest.yml @@ -14,6 +14,8 @@ var: default: [threatintel-recordedfuture, forwarded] - name: proxy_url - name: api_token + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml input: config/config.yml diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/test/domain.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/recordedfuture/test/domain.ndjson.log-expected.json index 29b0a8ed4a5d..7da98ffcc296 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/test/domain.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/recordedfuture/test/domain.ndjson.log-expected.json @@ -9,26 +9,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 0, + "recordedfuture.entity.id": "idn:16url-gy.example.net", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A16url-gy.example.net", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2016-07-25T20:29:32.750Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.901Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A16url-gy.example.net", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "16url-gy.example.net", - "threatintel.recordedfuture.entity.id": "idn:16url-gy.example.net", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A16url-gy.example.net", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2016-07-25T20:29:32.750Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.901Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A16url-gy.example.net", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "16url-gy.example.net" }, { "event.category": "threat", @@ -40,26 +42,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 482, + "recordedfuture.entity.id": "idn:b999f.example.org", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ab999f.example.org", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2012-11-21T01:54:04.292Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.812Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ab999f.example.org", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "b999f.example.org", - "threatintel.recordedfuture.entity.id": "idn:b999f.example.org", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ab999f.example.org", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2012-11-21T01:54:04.292Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.812Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ab999f.example.org", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "b999f.example.org" }, { "event.category": "threat", @@ -71,26 +75,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 955, + "recordedfuture.entity.id": "idn:c422.example.net", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac422.example.net", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2018-02-21T13:53:46.470Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.778Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac422.example.net", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "c422.example.net", - "threatintel.recordedfuture.entity.id": "idn:c422.example.net", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac422.example.net", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2018-02-21T13:53:46.470Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.778Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac422.example.net", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "c422.example.net" }, { "event.category": "threat", @@ -102,26 +108,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 1425, + "recordedfuture.entity.id": "idn:8rwcvgjsp.example.net", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A8rwcvgjsp.example.net", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2016-08-15T11:56:24.964Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.747Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A8rwcvgjsp.example.net", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "8rwcvgjsp.example.net", - "threatintel.recordedfuture.entity.id": "idn:8rwcvgjsp.example.net", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A8rwcvgjsp.example.net", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2016-08-15T11:56:24.964Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.747Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A8rwcvgjsp.example.net", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "8rwcvgjsp.example.net" }, { "event.category": "threat", @@ -133,26 +141,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 1910, + "recordedfuture.entity.id": "idn:c9px.example.net", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac9px.example.net", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2016-06-29T21:06:06.066Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.460Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac9px.example.net", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "c9px.example.net", - "threatintel.recordedfuture.entity.id": "idn:c9px.example.net", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac9px.example.net", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2016-06-29T21:06:06.066Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.460Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Ac9px.example.net", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "c9px.example.net" }, { "event.category": "threat", @@ -164,26 +174,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2380, + "recordedfuture.entity.id": "idn:ttj1i9z7.example.com", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Attj1i9z7.example.com", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2018-09-20T03:26:08.564Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.373Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Attj1i9z7.example.com", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "ttj1i9z7.example.com", - "threatintel.recordedfuture.entity.id": "idn:ttj1i9z7.example.com", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Attj1i9z7.example.com", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2018-09-20T03:26:08.564Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.373Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Attj1i9z7.example.com", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "ttj1i9z7.example.com" }, { "event.category": "threat", @@ -195,26 +207,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2862, + "recordedfuture.entity.id": "idn:7pgc.example.org", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A7pgc.example.org", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2017-02-23T17:44:16.104Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.373Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A7pgc.example.org", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "7pgc.example.org", - "threatintel.recordedfuture.entity.id": "idn:7pgc.example.org", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A7pgc.example.org", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2017-02-23T17:44:16.104Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.373Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A7pgc.example.org", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "7pgc.example.org" }, { "event.category": "threat", @@ -226,26 +240,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 3332, + "recordedfuture.entity.id": "idn:xm5u434.example.net", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Axm5u434.example.net", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2017-04-10T06:55:27.658Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.373Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Axm5u434.example.net", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "xm5u434.example.net", - "threatintel.recordedfuture.entity.id": "idn:xm5u434.example.net", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Axm5u434.example.net", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2017-04-10T06:55:27.658Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.373Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Axm5u434.example.net", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "xm5u434.example.net" }, { "event.category": "threat", @@ -257,26 +273,28 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 3811, + "recordedfuture.entity.id": "idn:gpgju.example.com", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Agpgju.example.com", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2018-07-27T15:22:39.390Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:47.373Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Agpgju.example.com", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "gpgju.example.com", - "threatintel.recordedfuture.entity.id": "idn:gpgju.example.com", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Agpgju.example.com", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2018-07-27T15:22:39.390Z", + "threat.indicator.last_seen": "2021-06-20T18:23:47.373Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3Agpgju.example.com", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "gpgju.example.com" }, { "event.category": "threat", @@ -288,25 +306,27 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 4284, + "recordedfuture.entity.id": "idn:55g.example.com", + "recordedfuture.entity.type": "InternetDomainName", + "recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A55g.example.com", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/44", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.first_seen": "2021-01-10T21:24:38.353Z", - "threatintel.indicator.last_seen": "2021-06-20T18:23:45.025Z", - "threatintel.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A55g.example.com", - "threatintel.indicator.type": "domain-name", - "threatintel.indicator.url.domain": "55g.example.com", - "threatintel.recordedfuture.entity.id": "idn:55g.example.com", - "threatintel.recordedfuture.entity.type": "InternetDomainName", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A55g.example.com", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/44", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-01-10T21:24:38.353Z", + "threat.indicator.last_seen": "2021-06-20T18:23:45.025Z", + "threat.indicator.reference": "https://app.recordedfuture.com.local/live/sc/entity/idn%3A55g.example.com", + "threat.indicator.type": "domain-name", + "threat.indicator.url.domain": "55g.example.com" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/test/hash.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/recordedfuture/test/hash.ndjson.log-expected.json index dbc47e31767e..cf8b9c1b23e2 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/test/hash.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/recordedfuture/test/hash.ndjson.log-expected.json @@ -9,24 +9,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 0, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "25328d1a481903f2d900479570842247", - "threatintel.indicator.file.hash.sha1": "d73c663e2ac0c7a14ca0e2681dd599b2e7a24f65", - "threatintel.indicator.file.hash.sha256": "dec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.503Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.503Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Adec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:dec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Adec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:dec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Adec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -44,10 +32,24 @@ "timestamp": "2021-06-20T18:40:18.503Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "25328d1a481903f2d900479570842247", + "threat.indicator.file.hash.sha1": "d73c663e2ac0c7a14ca0e2681dd599b2e7a24f65", + "threat.indicator.file.hash.sha256": "dec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", + "threat.indicator.first_seen": "2021-06-20T18:40:18.503Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.503Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Adec3a20fa1493c8e669b26d3f8b6084b34fda9906c978f9f12fb43f76504b5d6", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -59,24 +61,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 1478, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "7b8d9afd032f0c253b7dd68aca6fb50b", - "threatintel.indicator.file.hash.sha1": "f9ece49c249aabab29fd9c2193d897b7d131ed17", - "threatintel.indicator.file.hash.sha256": "4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.452Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.452Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -94,10 +84,24 @@ "timestamp": "2021-06-20T18:40:18.452Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "7b8d9afd032f0c253b7dd68aca6fb50b", + "threat.indicator.file.hash.sha1": "f9ece49c249aabab29fd9c2193d897b7d131ed17", + "threat.indicator.file.hash.sha256": "4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", + "threat.indicator.first_seen": "2021-06-20T18:40:18.452Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.452Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A4014355fdfee5fe9e01f3a84356d743c022cd75510f6c96ffe16fb332855d6f2", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -109,24 +113,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2954, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "7b65b50ed4554c86cb777e35e7750209", - "threatintel.indicator.file.hash.sha1": "e10942ba3fbb937c90c7cb3e39c06a13324981a8", - "threatintel.indicator.file.hash.sha256": "299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.343Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.343Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -144,10 +136,24 @@ "timestamp": "2021-06-20T18:40:18.343Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "7b65b50ed4554c86cb777e35e7750209", + "threat.indicator.file.hash.sha1": "e10942ba3fbb937c90c7cb3e39c06a13324981a8", + "threat.indicator.file.hash.sha256": "299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", + "threat.indicator.first_seen": "2021-06-20T18:40:18.343Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.343Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A299e7a30217e2137854308e7be79227635f409b0e00897cfff11806ad8449cc5", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -159,24 +165,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 4457, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "c6353df35499ca6934da2169b7bd1635", - "threatintel.indicator.file.hash.sha1": "3e208c649da0a9efbde7bbde6eece2142fdac3f9", - "threatintel.indicator.file.hash.sha256": "e5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.258Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.258Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ae5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:e5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ae5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:e5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ae5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -194,10 +188,24 @@ "timestamp": "2021-06-20T18:40:18.257Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "c6353df35499ca6934da2169b7bd1635", + "threat.indicator.file.hash.sha1": "3e208c649da0a9efbde7bbde6eece2142fdac3f9", + "threat.indicator.file.hash.sha256": "e5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", + "threat.indicator.first_seen": "2021-06-20T18:40:18.258Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.258Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ae5c73c63ba71659fbb9e0670cc203532aa61e3b8fa51f70ee5ce37b66784cd61", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -209,24 +217,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 5932, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "3d568bd03766a8d47c8fabb7d392c32e", - "threatintel.indicator.file.hash.sha1": "3ea8b08bc9ed3009a4d6a0ab5851b8e3fc10ead2", - "threatintel.indicator.file.hash.sha256": "184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.131Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.131Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -236,10 +232,24 @@ "timestamp": "2021-06-19T17:39:24.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/14", - "threatintel.recordedfuture.risk.riskSummary": "1 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "1/14", + "recordedfuture.risk.riskSummary": "1 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "3d568bd03766a8d47c8fabb7d392c32e", + "threat.indicator.file.hash.sha1": "3ea8b08bc9ed3009a4d6a0ab5851b8e3fc10ead2", + "threat.indicator.file.hash.sha256": "184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", + "threat.indicator.first_seen": "2021-06-20T18:40:18.131Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.131Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A184527a5436086cff0c06197330089f7964a9b6b8fc86327e6778363b7297ef1", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -251,24 +261,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 7054, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "a40e91f2d29616076114eea0f2a693af", - "threatintel.indicator.file.hash.sha1": "e38ccd47629c1b75385a83fbfbba0ea7f3b3a705", - "threatintel.indicator.file.hash.sha256": "1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.093Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.093Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -286,10 +284,24 @@ "timestamp": "2021-06-20T18:40:18.093Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "a40e91f2d29616076114eea0f2a693af", + "threat.indicator.file.hash.sha1": "e38ccd47629c1b75385a83fbfbba0ea7f3b3a705", + "threat.indicator.file.hash.sha256": "1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", + "threat.indicator.first_seen": "2021-06-20T18:40:18.093Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.093Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A1136b8991c6f180a6c67eaff7c2a998d67dbcadc2d9cf5a3f816de03503817a8", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -301,24 +313,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 8550, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "02062782c7eeaff185ea6966460f7c9a", - "threatintel.indicator.file.hash.sha1": "64355796dc38992ca5e434682ddbf63bdfabeb4e", - "threatintel.indicator.file.hash.sha256": "bf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.070Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.070Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Abf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:bf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Abf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:bf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Abf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -336,10 +336,24 @@ "timestamp": "2021-06-20T18:40:18.070Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "02062782c7eeaff185ea6966460f7c9a", + "threat.indicator.file.hash.sha1": "64355796dc38992ca5e434682ddbf63bdfabeb4e", + "threat.indicator.file.hash.sha256": "bf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", + "threat.indicator.first_seen": "2021-06-20T18:40:18.070Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.070Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Abf325093d87f746c297b2752c38a41a8f41b32aca01146b3632e24e90cdd14a1", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -351,24 +365,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 10020, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "bdd205ffc81c54e7cc1a9080cfa093e4", - "threatintel.indicator.file.hash.sha1": "a6b928fd6fee43495b96941ef80b25d074f6e0e2", - "threatintel.indicator.file.hash.sha256": "c06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", - "threatintel.indicator.first_seen": "2021-06-20T18:40:18.011Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:18.011Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:c06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:c06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -386,10 +388,24 @@ "timestamp": "2021-06-20T18:40:18.010Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "bdd205ffc81c54e7cc1a9080cfa093e4", + "threat.indicator.file.hash.sha1": "a6b928fd6fee43495b96941ef80b25d074f6e0e2", + "threat.indicator.file.hash.sha256": "c06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", + "threat.indicator.first_seen": "2021-06-20T18:40:18.011Z", + "threat.indicator.last_seen": "2021-06-20T18:40:18.011Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac06f58340d8e7b1f466942db18f67b5eb048c9adc45d843db370c836e125e3f9", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -401,24 +417,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 11492, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "af45390e39574cdb037d684074e6a542", - "threatintel.indicator.file.hash.sha1": "f6a14c7424604cd51ba6a6d3f7594ec762f48645", - "threatintel.indicator.file.hash.sha256": "c878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", - "threatintel.indicator.first_seen": "2021-06-20T18:40:17.964Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:17.964Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:c878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:c878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -436,10 +440,24 @@ "timestamp": "2021-06-20T18:40:17.964Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "af45390e39574cdb037d684074e6a542", + "threat.indicator.file.hash.sha1": "f6a14c7424604cd51ba6a6d3f7594ec762f48645", + "threat.indicator.file.hash.sha256": "c878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", + "threat.indicator.first_seen": "2021-06-20T18:40:17.964Z", + "threat.indicator.last_seen": "2021-06-20T18:40:17.964Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3Ac878bdb6c62ace8f001f979f7c7b2c6b38d135ac1c69bfa63785bf86721619fc", + "threat.indicator.type": "file" }, { "event.category": "threat", @@ -451,24 +469,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 12964, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.file.hash.md5": "5b8bcd367f802cd104210bb47abb3ab1", - "threatintel.indicator.file.hash.sha1": "b40d1796bd6974860ce6be691152ad963300c711", - "threatintel.indicator.file.hash.sha256": "0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", - "threatintel.indicator.first_seen": "2021-06-20T18:40:17.919Z", - "threatintel.indicator.last_seen": "2021-06-20T18:40:17.919Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", - "threatintel.indicator.type": "file", - "threatintel.recordedfuture.entity.id": "hash:0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", - "threatintel.recordedfuture.entity.type": "Hash", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", - "threatintel.recordedfuture.risk.criticality": 3, - "threatintel.recordedfuture.risk.criticalityLabel": "Malicious", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "hash:0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", + "recordedfuture.entity.type": "Hash", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/hash%3A0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", + "recordedfuture.risk.criticality": 3, + "recordedfuture.risk.criticalityLabel": "Malicious", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 3, "criticalityLabel": "Malicious", @@ -486,9 +492,23 @@ "timestamp": "2021-06-20T18:40:17.919Z" } ], - "threatintel.recordedfuture.risk.riskString": "2/14", - "threatintel.recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 2, - "threatintel.recordedfuture.risk.score": 65 + "recordedfuture.risk.riskString": "2/14", + "recordedfuture.risk.riskSummary": "2 of 14 Risk Rules currently observed.", + "recordedfuture.risk.rules": 2, + "recordedfuture.risk.score": 65, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.file.hash.md5": "5b8bcd367f802cd104210bb47abb3ab1", + "threat.indicator.file.hash.sha1": "b40d1796bd6974860ce6be691152ad963300c711", + "threat.indicator.file.hash.sha256": "0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", + "threat.indicator.first_seen": "2021-06-20T18:40:17.919Z", + "threat.indicator.last_seen": "2021-06-20T18:40:17.919Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/hash%3A0996575c7d2f07513d0dafe67ddde9805bbea35cf9d98edf8faf12c0e7f4334c", + "threat.indicator.type": "file" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/test/ip.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/recordedfuture/test/ip.ndjson.log-expected.json index 74488f715daf..c46c3e2a51f1 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/test/ip.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/recordedfuture/test/ip.ndjson.log-expected.json @@ -9,32 +9,34 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 0, + "recordedfuture.entity.id": "ip:2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", + "recordedfuture.entity.name": "2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", + "recordedfuture.ip_range": "2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 31287, - "threatintel.indicator.as.organization.name": "IPACCT CABLE Ltd", - "threatintel.indicator.first_seen": "2021-04-18T00:11:48.512Z", - "threatintel.indicator.geo.city_name": "Radnevo", - "threatintel.indicator.geo.continent_name": "Europe", - "threatintel.indicator.geo.country_name": "Bulgaria", - "threatintel.indicator.last_seen": "2021-06-19T19:40:32.897Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", - "threatintel.indicator.type": "ipv6-addr", - "threatintel.recordedfuture.entity.id": "ip:2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", - "threatintel.recordedfuture.entity.name": "2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", - "threatintel.recordedfuture.ip_range": "2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 31287, + "threat.indicator.as.organization.name": "IPACCT CABLE Ltd", + "threat.indicator.first_seen": "2021-04-18T00:11:48.512Z", + "threat.indicator.geo.city_name": "Radnevo", + "threat.indicator.geo.continent_name": "Europe", + "threat.indicator.geo.country_name": "Bulgaria", + "threat.indicator.last_seen": "2021-06-19T19:40:32.897Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:cdb4:ff33:c406:fcdc:6961:c8af/21", + "threat.indicator.type": "ipv6-addr" }, { "event.category": "threat", @@ -46,32 +48,33 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 763, + "recordedfuture.entity.id": "ip:2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", + "recordedfuture.ip_range": "2001:db8:f800:5c3f:c9f8:fbf8:d537:9071/128", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 197207, - "threatintel.indicator.as.organization.name": "Mobile Communication Company of Iran PLC", - "threatintel.indicator.first_seen": "2021-06-19T17:55:58.019Z", - "threatintel.indicator.geo.city_name": null, - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "Iran", - "threatintel.indicator.ip": "2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", - "threatintel.indicator.last_seen": "2021-06-19T19:40:32.839Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", - "threatintel.indicator.type": "ipv6-addr", - "threatintel.recordedfuture.entity.id": "ip:2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", - "threatintel.recordedfuture.ip_range": "2001:db8:f800:5c3f:c9f8:fbf8:d537:9071/128", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 197207, + "threat.indicator.as.organization.name": "Mobile Communication Company of Iran PLC", + "threat.indicator.first_seen": "2021-06-19T17:55:58.019Z", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "Iran", + "threat.indicator.ip": "2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", + "threat.indicator.last_seen": "2021-06-19T19:40:32.839Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:f800:5c3f:c9f8:fbf8:d537:9071", + "threat.indicator.type": "ipv6-addr" }, { "event.category": "threat", @@ -83,31 +86,29 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 1531, + "recordedfuture.entity.id": "ip:203.0.113.55", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.55", + "recordedfuture.ip_range": "203.0.113.55/32", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.organization.name": null, - "threatintel.indicator.first_seen": "2021-06-19T19:40:30.596Z", - "threatintel.indicator.geo.city_name": null, - "threatintel.indicator.geo.continent_name": null, - "threatintel.indicator.geo.country_name": null, - "threatintel.indicator.ip": "203.0.113.55", - "threatintel.indicator.last_seen": "2021-06-19T19:40:30.596Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.55", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:203.0.113.55", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.55", - "threatintel.recordedfuture.ip_range": "203.0.113.55/32", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-19T19:40:30.596Z", + "threat.indicator.ip": "203.0.113.55", + "threat.indicator.last_seen": "2021-06-19T19:40:30.596Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.55", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -119,32 +120,34 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2161, + "recordedfuture.entity.id": "ip:203.0.113.108", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.108", + "recordedfuture.ip_range": "203.0.113.108/32", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 17622, - "threatintel.indicator.as.organization.name": "China Unicom Guangzhou network", - "threatintel.indicator.first_seen": "2021-06-19T19:40:20.534Z", - "threatintel.indicator.geo.city_name": "Guangzhou", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "China", - "threatintel.indicator.ip": "203.0.113.108", - "threatintel.indicator.last_seen": "2021-06-19T19:40:20.534Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.108", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:203.0.113.108", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.108", - "threatintel.recordedfuture.ip_range": "203.0.113.108/32", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 17622, + "threat.indicator.as.organization.name": "China Unicom Guangzhou network", + "threat.indicator.first_seen": "2021-06-19T19:40:20.534Z", + "threat.indicator.geo.city_name": "Guangzhou", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "China", + "threat.indicator.ip": "203.0.113.108", + "threat.indicator.last_seen": "2021-06-19T19:40:20.534Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.108", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -156,32 +159,33 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2851, + "recordedfuture.entity.id": "ip:203.0.113.139", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.139", + "recordedfuture.ip_range": "203.0.113.139/32", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 7713, - "threatintel.indicator.as.organization.name": "PT Telekomunikasi Indonesia", - "threatintel.indicator.first_seen": "2016-06-23T07:39:06.418Z", - "threatintel.indicator.geo.city_name": null, - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "Indonesia", - "threatintel.indicator.ip": "203.0.113.139", - "threatintel.indicator.last_seen": "2021-06-19T19:40:03.882Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.139", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:203.0.113.139", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.139", - "threatintel.recordedfuture.ip_range": "203.0.113.139/32", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 7713, + "threat.indicator.as.organization.name": "PT Telekomunikasi Indonesia", + "threat.indicator.first_seen": "2016-06-23T07:39:06.418Z", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "Indonesia", + "threat.indicator.ip": "203.0.113.139", + "threat.indicator.last_seen": "2021-06-19T19:40:03.882Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.139", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -193,32 +197,34 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 3532, + "recordedfuture.entity.id": "ip:2001:db8:bf58:c5c3:7a06:5267:82e0:621a", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:bf58:c5c3:7a06:5267:82e0:621a", + "recordedfuture.ip_range": "2001:db8:bf58:c5c3:7a06:5267:82e0:621a/128", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 17622, - "threatintel.indicator.as.organization.name": "China Unicom Guangzhou network", - "threatintel.indicator.first_seen": "2021-06-19T19:40:02.557Z", - "threatintel.indicator.geo.city_name": "Guangzhou", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "China", - "threatintel.indicator.ip": "2001:db8:bf58:c5c3:7a06:5267:82e0:621a", - "threatintel.indicator.last_seen": "2021-06-19T19:40:02.557Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:bf58:c5c3:7a06:5267:82e0:621a", - "threatintel.indicator.type": "ipv6-addr", - "threatintel.recordedfuture.entity.id": "ip:2001:db8:bf58:c5c3:7a06:5267:82e0:621a", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:bf58:c5c3:7a06:5267:82e0:621a", - "threatintel.recordedfuture.ip_range": "2001:db8:bf58:c5c3:7a06:5267:82e0:621a/128", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 17622, + "threat.indicator.as.organization.name": "China Unicom Guangzhou network", + "threat.indicator.first_seen": "2021-06-19T19:40:02.557Z", + "threat.indicator.geo.city_name": "Guangzhou", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "China", + "threat.indicator.ip": "2001:db8:bf58:c5c3:7a06:5267:82e0:621a", + "threat.indicator.last_seen": "2021-06-19T19:40:02.557Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A2001:db8:bf58:c5c3:7a06:5267:82e0:621a", + "threat.indicator.type": "ipv6-addr" }, { "event.category": "threat", @@ -230,32 +236,34 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 4295, + "recordedfuture.entity.id": "ip:192.0.2.147", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.147", + "recordedfuture.ip_range": "192.0.2.147/32", + "recordedfuture.risk.criticality": 0, + "recordedfuture.risk.criticalityLabel": "None", + "recordedfuture.risk.evidenceDetails": [], + "recordedfuture.risk.riskString": "0/54", + "recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", + "recordedfuture.risk.rules": 0, + "recordedfuture.risk.score": 0, "service.type": "threatintel", "tags": [ "forwarded", "threatintel-recordedfuture" ], - "threatintel.indicator.as.number": 4837, - "threatintel.indicator.as.organization.name": "CHINA UNICOM China169 Backbone", - "threatintel.indicator.first_seen": "2017-12-20T02:21:07.734Z", - "threatintel.indicator.geo.city_name": "Zhengzhou", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "China", - "threatintel.indicator.ip": "192.0.2.147", - "threatintel.indicator.last_seen": "2021-06-19T19:39:43.160Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.147", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:192.0.2.147", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.147", - "threatintel.recordedfuture.ip_range": "192.0.2.147/32", - "threatintel.recordedfuture.risk.criticality": 0, - "threatintel.recordedfuture.risk.criticalityLabel": "None", - "threatintel.recordedfuture.risk.evidenceDetails": [], - "threatintel.recordedfuture.risk.riskString": "0/54", - "threatintel.recordedfuture.risk.riskSummary": "No Risk Rules are currently observed.", - "threatintel.recordedfuture.risk.rules": 0, - "threatintel.recordedfuture.risk.score": 0 + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 4837, + "threat.indicator.as.organization.name": "CHINA UNICOM China169 Backbone", + "threat.indicator.first_seen": "2017-12-20T02:21:07.734Z", + "threat.indicator.geo.city_name": "Zhengzhou", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "China", + "threat.indicator.ip": "192.0.2.147", + "threat.indicator.last_seen": "2021-06-19T19:39:43.160Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.147", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -267,28 +275,13 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 4972, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.as.number": 9829, - "threatintel.indicator.as.organization.name": "National Internet Backbone", - "threatintel.indicator.first_seen": "2019-12-24T09:54:02.935Z", - "threatintel.indicator.geo.city_name": "Palakkad", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "India", - "threatintel.indicator.ip": "203.0.113.198", - "threatintel.indicator.last_seen": "2021-06-19T19:39:25.532Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.198", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:203.0.113.198", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.198", - "threatintel.recordedfuture.ip_range": "203.0.113.198/32", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "ip:203.0.113.198", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.198", + "recordedfuture.ip_range": "203.0.113.198/32", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -298,10 +291,27 @@ "timestamp": "2019-12-24T09:53:13.546Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/54", - "threatintel.recordedfuture.risk.riskSummary": "1 of 54 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/54", + "recordedfuture.risk.riskSummary": "1 of 54 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 9829, + "threat.indicator.as.organization.name": "National Internet Backbone", + "threat.indicator.first_seen": "2019-12-24T09:54:02.935Z", + "threat.indicator.geo.city_name": "Palakkad", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "India", + "threat.indicator.ip": "203.0.113.198", + "threat.indicator.last_seen": "2021-06-19T19:39:25.532Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A203.0.113.198", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -313,28 +323,13 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 5970, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.as.number": 9829, - "threatintel.indicator.as.organization.name": "National Internet Backbone", - "threatintel.indicator.first_seen": "2020-03-03T08:10:28.489Z", - "threatintel.indicator.geo.city_name": "Bangalore", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "India", - "threatintel.indicator.ip": "192.0.2.179", - "threatintel.indicator.last_seen": "2021-06-19T19:39:11.694Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.179", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:192.0.2.179", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.179", - "threatintel.recordedfuture.ip_range": "192.0.2.179/32", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "ip:192.0.2.179", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.179", + "recordedfuture.ip_range": "192.0.2.179/32", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -360,10 +355,27 @@ "timestamp": "2021-06-21T19:53:19.897Z" } ], - "threatintel.recordedfuture.risk.riskString": "3/54", - "threatintel.recordedfuture.risk.riskSummary": "3 of 54 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 3, - "threatintel.recordedfuture.risk.score": 15 + "recordedfuture.risk.riskString": "3/54", + "recordedfuture.risk.riskSummary": "3 of 54 Risk Rules currently observed.", + "recordedfuture.risk.rules": 3, + "recordedfuture.risk.score": 15, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 9829, + "threat.indicator.as.organization.name": "National Internet Backbone", + "threat.indicator.first_seen": "2020-03-03T08:10:28.489Z", + "threat.indicator.geo.city_name": "Bangalore", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "India", + "threat.indicator.ip": "192.0.2.179", + "threat.indicator.last_seen": "2021-06-19T19:39:11.694Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.179", + "threat.indicator.type": "ipv4-addr" }, { "event.category": "threat", @@ -375,28 +387,13 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 7483, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.as.number": 45899, - "threatintel.indicator.as.organization.name": "VNPT Corp", - "threatintel.indicator.first_seen": "2021-06-19T19:38:57.372Z", - "threatintel.indicator.geo.city_name": "Long Phu", - "threatintel.indicator.geo.continent_name": "Asia", - "threatintel.indicator.geo.country_name": "Vietnam", - "threatintel.indicator.ip": "192.0.2.245", - "threatintel.indicator.last_seen": "2021-06-19T19:38:57.372Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.245", - "threatintel.indicator.type": "ipv4-addr", - "threatintel.recordedfuture.entity.id": "ip:192.0.2.245", - "threatintel.recordedfuture.entity.type": "IpAddress", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.245", - "threatintel.recordedfuture.ip_range": "192.0.2.245/32", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "ip:192.0.2.245", + "recordedfuture.entity.type": "IpAddress", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.245", + "recordedfuture.ip_range": "192.0.2.245/32", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -406,9 +403,26 @@ "timestamp": "2021-06-19T19:50:20.162Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/54", - "threatintel.recordedfuture.risk.riskSummary": "1 of 54 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/54", + "recordedfuture.risk.riskSummary": "1 of 54 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.as.number": 45899, + "threat.indicator.as.organization.name": "VNPT Corp", + "threat.indicator.first_seen": "2021-06-19T19:38:57.372Z", + "threat.indicator.geo.city_name": "Long Phu", + "threat.indicator.geo.continent_name": "Asia", + "threat.indicator.geo.country_name": "Vietnam", + "threat.indicator.ip": "192.0.2.245", + "threat.indicator.last_seen": "2021-06-19T19:38:57.372Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/ip%3A192.0.2.245", + "threat.indicator.type": "ipv4-addr" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/recordedfuture/test/url.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/recordedfuture/test/url.ndjson.log-expected.json index 779d86ae9652..f840643fef3b 100644 --- a/x-pack/filebeat/module/threatintel/recordedfuture/test/url.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/recordedfuture/test/url.ndjson.log-expected.json @@ -9,26 +9,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 0, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "d6s.example.net", - "threatintel.indicator.url.original": "https://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", - "threatintel.indicator.url.path": "/nzy/vvc68ke", - "threatintel.indicator.url.query": "p5uxwn=1bj", - "threatintel.indicator.url.scheme": "https", - "threatintel.recordedfuture.entity.id": "url:https://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:https://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -38,10 +24,26 @@ "timestamp": "2021-04-15T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "d6s.example.net", + "threat.indicator.url.original": "https://d6s.example.net/nzy/vvc68ke?p5uxwn=1bj", + "threat.indicator.url.path": "/nzy/vvc68ke", + "threat.indicator.url.query": "p5uxwn=1bj", + "threat.indicator.url.scheme": "https" }, { "event.category": "threat", @@ -53,26 +55,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 874, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "ga7v9u.example.org", - "threatintel.indicator.url.original": "https://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", - "threatintel.indicator.url.path": "/bnqv8e2v8/qb49", - "threatintel.indicator.url.query": "7kq=iw61", - "threatintel.indicator.url.scheme": "https", - "threatintel.recordedfuture.entity.id": "url:https://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:https://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -82,10 +70,26 @@ "timestamp": "2021-02-14T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "ga7v9u.example.org", + "threat.indicator.url.original": "https://ga7v9u.example.org/bnqv8e2v8/qb49?7kq=iw61", + "threat.indicator.url.path": "/bnqv8e2v8/qb49", + "threat.indicator.url.query": "7kq=iw61", + "threat.indicator.url.scheme": "https" }, { "event.category": "threat", @@ -97,26 +101,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 1760, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "cdmw.example.net", - "threatintel.indicator.url.original": "https://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", - "threatintel.indicator.url.path": "/c20fwa/wwn", - "threatintel.indicator.url.query": "dlz53=z6ovc", - "threatintel.indicator.url.scheme": "https", - "threatintel.recordedfuture.entity.id": "url:https://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:https://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -126,10 +116,26 @@ "timestamp": "2021-05-15T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "cdmw.example.net", + "threat.indicator.url.original": "https://cdmw.example.net/c20fwa/wwn?dlz53=z6ovc", + "threat.indicator.url.path": "/c20fwa/wwn", + "threat.indicator.url.query": "dlz53=z6ovc", + "threat.indicator.url.scheme": "https" }, { "event.category": "threat", @@ -141,26 +147,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 2627, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "4mne.example.local", - "threatintel.indicator.url.original": "https://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", - "threatintel.indicator.url.path": "/ns2rk8f/wngtk2xz", - "threatintel.indicator.url.query": "vceuk7wl6=3p0", - "threatintel.indicator.url.scheme": "https", - "threatintel.recordedfuture.entity.id": "url:https://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:https://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -170,10 +162,26 @@ "timestamp": "2021-02-14T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "4mne.example.local", + "threat.indicator.url.original": "https://4mne.example.local/ns2rk8f/wngtk2xz?vceuk7wl6=3p0", + "threat.indicator.url.path": "/ns2rk8f/wngtk2xz", + "threat.indicator.url.query": "vceuk7wl6=3p0", + "threat.indicator.url.scheme": "https" }, { "event.category": "threat", @@ -185,26 +193,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 3524, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "z198hloc8.example.com", - "threatintel.indicator.url.original": "http://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", - "threatintel.indicator.url.path": "/f8ih39/f6kou", - "threatintel.indicator.url.query": "f6-u3=uwhii", - "threatintel.indicator.url.scheme": "http", - "threatintel.recordedfuture.entity.id": "url:http://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:http://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -214,10 +208,26 @@ "timestamp": "2020-06-24T12:01:33.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "z198hloc8.example.com", + "threat.indicator.url.original": "http://z198hloc8.example.com/f8ih39/f6kou?f6-u3=uwhii", + "threat.indicator.url.path": "/f8ih39/f6kou", + "threat.indicator.url.query": "f6-u3=uwhii", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -229,26 +239,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 4377, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "y484j-fb6.example.local", - "threatintel.indicator.url.original": "http://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", - "threatintel.indicator.url.path": "/b97s24xf/prz", - "threatintel.indicator.url.query": "sg-x1do=4myont", - "threatintel.indicator.url.scheme": "http", - "threatintel.recordedfuture.entity.id": "url:http://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:http://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -258,10 +254,26 @@ "timestamp": "2021-02-14T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "y484j-fb6.example.local", + "threat.indicator.url.original": "http://y484j-fb6.example.local/b97s24xf/prz?sg-x1do=4myont", + "threat.indicator.url.path": "/b97s24xf/prz", + "threat.indicator.url.query": "sg-x1do=4myont", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -273,26 +285,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 5272, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "sp2xyqq82.example.local", - "threatintel.indicator.url.original": "http://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", - "threatintel.indicator.url.path": "/zxvm093/kat1rcz", - "threatintel.indicator.url.query": "vaev0aeod=rc0513", - "threatintel.indicator.url.scheme": "http", - "threatintel.recordedfuture.entity.id": "url:http://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:http://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -302,10 +300,26 @@ "timestamp": "2020-11-16T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "sp2xyqq82.example.local", + "threat.indicator.url.original": "http://sp2xyqq82.example.local/zxvm093/kat1rcz?vaev0aeod=rc0513", + "threat.indicator.url.path": "/zxvm093/kat1rcz", + "threat.indicator.url.query": "vaev0aeod=rc0513", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -317,26 +331,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 6187, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "zh4o7xc.example.com", - "threatintel.indicator.url.original": "https://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", - "threatintel.indicator.url.path": "/-yiq/vg2whtxif", - "threatintel.indicator.url.query": "cb0-knk=s6poib5r", - "threatintel.indicator.url.scheme": "https", - "threatintel.recordedfuture.entity.id": "url:https://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:https://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -346,10 +346,26 @@ "timestamp": "2021-05-15T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttps://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "zh4o7xc.example.com", + "threat.indicator.url.original": "https://zh4o7xc.example.com/-yiq/vg2whtxif?cb0-knk=s6poib5r", + "threat.indicator.url.path": "/-yiq/vg2whtxif", + "threat.indicator.url.query": "cb0-knk=s6poib5r", + "threat.indicator.url.scheme": "https" }, { "event.category": "threat", @@ -361,26 +377,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 7094, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "fiivf4s.example.org", - "threatintel.indicator.url.original": "http://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", - "threatintel.indicator.url.path": "/8u2qi/86vfcfq7m", - "threatintel.indicator.url.query": "pfb2ensc0=h7imk8io2", - "threatintel.indicator.url.scheme": "http", - "threatintel.recordedfuture.entity.id": "url:http://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:http://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -390,10 +392,26 @@ "timestamp": "2021-02-14T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "fiivf4s.example.org", + "threat.indicator.url.original": "http://fiivf4s.example.org/8u2qi/86vfcfq7m?pfb2ensc0=h7imk8io2", + "threat.indicator.url.path": "/8u2qi/86vfcfq7m", + "threat.indicator.url.query": "pfb2ensc0=h7imk8io2", + "threat.indicator.url.scheme": "http" }, { "event.category": "threat", @@ -405,26 +423,12 @@ "fileset.name": "recordedfuture", "input.type": "log", "log.offset": 8007, - "service.type": "threatintel", - "tags": [ - "forwarded", - "threatintel-recordedfuture" - ], - "threatintel.indicator.first_seen": "2021-06-20T00:00:00.000Z", - "threatintel.indicator.last_seen": "2021-06-20T23:59:59.000Z", - "threatintel.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", - "threatintel.indicator.type": "url", - "threatintel.indicator.url.domain": "abav9v.example.org", - "threatintel.indicator.url.original": "http://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", - "threatintel.indicator.url.path": "/gj93q/7fs7", - "threatintel.indicator.url.query": "kcq7=pjaj1", - "threatintel.indicator.url.scheme": "http", - "threatintel.recordedfuture.entity.id": "url:http://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", - "threatintel.recordedfuture.entity.type": "URL", - "threatintel.recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", - "threatintel.recordedfuture.risk.criticality": 1, - "threatintel.recordedfuture.risk.criticalityLabel": "Unusual", - "threatintel.recordedfuture.risk.evidenceDetails": [ + "recordedfuture.entity.id": "url:http://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", + "recordedfuture.entity.type": "URL", + "recordedfuture.intelCard": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", + "recordedfuture.risk.criticality": 1, + "recordedfuture.risk.criticalityLabel": "Unusual", + "recordedfuture.risk.evidenceDetails": [ { "criticality": 1, "criticalityLabel": "Unusual", @@ -434,9 +438,25 @@ "timestamp": "2021-02-14T00:00:00.000Z" } ], - "threatintel.recordedfuture.risk.riskString": "1/25", - "threatintel.recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", - "threatintel.recordedfuture.risk.rules": 1, - "threatintel.recordedfuture.risk.score": 5 + "recordedfuture.risk.riskString": "1/25", + "recordedfuture.risk.riskSummary": "1 of 25 Risk Rules currently observed.", + "recordedfuture.risk.rules": 1, + "recordedfuture.risk.score": 5, + "service.type": "threatintel", + "tags": [ + "forwarded", + "threatintel-recordedfuture" + ], + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] RecordedFuture", + "threat.indicator.first_seen": "2021-06-20T00:00:00.000Z", + "threat.indicator.last_seen": "2021-06-20T23:59:59.000Z", + "threat.indicator.reference": "https://app.recordedfuture.local/live/sc/entity/url%3Ahttp://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", + "threat.indicator.type": "url", + "threat.indicator.url.domain": "abav9v.example.org", + "threat.indicator.url.original": "http://abav9v.example.org/gj93q/7fs7?kcq7=pjaj1", + "threat.indicator.url.path": "/gj93q/7fs7", + "threat.indicator.url.query": "kcq7=pjaj1", + "threat.indicator.url.scheme": "http" } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/threatintel/threatq/config/config.yml b/x-pack/filebeat/module/threatintel/threatq/config/config.yml index 89e8cab731ec..0f520215bc8f 100644 --- a/x-pack/filebeat/module/threatintel/threatq/config/config.yml +++ b/x-pack/filebeat/module/threatintel/threatq/config/config.yml @@ -1,7 +1,6 @@ {{ if eq .input "httpjson" }} type: httpjson -config_version: "2" interval: {{ .interval }} auth.oauth2: @@ -50,22 +49,12 @@ exclude_files: [".gz$"] {{ end }} -tags: {{.tags | tojson}} -publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +tags: +{{if .preserve_original_event}} + - preserve_original_event +{{end}} +{{range $val := .tags}} + - {{$val}} +{{end}} -processors: - - decode_json_fields: - fields: [message] - target: json - process_array: true - max_depth: 5 - overwrite_keys: true - add_error_key: true - - fingerprint: - fields: ["json.id", "json.indicator_id"] - target_field: "@metadata._id" - ignore_missing: true - - add_fields: - target: '' - fields: - ecs.version: 1.12.0 \ No newline at end of file +publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/threatintel/threatq/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/threatq/ingest/pipeline.yml index 6d301f898444..96f8b224e19a 100644 --- a/x-pack/filebeat/module/threatintel/threatq/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/threatq/ingest/pipeline.yml @@ -1,3 +1,4 @@ +--- description: Pipeline for parsing ThreatQ Threat Intel processors: #################### @@ -6,6 +7,9 @@ processors: - set: field: event.ingested value: "{{_ingest.timestamp}}" + - set: + field: ecs.version + value: "1.12" - set: field: event.kind value: enrichment @@ -19,6 +23,19 @@ processors: ############### # Parse dates # ############### + - rename: + field: message + target_field: event.original + ignore_missing: true + - json: + field: event.original + target_field: json + - fingerprint: + fields: + - json.id + - json.indicator_id + target_field: "_id" + ignore_missing: true - date: target_field: "@timestamp" field: "json.updated_at" @@ -27,28 +44,28 @@ processors: if: "ctx.json.updated_at != null" ignore_failure: true - date: - target_field: "threatintel.threatq.created_at" + target_field: "threatq.created_at" field: "json.created_at" formats: - "yyyy-MM-dd HH:mm:ss" if: "ctx.json.created_at != null" ignore_failure: true - date: - target_field: "threatintel.threatq.expires_at" + target_field: "threatq.expires_at" field: "json.expires_at" formats: - "yyyy-MM-dd HH:mm:ss" if: "ctx.json.expires_at != null" ignore_failure: true - date: - target_field: "threatintel.threatq.expires_calculated_at" + target_field: "threatq.expires_calculated_at" field: "json.expires_calculated_at" formats: - "yyyy-MM-dd HH:mm:ss" if: "ctx.json.expires_calculated_at != null" ignore_failure: true - date: - target_field: "threatintel.threatq.published_at" + target_field: "threatq.published_at" field: "json.published_at" formats: - "yyyy-MM-dd HH:mm:ss" @@ -58,29 +75,50 @@ processors: ##################### # Threat ECS Fields # ##################### + - set: + field: threat.feed.name + value: "[Filebeat] ThreatQuotient" + - set: + field: threat.feed.dashboard_id + value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" - rename: field: json.type.name - target_field: threatintel.indicator.type + target_field: threat.indicator.type ignore_missing: true - rename: field: json.description - target_field: threatintel.indicator.description + target_field: threat.indicator.description ignore_missing: true - - convert: - field: json.score - target_field: threatintel.indicator.confidence - type: integer - on_failure: - - append: - field: error.message - value: "Cannot convert json.score to integer: {{{ _ingest.on_failure_message }}}" + - script: + lang: painless + if: ctx.json?.score != null + description: > + Normalize confidence level. + source: > + def value = ctx.json.score; + if (value <= 0.0 || value > 100.0) { + ctx.threat.indicator.confidence = "None"; + return; + } + if (value >= 1.0 && value <= 29.0) { + ctx.threat.indicator.confidence = "Low"; + return; + } + if (value >= 30.0 && value <= 69.0) { + ctx.threat.indicator.confidence = "Med"; + return; + } + if (value >= 70 && value <= 100) { + ctx.threat.indicator.confidence = "High"; + return; + } - rename: field: json.status.name - target_field: threatintel.threatq.status + target_field: threatq.status ignore_missing: true - rename: field: json.value - target_field: threatintel.threatq.indicator_value + target_field: threatq.indicator_value ignore_missing: true ######################################### @@ -89,119 +127,144 @@ processors: # Indicator type: Email Address - set: - field: threatintel.indicator.email.address - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'Email Address'" + field: threat.indicator.email.address + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'Email Address'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: email-addr - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'Email Address'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'Email Address'" # Indicator type: FQDN - set: - field: threatintel.indicator.domain - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'FQDN'" + field: threat.indicator.domain + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'FQDN'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: domain-name - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'FQDN'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'FQDN'" # Indicator type: IP Address - set: - field: threatintel.indicator.ip - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'IP Address'" + field: threat.indicator.ip + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'IP Address'" + ignore_empty_value: true + - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv4-addr - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'IP Address'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'IP Address'" # Indicator type: IPv6 Address - set: - field: threatintel.indicator.domain - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'IPv6 Address'" + field: threat.indicator.domain + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'IPv6 Address'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: ipv6-addr - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'IPv6 Address'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'IPv6 Address'" # Indicator type: MD5 - set: - field: threatintel.indicator.file.hash.md5 - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'MD5'" + field: threat.indicator.file.hash.md5 + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'MD5'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'MD5'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'MD5'" # Indicator type: SHA-1 - set: - field: threatintel.indicator.file.hash.sha1 - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-1'" + field: threat.indicator.file.hash.sha1 + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-1'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-1'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-1'" # Indicator type: SHA-256 - set: - field: threatintel.indicator.file.hash.sha256 - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-256'" + field: threat.indicator.file.hash.sha256 + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-256'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-256'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-256'" # Indicator type: SHA-512 - set: - field: threatintel.indicator.file.hash.sha512 - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-512'" + field: threat.indicator.file.hash.sha512 + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-512'" + ignore_empty_value: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: file - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'SHA-512'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'SHA-512'" # Indicator type: URL + - uri_parts: + field: threatq.indicator_value + target_field: threat.indicator.url + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'URL' && ctx.threatq?.indicator_value != null" + remove_if_successful: true - set: - field: threatintel.indicator.url.full - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'URL'" - - set: - field: threatintel.indicator.type + field: threat.indicator.type value: url - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'URL'" + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'URL'" # Indicator type: x509 Serial - set: - field: threatintel.indicator.x509.serial_number - value: "{{threatintel.threatq.indicator_value}}" - if: "ctx?.threatintel?.indicator?.type != null && ctx?.threatintel?.indicator?.type == 'x509 Serial'" + field: threat.indicator.x509.serial_number + copy_from: threatq.indicator_value + if: "ctx.threat?.indicator?.type != null && ctx.threat?.indicator?.type == 'x509 Serial'" + ignore_empty_value: true ################################### # Map indicator providers and TLP # ################################### - - foreach: - description: Append threat intel sources - field: json.sources - ignore_missing: true - processor: - append: - field: threatintel.indicator.provider - value: "{{{ _ingest._value.name }}}" - - foreach: - description: Append threat intel source TLP values - field: json.sources - ignore_missing: true - processor: - append: - field: threatintel.indicator.marking.tlp - value: "{{{ _ingest._value.tlp_name }}}" + - script: + if: "ctx.json?.sources != null && ctx.json?.sources instanceof List && ctx.json?.sources.size() > 0" + lang: painless + description: "Extract TLP and providers from source" + source: |- + def providers = new ArrayList(); + def tlps = new ArrayList(); + for (source in ctx.json.sources) { + if (source == null) { + return; + } + if (source.containsKey("provider") && source["provider"] != null) { + providers.add(source["provider"]); + } + if (source.containsKey("tlp_name") && source["tlp_name"] != null) { + tlps.add(source["tlp_name"]); + } + } + if (tlps.size() > 0) { + if (ctx.threat.indicator.marking == null) { + ctx.threat.indicator.marking = new HashMap(); + } + ctx.threat.indicator.marking.tlp = tlps; + } + if (providers.size() > 0) { + if (ctx.threat.indicator.provider == null) { + ctx.threat.indicator.provider = new HashMap(); + } + ctx.threat.indicator.provider = providers; + } ############################ # Map indicator attributes # @@ -228,7 +291,7 @@ processors: ignore_missing: true processor: append: - field: threatintel.threatq.attributes.{{{ _ingest._value.name }}} + field: threatq.attributes.{{{ _ingest._value.name }}} value: "{{{ _ingest._value.value }}}" ############################# @@ -239,20 +302,25 @@ processors: ignore_missing: true processor: append: - field: threatintel.threatq.adversaries + field: threatq.adversaries value: "{{{ _ingest._value.name }}}" ###################### # Cleanup processors # ###################### # Setting indicator type to unknown if it does not match anything + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true - set: - field: threatintel.indicator.type + field: threat.indicator.type value: unknown - if: ctx?.threatintel?.indicator?.type == null + if: ctx.threat?.indicator?.type == null - script: lang: painless - if: ctx?.threatintel != null + if: ctx.threat != null source: | void handleMap(Map map) { for (def x : map.values()) { diff --git a/x-pack/filebeat/module/threatintel/threatq/manifest.yml b/x-pack/filebeat/module/threatintel/threatq/manifest.yml index dd7165b182f1..d5628d2a705d 100644 --- a/x-pack/filebeat/module/threatintel/threatq/manifest.yml +++ b/x-pack/filebeat/module/threatintel/threatq/manifest.yml @@ -11,11 +11,13 @@ var: - name: client_id - name: client_secret - name: host - default: "https://www.threatq.com/" + default: "https://www.threatq.com" - name: proxy_url - name: http_client_timeout - name: tags default: [threatintel-threatq, forwarded] + - name: preserve_original_event + default: false ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/threatintel/threatq/test/threatq_sample.ndjson.log-expected.json b/x-pack/filebeat/module/threatintel/threatq/test/threatq_sample.ndjson.log-expected.json index 58c61e5161c5..58958850bd53 100644 --- a/x-pack/filebeat/module/threatintel/threatq/test/threatq_sample.ndjson.log-expected.json +++ b/x-pack/filebeat/module/threatintel/threatq/test/threatq_sample.ndjson.log-expected.json @@ -14,38 +14,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.44.202.220", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.44.202.220", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "3" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Saipan" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "MP" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.44.202.220", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.44.202.220", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -62,38 +58,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.94.155.176", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.94.155.176", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Sacramento" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.94.155.176", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.94.155.176", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -110,38 +102,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.42.81.68", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.42.81.68", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "New York" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.42.81.68", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.42.81.68", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -158,32 +146,28 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "37.17.250.101", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "37.17.250.101", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:41.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:02.000Z", - "threatintel.threatq.indicator_value": "37.17.250.101", - "threatintel.threatq.published_at": "2020-09-11T14:35:41.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:41.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:02.000Z", + "threatq.indicator_value": "37.17.250.101", + "threatq.published_at": "2020-09-11T14:35:41.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -200,38 +184,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.94.129.203", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.94.129.203", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Sacramento" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.94.129.203", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.94.129.203", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -248,38 +228,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.216.117.22", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.216.117.22", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "3" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Houston" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.216.117.22", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.216.117.22", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -296,38 +272,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.80.70.115", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.80.70.115", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Fort Lauderdale" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.80.70.115", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.80.70.115", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -344,38 +316,34 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.65.79.99", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.65.79.99", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Pompano Beach" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.65.79.99", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.65.79.99", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" }, { "@timestamp": "2020-11-15T00:00:02.000Z", @@ -392,37 +360,33 @@ "forwarded", "threatintel-threatq" ], - "threatintel.indicator.confidence": 4, - "threatintel.indicator.ip": "69.199.22.46", - "threatintel.indicator.marking.tlp": [ - "" - ], - "threatintel.indicator.provider": [ - "AlienVault OTX" - ], - "threatintel.indicator.type": "ipv4-addr", - "threatintel.threatq.attributes.alienvault_reliability": [ + "threat.feed.dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f", + "threat.feed.name": "[Filebeat] ThreatQuotient", + "threat.indicator.confidence": "Low", + "threat.indicator.ip": "69.199.22.46", + "threat.indicator.type": "ipv4-addr", + "threatq.attributes.alienvault_reliability": [ "4" ], - "threatintel.threatq.attributes.alienvault_revision": [ + "threatq.attributes.alienvault_revision": [ "3" ], - "threatintel.threatq.attributes.alienvault_threat_level": [ + "threatq.attributes.alienvault_threat_level": [ "2" ], - "threatintel.threatq.attributes.city": [ + "threatq.attributes.city": [ "Little Elm" ], - "threatintel.threatq.attributes.country": [ + "threatq.attributes.country": [ "US" ], - "threatintel.threatq.attributes.description": [ + "threatq.attributes.description": [ "Malicious Host" ], - "threatintel.threatq.created_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", - "threatintel.threatq.indicator_value": "69.199.22.46", - "threatintel.threatq.published_at": "2020-09-11T14:35:51.000Z", - "threatintel.threatq.status": "Expired" + "threatq.created_at": "2020-09-11T14:35:51.000Z", + "threatq.expires_calculated_at": "2020-10-15T14:40:03.000Z", + "threatq.indicator_value": "69.199.22.46", + "threatq.published_at": "2020-09-11T14:35:51.000Z", + "threatq.status": "Expired" } ] \ No newline at end of file From 3d88a4484766b9497ab73031e891fd30e240d4ca Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Fri, 19 Nov 2021 10:49:26 +0000 Subject: [PATCH 003/172] [mergify] report open backported PRs once a week (#28964) --- .mergify.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 8ab1e9b9363c..15ef4cd538ab 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -101,6 +101,18 @@ pull_request_rules: - files~=^\.mergify\.yml$ actions: delete_head_branch: + - name: notify the backport has not been merged yet + conditions: + - -merged + - -closed + - author=mergify[bot] + - "#check-success>0" + - schedule=Mon-Mon 06:00-10:00[Europe/Paris] + - "#assignee>=1" + actions: + comment: + message: | + This pull request has not been merged yet. Could you please review and merge it @{{ assignee | join(', @') }}? 🙏 - name: notify the backport policy conditions: - -label~=^backport From 1228d8b4714a56e6791ac6ca07b2d8291a513c85 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Fri, 19 Nov 2021 14:41:42 +0000 Subject: [PATCH 004/172] ci: daily/weekly jobs (#29050) --- .ci/schedule-daily.groovy | 7 +++++-- .ci/schedule-weekly.groovy | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.ci/schedule-daily.groovy b/.ci/schedule-daily.groovy index adad76cbd765..2211dec4c499 100644 --- a/.ci/schedule-daily.groovy +++ b/.ci/schedule-daily.groovy @@ -21,8 +21,11 @@ pipeline { stage('Nighly beats builds') { steps { runBuild(quietPeriod: 0, job: 'Beats/beats/master') - runBuild(quietPeriod: 2000, job: 'Beats/beats/7.16') - runBuild(quietPeriod: 4000, job: 'Beats/beats/7.15') + // This should be `current_8` bump.getCurrentMinorReleaseFor8 + runBuild(quietPeriod: 2000, job: 'Beats/beats/8.0') + // This should be `current_7` bump.getCurrentMinorReleaseFor7 or + // `next_minor_7` bump.getNextMinorReleaseFor7 + runBuild(quietPeriod: 4000, job: 'Beats/beats/7.16') } } } diff --git a/.ci/schedule-weekly.groovy b/.ci/schedule-weekly.groovy index 74293ab7b9f6..c2d96964575d 100644 --- a/.ci/schedule-weekly.groovy +++ b/.ci/schedule-weekly.groovy @@ -21,8 +21,11 @@ pipeline { stage('Weekly beats builds') { steps { runBuild(quietPeriod: 0, job: 'Beats/beats/master') - runBuild(quietPeriod: 1000, job: 'Beats/beats/7.16') - runBuild(quietPeriod: 2000, job: 'Beats/beats/7.15') + // This should be `current_8` bump.getCurrentMinorReleaseFor8 + runBuild(quietPeriod: 1000, job: 'Beats/beats/8.0') + // This should be `current_7` bump.getCurrentMinorReleaseFor7 or + // `next_minor_7` bump.getNextMinorReleaseFor7 + runBuild(quietPeriod: 2000, job: 'Beats/beats/7.16') } } } From 07d4e994e2d618a64b82dc0cfc43e8699b4977d5 Mon Sep 17 00:00:00 2001 From: Mario Castro Date: Fri, 19 Nov 2021 16:53:01 +0100 Subject: [PATCH 005/172] [Metricbeat] Fix wrong mapping on "info" subkey (#28782) --- metricbeat/docs/fields.asciidoc | 20 +++++++++---------- metricbeat/module/beat/_meta/fields.yml | 10 +++++----- metricbeat/module/beat/fields.go | 2 +- metricbeat/module/beat/stats/_meta/fields.yml | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 9e2489352e1e..886ec623bbca 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -6736,7 +6736,7 @@ alias to: beat.stats.apm_server.acm.response.errors.unauthorized -- type: alias -alias to: beat.stats.beat.host +alias to: beat.stats.info.host -- @@ -6745,7 +6745,7 @@ alias to: beat.stats.beat.host -- type: alias -alias to: beat.stats.beat.name +alias to: beat.stats.info.name -- @@ -6754,7 +6754,7 @@ alias to: beat.stats.beat.name -- type: alias -alias to: beat.stats.beat.type +alias to: beat.stats.info.type -- @@ -6763,7 +6763,7 @@ alias to: beat.stats.beat.type -- type: alias -alias to: beat.stats.beat.uuid +alias to: beat.stats.info.uuid -- @@ -6772,7 +6772,7 @@ alias to: beat.stats.beat.uuid -- type: alias -alias to: beat.stats.beat.version +alias to: beat.stats.info.version -- @@ -8273,35 +8273,35 @@ type: long -- -*`beat.stats.beat.name`*:: +*`beat.stats.info.name`*:: + -- type: keyword -- -*`beat.stats.beat.host`*:: +*`beat.stats.info.host`*:: + -- type: keyword -- -*`beat.stats.beat.type`*:: +*`beat.stats.info.type`*:: + -- type: keyword -- -*`beat.stats.beat.uuid`*:: +*`beat.stats.info.uuid`*:: + -- type: keyword -- -*`beat.stats.beat.version`*:: +*`beat.stats.info.version`*:: + -- type: keyword diff --git a/metricbeat/module/beat/_meta/fields.yml b/metricbeat/module/beat/_meta/fields.yml index 5f40348c572c..b29bffb2cfa2 100644 --- a/metricbeat/module/beat/_meta/fields.yml +++ b/metricbeat/module/beat/_meta/fields.yml @@ -305,19 +305,19 @@ fields: - name: host type: alias - path: beat.stats.beat.host + path: beat.stats.info.host - name: name type: alias - path: beat.stats.beat.name + path: beat.stats.info.name - name: type type: alias - path: beat.stats.beat.type + path: beat.stats.info.type - name: uuid type: alias - path: beat.stats.beat.uuid + path: beat.stats.info.uuid - name: version type: alias - path: beat.stats.beat.version + path: beat.stats.info.version - name: metrics type: group fields: diff --git a/metricbeat/module/beat/fields.go b/metricbeat/module/beat/fields.go index cd59838480a3..b8ee153217ae 100644 --- a/metricbeat/module/beat/fields.go +++ b/metricbeat/module/beat/fields.go @@ -32,5 +32,5 @@ func init() { // AssetBeat returns asset data. // This is the base64 encoded zlib format compressed contents of module/beat. func AssetBeat() string { - return "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" + return "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" } diff --git a/metricbeat/module/beat/stats/_meta/fields.yml b/metricbeat/module/beat/stats/_meta/fields.yml index 0e5700b5fd5c..19c0f75d7156 100644 --- a/metricbeat/module/beat/stats/_meta/fields.yml +++ b/metricbeat/module/beat/stats/_meta/fields.yml @@ -219,7 +219,7 @@ type: long - name: unauthorized type: long - - name: beat + - name: info type: group fields: - name: name From 7323a63d4d68d710af3848b8da2b789f1c14c04e Mon Sep 17 00:00:00 2001 From: Lee E Hinman <57081003+leehinman@users.noreply.github.com> Date: Fri, 19 Nov 2021 14:52:41 -0800 Subject: [PATCH 006/172] Fix AccessList & AccessMask processing in security data_stream (#29016) - According to MS documentation examples AccessList contains a space separated list of access masks and AccessMask contains an integer. - Retain old behavior if AccessMask contains a space separated list of access masks - Add new code to parse AccessList as space separated list of access masks - Add new code to parse AccessMask if an integer --- CHANGELOG.next.asciidoc | 1 + .../security/config/winlogbeat-security.js | 86 ++++++++++++++++--- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 6bb189ee3016..db654552a586 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -241,6 +241,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Tolerate faults when Windows Event Log session is interrupted {issue}27947[27947] {pull}28191[28191] - Add ECS 1.9 new users fields {pull}26509[26509] - Don't split hyphenated tokens {pull}28483[28483] +- Correctly handle AccessMask if it is an integer or list of masks. {pull}29016[29016] *Functionbeat* diff --git a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js b/x-pack/winlogbeat/module/security/config/winlogbeat-security.js index 76ef1f0b21e2..39739db14796 100644 --- a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js +++ b/x-pack/winlogbeat/module/security/config/winlogbeat-security.js @@ -1595,6 +1595,32 @@ var security = (function () { [0x00010000, 'Delete'] ]; + // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks + var accessMaskDescriptions = [ + [0x00000001, 'Create Child'], + [0x00000002, 'Delete Child'], + [0x00000004, 'List Contents'], + [0x00000008, 'SELF'], + [0x00000010, 'Read Property'], + [0x00000020, 'Write Property'], + [0x00000040, 'Delete Treee'], + [0x00000080, 'List Object'], + [0x00000100, 'Control Access'], + [0x00010000, 'DELETE'], + [0x00020000, 'READ_CONTROL'], + [0x00040000, 'WRITE_DAC'], + [0x00080000, 'WRITE_OWNER'], + [0x00100000, 'SYNCHRONIZE'], + [0x00F00000, 'STANDARD_RIGHTS_REQUIRED'], + [0x001F0000, 'STANDARD_RIGHTS_ALL'], + [0x0000FFFF, 'SPECIFIC_RIGHTS_ALL'], + [0x01000000, 'ADS_RIGHT_ACCESS_SYSTEM_SECURITY'], + [0x10000000, 'ADS_RIGHT_GENERIC_ALL'], + [0x20000000, 'ADS_RIGHT_GENERIC_EXECUTE'], + [0x40000000, 'ADS_RIGHT_GENERIC_WRITE'], + [0x80000000, 'ADS_RIGHT_GENERIC_READ'] + ]; + // lookupMessageCode returns the string associated with the code. key should // be the name of the field in evt containing the code (e.g. %%2313). var lookupMessageCode = function (evt, key) { @@ -1844,6 +1870,22 @@ var security = (function () { } }; + var translateAccessMask = function(mask) { + if (!mask) { + return; + } + var accessCode = parseInt(mask); + var accessResult = []; + for (var i = 0; i < accessMaskDescriptions.length; i++) { + if ((accessCode | accessMaskDescriptions[i][0]) === accessCode) { + accessResult.push(accessMaskDescriptions[i][1]); + } + } + if (accessResult) { + return accessResult; + } + }; + var addSessionData = new processor.Chain() .Convert({ fields: [ @@ -2389,22 +2431,44 @@ var security = (function () { evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); }) .Add(function(evt){ - var maskCodes = evt.Get("winlog.event_data.AccessMask"); - if (!maskCodes) { + var accessMask = evt.Get("winlog.event_data.AccessMask"); + if (!accessMask) { return; } - var maskList = maskCodes.replace(/\s+/g, '').split("%%").filter(String); - evt.Put("winlog.event_data.AccessMask", maskList); - var maskResults = []; - for (var j = 0; j < maskList.length; j++) { - var description = msobjsMessageTable[maskList[j]]; - if (description === undefined) { - return; + var accessDescriptions = translateAccessMask(accessMask); + if (!accessDescriptions) { + return; + } + if (accessDescriptions.length > 0) { + evt.Put("winlog.event_data.AccessMaskDescription", accessDescriptions); + } + }) + .Add(function(evt){ + var listNames = ["AccessList", "AccessMask"] + for (var i = 0; i < listNames.length; i++) { + var listContents = evt.Get("winlog.event_data." + listNames[i]) + if (!listContents) { + continue; } - maskResults.push(description); + var listDescription = evt.Get("winlog.event_data." + listNames[i] + "Description") + if (listDescription) { + continue; + } + + var items = listContents.replace(/\s+/g, '').split("%%").filter(String); + evt.Put("winlog.event_data." + listNames[i], items) + var results = []; + for (var j = 0; j < items.length; j++) { + var description = msobjsMessageTable[items[j]]; + if (description === undefined) { + continue; + } + results.push(description); + } + evt.Put("winlog.event_data." + listNames[i] + "Description", results); } - evt.Put("winlog.event_data.AccessMaskDescription", maskResults); }) + .Build(); var trustDomainMgmtEvts = new processor.Chain() From 1e762ccea1b97870f0ed78cabb361fdb886f925e Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Mon, 22 Nov 2021 07:00:29 +1030 Subject: [PATCH 007/172] x-pack/filebeat/module: add note for default var.input (#28324) [git-generate] find x-pack/filebeat/module -type f -name '*.asciidoc' -exec gsed -i -r 's/(The input from which messages are read\. One of `file`, `tcp` or `udp`\.)/\1 Defaults to `udp`./g' {} \; make update --- filebeat/docs/modules/barracuda.asciidoc | 4 ++-- filebeat/docs/modules/bluecoat.asciidoc | 2 +- filebeat/docs/modules/cisco.asciidoc | 4 ++-- filebeat/docs/modules/cylance.asciidoc | 2 +- filebeat/docs/modules/f5.asciidoc | 4 ++-- filebeat/docs/modules/fortinet.asciidoc | 6 +++--- filebeat/docs/modules/imperva.asciidoc | 2 +- filebeat/docs/modules/infoblox.asciidoc | 2 +- filebeat/docs/modules/juniper.asciidoc | 4 ++-- filebeat/docs/modules/microsoft.asciidoc | 2 +- filebeat/docs/modules/netscout.asciidoc | 2 +- filebeat/docs/modules/proofpoint.asciidoc | 2 +- filebeat/docs/modules/radware.asciidoc | 2 +- filebeat/docs/modules/snort.asciidoc | 2 +- filebeat/docs/modules/sonicwall.asciidoc | 2 +- filebeat/docs/modules/sophos.asciidoc | 2 +- filebeat/docs/modules/squid.asciidoc | 2 +- filebeat/docs/modules/tomcat.asciidoc | 2 +- filebeat/docs/modules/zscaler.asciidoc | 2 +- x-pack/filebeat/module/barracuda/_meta/docs.asciidoc | 4 ++-- x-pack/filebeat/module/bluecoat/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/cisco/_meta/docs.asciidoc | 4 ++-- x-pack/filebeat/module/cylance/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/f5/_meta/docs.asciidoc | 4 ++-- x-pack/filebeat/module/fortinet/_meta/docs.asciidoc | 6 +++--- x-pack/filebeat/module/imperva/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/infoblox/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/juniper/_meta/docs.asciidoc | 4 ++-- x-pack/filebeat/module/microsoft/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/netscout/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/proofpoint/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/radware/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/snort/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/sonicwall/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/sophos/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/squid/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/tomcat/_meta/docs.asciidoc | 2 +- x-pack/filebeat/module/zscaler/_meta/docs.asciidoc | 2 +- 38 files changed, 50 insertions(+), 50 deletions(-) diff --git a/filebeat/docs/modules/barracuda.asciidoc b/filebeat/docs/modules/barracuda.asciidoc index fc5529cf0591..e1732beb0611 100644 --- a/filebeat/docs/modules/barracuda.asciidoc +++ b/filebeat/docs/modules/barracuda.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "barracudawaf" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -78,7 +78,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "barracudasf" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/bluecoat.asciidoc b/filebeat/docs/modules/bluecoat.asciidoc index b6e1e23e50ae..4f7c7e243b5f 100644 --- a/filebeat/docs/modules/bluecoat.asciidoc +++ b/filebeat/docs/modules/bluecoat.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bluecoatdirector" d *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/cisco.asciidoc b/filebeat/docs/modules/cisco.asciidoc index e2a0a89acbad..ae06741b09ed 100644 --- a/filebeat/docs/modules/cisco.asciidoc +++ b/filebeat/docs/modules/cisco.asciidoc @@ -305,7 +305,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "cisconxos" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -350,7 +350,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "ciscomeraki" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/cylance.asciidoc b/filebeat/docs/modules/cylance.asciidoc index 641c369f4e59..3e70754430f3 100644 --- a/filebeat/docs/modules/cylance.asciidoc +++ b/filebeat/docs/modules/cylance.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "cylance" device rev *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/f5.asciidoc b/filebeat/docs/modules/f5.asciidoc index 5b886f8cae6e..611239e2c21c 100644 --- a/filebeat/docs/modules/f5.asciidoc +++ b/filebeat/docs/modules/f5.asciidoc @@ -37,7 +37,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bigipapm" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -82,7 +82,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bigipafm" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/fortinet.asciidoc b/filebeat/docs/modules/fortinet.asciidoc index 8a5da7b80f7d..9dc8c1e3f268 100644 --- a/filebeat/docs/modules/fortinet.asciidoc +++ b/filebeat/docs/modules/fortinet.asciidoc @@ -85,7 +85,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "forticlientendpoint *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -130,7 +130,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "fortinetfortimail" *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -175,7 +175,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "fortinetmgr" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/imperva.asciidoc b/filebeat/docs/modules/imperva.asciidoc index bdbf16b0bec4..480ed29d30d6 100644 --- a/filebeat/docs/modules/imperva.asciidoc +++ b/filebeat/docs/modules/imperva.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "impervawaf" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/infoblox.asciidoc b/filebeat/docs/modules/infoblox.asciidoc index 745a52e0c96c..a830d7652475 100644 --- a/filebeat/docs/modules/infoblox.asciidoc +++ b/filebeat/docs/modules/infoblox.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "infobloxnios" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/juniper.asciidoc b/filebeat/docs/modules/juniper.asciidoc index a97baa17de53..113fe33c513a 100644 --- a/filebeat/docs/modules/juniper.asciidoc +++ b/filebeat/docs/modules/juniper.asciidoc @@ -146,7 +146,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "junosrouter" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -191,7 +191,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "netscreen" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/microsoft.asciidoc b/filebeat/docs/modules/microsoft.asciidoc index ff00507119f5..7a1170c67d9a 100644 --- a/filebeat/docs/modules/microsoft.asciidoc +++ b/filebeat/docs/modules/microsoft.asciidoc @@ -224,7 +224,7 @@ include::../include/var-paths.asciidoc[] *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/netscout.asciidoc b/filebeat/docs/modules/netscout.asciidoc index a1d4d3dcdd5c..13e78e5b1168 100644 --- a/filebeat/docs/modules/netscout.asciidoc +++ b/filebeat/docs/modules/netscout.asciidoc @@ -31,7 +31,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "arborpeakflowsp" de *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/proofpoint.asciidoc b/filebeat/docs/modules/proofpoint.asciidoc index 905288fab3d3..b5ebebc6ccd6 100644 --- a/filebeat/docs/modules/proofpoint.asciidoc +++ b/filebeat/docs/modules/proofpoint.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "proofpoint" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/radware.asciidoc b/filebeat/docs/modules/radware.asciidoc index 3d1dbc4dcbc1..d76a5b96fe02 100644 --- a/filebeat/docs/modules/radware.asciidoc +++ b/filebeat/docs/modules/radware.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "radwaredp" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/snort.asciidoc b/filebeat/docs/modules/snort.asciidoc index ff9d5809ae8e..aa6a08f8f26f 100644 --- a/filebeat/docs/modules/snort.asciidoc +++ b/filebeat/docs/modules/snort.asciidoc @@ -31,7 +31,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "snort" device revis *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/sonicwall.asciidoc b/filebeat/docs/modules/sonicwall.asciidoc index a50c6477307b..17e953dcfc1c 100644 --- a/filebeat/docs/modules/sonicwall.asciidoc +++ b/filebeat/docs/modules/sonicwall.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "sonicwall" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/sophos.asciidoc b/filebeat/docs/modules/sophos.asciidoc index 88572fee06a3..4e8a2367424e 100644 --- a/filebeat/docs/modules/sophos.asciidoc +++ b/filebeat/docs/modules/sophos.asciidoc @@ -156,7 +156,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "astarosg" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/squid.asciidoc b/filebeat/docs/modules/squid.asciidoc index b72a44125373..4bf202b262a0 100644 --- a/filebeat/docs/modules/squid.asciidoc +++ b/filebeat/docs/modules/squid.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "squid" device revis *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/filebeat/docs/modules/tomcat.asciidoc b/filebeat/docs/modules/tomcat.asciidoc index 7f80711b1c43..f3057c08be88 100644 --- a/filebeat/docs/modules/tomcat.asciidoc +++ b/filebeat/docs/modules/tomcat.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "apachetomcat" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.paths`*:: diff --git a/filebeat/docs/modules/zscaler.asciidoc b/filebeat/docs/modules/zscaler.asciidoc index 3586f16d6d1e..0a09654200d6 100644 --- a/filebeat/docs/modules/zscaler.asciidoc +++ b/filebeat/docs/modules/zscaler.asciidoc @@ -33,7 +33,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "zscalernss" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/barracuda/_meta/docs.asciidoc b/x-pack/filebeat/module/barracuda/_meta/docs.asciidoc index c8eb358cd7d8..79d27b361660 100644 --- a/x-pack/filebeat/module/barracuda/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/barracuda/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "barracudawaf" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -73,7 +73,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "barracudasf" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/bluecoat/_meta/docs.asciidoc b/x-pack/filebeat/module/bluecoat/_meta/docs.asciidoc index b9ef6534d892..3497b6873ea2 100644 --- a/x-pack/filebeat/module/bluecoat/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/bluecoat/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bluecoatdirector" d *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/cisco/_meta/docs.asciidoc b/x-pack/filebeat/module/cisco/_meta/docs.asciidoc index e831bbb1e8ff..e666da7fa665 100644 --- a/x-pack/filebeat/module/cisco/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/cisco/_meta/docs.asciidoc @@ -300,7 +300,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "cisconxos" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -345,7 +345,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "ciscomeraki" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/cylance/_meta/docs.asciidoc b/x-pack/filebeat/module/cylance/_meta/docs.asciidoc index 135260569a46..4cd22f8b7973 100644 --- a/x-pack/filebeat/module/cylance/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/cylance/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "cylance" device rev *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/f5/_meta/docs.asciidoc b/x-pack/filebeat/module/f5/_meta/docs.asciidoc index d0448abd5452..e83d14081ff7 100644 --- a/x-pack/filebeat/module/f5/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/f5/_meta/docs.asciidoc @@ -32,7 +32,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bigipapm" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -77,7 +77,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "bigipafm" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/fortinet/_meta/docs.asciidoc b/x-pack/filebeat/module/fortinet/_meta/docs.asciidoc index 46c620991970..2cd30c1437ae 100644 --- a/x-pack/filebeat/module/fortinet/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/fortinet/_meta/docs.asciidoc @@ -80,7 +80,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "forticlientendpoint *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -125,7 +125,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "fortinetfortimail" *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -170,7 +170,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "fortinetmgr" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/imperva/_meta/docs.asciidoc b/x-pack/filebeat/module/imperva/_meta/docs.asciidoc index 918763f391dd..c5b1ab376910 100644 --- a/x-pack/filebeat/module/imperva/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/imperva/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "impervawaf" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/infoblox/_meta/docs.asciidoc b/x-pack/filebeat/module/infoblox/_meta/docs.asciidoc index 286934fa4e4b..1be04b5b739f 100644 --- a/x-pack/filebeat/module/infoblox/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/infoblox/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "infobloxnios" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/juniper/_meta/docs.asciidoc b/x-pack/filebeat/module/juniper/_meta/docs.asciidoc index a0e4ab1717fe..b42de3eb091b 100644 --- a/x-pack/filebeat/module/juniper/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/juniper/_meta/docs.asciidoc @@ -141,7 +141,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "junosrouter" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: @@ -186,7 +186,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "netscreen" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/microsoft/_meta/docs.asciidoc b/x-pack/filebeat/module/microsoft/_meta/docs.asciidoc index 577c87f6cc39..13ea8f43bdc4 100644 --- a/x-pack/filebeat/module/microsoft/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/microsoft/_meta/docs.asciidoc @@ -219,7 +219,7 @@ include::../include/var-paths.asciidoc[] *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/netscout/_meta/docs.asciidoc b/x-pack/filebeat/module/netscout/_meta/docs.asciidoc index 3d0477a9f435..463c93b5c0f2 100644 --- a/x-pack/filebeat/module/netscout/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/netscout/_meta/docs.asciidoc @@ -26,7 +26,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "arborpeakflowsp" de *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/proofpoint/_meta/docs.asciidoc b/x-pack/filebeat/module/proofpoint/_meta/docs.asciidoc index b0accc04273c..21a768ab432d 100644 --- a/x-pack/filebeat/module/proofpoint/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/proofpoint/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "proofpoint" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/radware/_meta/docs.asciidoc b/x-pack/filebeat/module/radware/_meta/docs.asciidoc index 3e0a992b51fb..ba9bc87444c5 100644 --- a/x-pack/filebeat/module/radware/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/radware/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "radwaredp" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/snort/_meta/docs.asciidoc b/x-pack/filebeat/module/snort/_meta/docs.asciidoc index f2ae38f00433..47c1c430934f 100644 --- a/x-pack/filebeat/module/snort/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/snort/_meta/docs.asciidoc @@ -26,7 +26,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "snort" device revis *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/sonicwall/_meta/docs.asciidoc b/x-pack/filebeat/module/sonicwall/_meta/docs.asciidoc index 904e7f6d19c1..595b2a31acb2 100644 --- a/x-pack/filebeat/module/sonicwall/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/sonicwall/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "sonicwall" device r *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/sophos/_meta/docs.asciidoc b/x-pack/filebeat/module/sophos/_meta/docs.asciidoc index 41e86a0d1a43..6d6147984a1d 100644 --- a/x-pack/filebeat/module/sophos/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/sophos/_meta/docs.asciidoc @@ -151,7 +151,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "astarosg" device re *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/squid/_meta/docs.asciidoc b/x-pack/filebeat/module/squid/_meta/docs.asciidoc index 0708c243f276..10411c4f73d2 100644 --- a/x-pack/filebeat/module/squid/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/squid/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "squid" device revis *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: diff --git a/x-pack/filebeat/module/tomcat/_meta/docs.asciidoc b/x-pack/filebeat/module/tomcat/_meta/docs.asciidoc index 9b7e44012043..d56df0ba01be 100644 --- a/x-pack/filebeat/module/tomcat/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/tomcat/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "apachetomcat" devic *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.paths`*:: diff --git a/x-pack/filebeat/module/zscaler/_meta/docs.asciidoc b/x-pack/filebeat/module/zscaler/_meta/docs.asciidoc index 5728796de545..779c5deabc01 100644 --- a/x-pack/filebeat/module/zscaler/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/zscaler/_meta/docs.asciidoc @@ -28,7 +28,7 @@ NOTE: This was converted from RSA NetWitness log parser XML "zscalernss" device *`var.input`*:: -The input from which messages are read. One of `file`, `tcp` or `udp`. +The input from which messages are read. One of `file`, `tcp` or `udp`. Defaults to `udp`. *`var.syslog_host`*:: From f2ae2819927c44487305f370edb1e143b047a5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Mon, 22 Nov 2021 10:39:03 +0100 Subject: [PATCH 008/172] Remove `logging.files.suffix` option and always use datetime suffixes (#28927) ## What does this PR do? This PR contains several improvements to the output file log rotation: * Removes suffix option as discussed offline * Filenames end in extension name so users get a hint about the contents * Removes `time.Sleep` from testing code * Datetime format no longer contains hour and minutes. In case of conflict on rotation, an index is appended to the filename. ## Why is it important? Previously, log file suffixes were configurable. Users had the option to either add the count or the datetime to the end of the log file. From now on, we only allow datetime based naming. Hence the configuration option `logging.files.suffix` is removed. Example: Filebeat is writing logs to `filebeat-20211111.ndjson` actively. Then a few minutes later it gets rotated, and the new active file becomes `filebeat-20211111-1.ndjson`. This change should help with Beats not being able to rotate files on Windows. --- CHANGELOG.next.asciidoc | 1 + auditbeat/auditbeat.reference.yml | 5 - filebeat/filebeat.reference.yml | 5 - filebeat/tests/system/filebeat.py | 2 +- filebeat/tests/system/test_harvester.py | 4 +- filebeat/tests/system/test_input.py | 6 +- filebeat/tests/system/test_load.py | 2 +- filebeat/tests/system/test_multiline.py | 8 +- filebeat/tests/system/test_registrar.py | 16 +- heartbeat/heartbeat.reference.yml | 5 - journalbeat/journalbeat.reference.yml | 5 - .../_meta/config/logging.reference.yml.tmpl | 5 - libbeat/common/file/interval_rotator.go | 192 ---------------- libbeat/common/file/interval_rotator_test.go | 154 ------------- libbeat/common/file/rotator.go | 215 ++++++++---------- libbeat/common/file/rotator_test.go | 162 +++++++------ libbeat/common/file/trigger.go | 8 +- libbeat/docs/loggingconfig.asciidoc | 9 - libbeat/logp/config.go | 20 +- libbeat/logp/core.go | 1 - libbeat/logp/core_test.go | 2 +- libbeat/outputs/fileout/config.go | 16 +- libbeat/outputs/fileout/file.go | 1 - libbeat/tests/system/base.py | 2 + libbeat/tests/system/beat/beat.py | 27 ++- libbeat/tests/system/test_base.py | 3 +- libbeat/tests/system/test_logging.py | 4 +- libbeat/tests/system/test_umask.py | 2 +- metricbeat/metricbeat.reference.yml | 5 - packetbeat/packetbeat.reference.yml | 5 - packetbeat/tests/system/packetbeat.py | 17 +- .../tests/system/test_0002_thrift_basics.py | 2 +- packetbeat/tests/system/test_0006_wsgi.py | 4 +- winlogbeat/tests/system/test_config.py | 2 +- winlogbeat/tests/system/test_wineventlog.py | 2 +- winlogbeat/winlogbeat.reference.yml | 5 - x-pack/auditbeat/auditbeat.reference.yml | 5 - .../pkg/agent/operation/monitoring.go | 6 +- .../elastic-agent/pkg/core/logger/logger.go | 4 +- .../core/monitoring/beats/beats_monitor.go | 2 +- .../pkg/core/monitoring/beats/monitoring.go | 4 +- x-pack/filebeat/filebeat.reference.yml | 5 - .../functionbeat/functionbeat.reference.yml | 5 - x-pack/heartbeat/heartbeat.reference.yml | 5 - x-pack/metricbeat/metricbeat.reference.yml | 5 - x-pack/osquerybeat/osquerybeat.reference.yml | 5 - x-pack/packetbeat/packetbeat.reference.yml | 5 - x-pack/winlogbeat/winlogbeat.reference.yml | 5 - 48 files changed, 254 insertions(+), 726 deletions(-) delete mode 100644 libbeat/common/file/interval_rotator.go delete mode 100644 libbeat/common/file/interval_rotator_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index db654552a586..66ba47603199 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -27,6 +27,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - add_process_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - add_docker_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] +- Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] *Auditbeat* diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 3d1435314b4e..1068dbd80829 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -1443,11 +1443,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. auditbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Auditbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index dc7250e402cc..69c6e855c109 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -2355,11 +2355,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. filebeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Filebeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/filebeat/tests/system/filebeat.py b/filebeat/tests/system/filebeat.py index 92df15911bb8..9f1f7905d162 100644 --- a/filebeat/tests/system/filebeat.py +++ b/filebeat/tests/system/filebeat.py @@ -36,7 +36,7 @@ def access_registry(self, name=None, data_path=None): return Registry(data_path, name) def log_access(self, file=None): - file = file if file else self.beat_name + ".log" + file = file if file else self.beat_name + "-" + self.today + ".ndjson" return LogState(os.path.join(self.working_dir, file)) def has_registry(self, name=None, data_path=None): diff --git a/filebeat/tests/system/test_harvester.py b/filebeat/tests/system/test_harvester.py index f56a51d0fe07..ecbb23fab77f 100644 --- a/filebeat/tests/system/test_harvester.py +++ b/filebeat/tests/system/test_harvester.py @@ -493,11 +493,11 @@ def test_boms(self, fb_encoding, py_encoding, bom): filebeat = self.start_beat(output=fb_encoding + ".log") self.wait_until( - lambda: self.output_has(lines=1, output_file="output/" + fb_encoding), + lambda: self.output_has(lines=1, output_file="output/" + fb_encoding + "-" + self.today + ".ndjson"), max_timeout=10) # Verify that output does not contain bom - output = self.read_output_json(output_file="output/" + fb_encoding) + output = self.read_output_json(output_file="output/" + fb_encoding + "-" + self.today + ".ndjson") assert output[0]["message"] == message filebeat.kill_and_wait() diff --git a/filebeat/tests/system/test_input.py b/filebeat/tests/system/test_input.py index f9dbd138a2e2..a4215587735c 100644 --- a/filebeat/tests/system/test_input.py +++ b/filebeat/tests/system/test_input.py @@ -633,10 +633,10 @@ def test_restart_recursive_glob(self): with open(testfile_path, 'a') as testfile: testfile.write("entry2\n") - filebeat = self.start_beat(output="filebeat2.log") + filebeat = self.start_beat() self.wait_until( - lambda: self.output_has_message("entry2"), + lambda: self.output_has_message("entry2", output_file="output/filebeat-"+self.today+"-1.ndjson"), max_timeout=10, name="output contains 'entry2'") @@ -783,7 +783,7 @@ def test_inode_marker_based_identity_tracking_to_path_based(self): proc = self.start_beat() # on startup output is rotated - self.wait_until(lambda: self.output_has(lines=1, output_file="output/filebeat.1")) + self.wait_until(lambda: self.output_has(lines=1, output_file="output/filebeat-" + self.today + "-1.ndjson")) self.wait_until(lambda: self.output_has(lines=1)) proc.check_kill_and_wait() diff --git a/filebeat/tests/system/test_load.py b/filebeat/tests/system/test_load.py index 6a35a6ce2509..b48b83e2659c 100644 --- a/filebeat/tests/system/test_load.py +++ b/filebeat/tests/system/test_load.py @@ -72,7 +72,7 @@ def test_no_missing_events(self): entry_list = [] - with open(self.working_dir + "/output/filebeat") as f: + with open(self.working_dir + "/output/filebeat-" + self.today + ".ndjson") as f: for line in f: content = json.loads(line) v = int(content["message"]) diff --git a/filebeat/tests/system/test_multiline.py b/filebeat/tests/system/test_multiline.py index ee5384ef5efe..31d4f0258ca1 100644 --- a/filebeat/tests/system/test_multiline.py +++ b/filebeat/tests/system/test_multiline.py @@ -148,11 +148,11 @@ def test_max_lines(self): # Checks line 3 is sent assert True == self.log_contains( - "MetaDataMappingService.java:388", "output/filebeat") + "MetaDataMappingService.java:388", "output/filebeat-" + self.today + ".ndjson") # Checks line 4 is not sent anymore assert False == self.log_contains( - "InternalClusterService.java:388", "output/filebeat") + "InternalClusterService.java:388", "output/filebeat-" + self.today + ".ndjson") # Check that output file has the same number of lines as the log file assert 20 == len(output) @@ -231,10 +231,10 @@ def test_max_bytes(self): output = self.read_output() # Check that first 60 chars are sent - assert True == self.log_contains("cluster.metadata", "output/filebeat") + assert True == self.log_contains("cluster.metadata", "output/filebeat-" + self.today + ".ndjson") # Checks that chars afterwards are not sent - assert False == self.log_contains("Zach", "output/filebeat") + assert False == self.log_contains("Zach", "output/filebeat-" + self.today + ".ndjson") # Check that output file has the same number of lines as the log file assert 20 == len(output) diff --git a/filebeat/tests/system/test_registrar.py b/filebeat/tests/system/test_registrar.py index 02d07a32446a..bb55ef547b3e 100644 --- a/filebeat/tests/system/test_registrar.py +++ b/filebeat/tests/system/test_registrar.py @@ -486,11 +486,11 @@ def test_restart_continue(self): # Output file was rotated self.wait_until( - lambda: self.output_has(lines=1, output_file="output/filebeat.1"), + lambda: self.output_has(lines=1, output_file="output/filebeat-" + self.today + ".ndjson"), max_timeout=10) self.wait_until( - lambda: self.output_has(lines=1), + lambda: self.output_has(lines=1, output_file="output/filebeat-" + self.today + "-1.ndjson"), max_timeout=10) filebeat.check_kill_and_wait() @@ -505,7 +505,7 @@ def test_restart_continue(self): # should never have been detected assert len(data) == 1 - output = self.read_output() + output = self.read_output(output_file="output/filebeat-" + self.today + "-1.ndjson") # Check that output file has the same number of lines as the log file assert len(output) == 1 @@ -592,15 +592,15 @@ def test_rotating_file_with_restart(self): with open(testfile_path, 'w') as testfile: testfile.write("entry3\n") - filebeat = self.start_beat(output="filebeat2.log") + filebeat = self.start_beat() # Output file was rotated self.wait_until( - lambda: self.output_has(lines=2, output_file="output/filebeat.1"), + lambda: self.output_has(lines=2), max_timeout=10) self.wait_until( - lambda: self.output_has(lines=1), + lambda: self.output_has(lines=1, output_file="output/filebeat-" + self.today + "-1.ndjson"), max_timeout=10) filebeat.check_kill_and_wait() @@ -951,8 +951,8 @@ def test_restart_state(self): clean_inactive="3s", ) - filebeat = self.start_beat(output="filebeat2.log") - logs = self.log_access("filebeat2.log") + filebeat = self.start_beat() + logs = self.log_access() # Write additional file for name in restart_files: diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 1eb37188303a..6bac78d08c20 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -1589,11 +1589,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. heartbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Heartbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/journalbeat/journalbeat.reference.yml b/journalbeat/journalbeat.reference.yml index 5058ed19ccec..2170f2fcec4e 100644 --- a/journalbeat/journalbeat.reference.yml +++ b/journalbeat/journalbeat.reference.yml @@ -1386,11 +1386,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. journalbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Journalbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/libbeat/_meta/config/logging.reference.yml.tmpl b/libbeat/_meta/config/logging.reference.yml.tmpl index 9a1e91a0af85..f4ca435be017 100644 --- a/libbeat/_meta/config/logging.reference.yml.tmpl +++ b/libbeat/_meta/config/logging.reference.yml.tmpl @@ -67,8 +67,3 @@ logging.files: # Rotate existing logs on startup rather than appending to the existing # file. Defaults to true. # rotateonstartup: true - - # Rotated files are either suffixed with a number e.g. {{.BeatName}}.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count diff --git a/libbeat/common/file/interval_rotator.go b/libbeat/common/file/interval_rotator.go deleted file mode 100644 index e5105beb0a77..000000000000 --- a/libbeat/common/file/interval_rotator.go +++ /dev/null @@ -1,192 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package file - -import ( - "fmt" - "os" - "path/filepath" - "sort" - "strconv" - "time" - - "github.com/pkg/errors" -) - -type intervalRotator struct { - log Logger - interval time.Duration - lastRotate time.Time - filename string - fileFormat string - clock clock - weekly bool - arbitrary bool -} - -func newIntervalRotator(log Logger, interval time.Duration, filename string) rotater { - ir := &intervalRotator{ - filename: filename, - log: log, - interval: (interval / time.Second) * time.Second, // drop fractional seconds - clock: realClock{}, - } - ir.initialize() - return ir -} - -func (r *intervalRotator) initialize() { - switch r.interval { - case time.Second: - r.fileFormat = "2006-01-02-15-04-05" - case time.Minute: - r.fileFormat = "2006-01-02-15-04" - case time.Hour: - r.fileFormat = "2006-01-02-15" - case 24 * time.Hour: // calendar day - r.fileFormat = "2006-01-02" - case 7 * 24 * time.Hour: // calendar week - r.fileFormat = "" - r.weekly = true - case 30 * 24 * time.Hour: // calendar month - r.fileFormat = "2006-01" - case 365 * 24 * time.Hour: // calendar year - r.fileFormat = "2006" - default: - r.arbitrary = true - r.fileFormat = "2006-01-02-15-04-05" - } - - fi, err := os.Stat(r.filename) - if err != nil { - if r.log != nil { - r.log.Debugw("Not attempting to find last rotated time, configured logs dir cannot be opened: %v", err) - } - return - } - r.lastRotate = fi.ModTime() -} - -func (r *intervalRotator) ActiveFile() string { - return r.filename -} - -func (r *intervalRotator) LogPrefix(filename string, modTime time.Time) string { - var t time.Time - if r.lastRotate.IsZero() { - t = modTime - } else { - t = r.lastRotate - } - - if r.weekly { - y, w := t.ISOWeek() - return fmt.Sprintf("%s-%04d-%02d-", filename, y, w) - } - if r.arbitrary { - intervalNumber := t.Unix() / (int64(r.interval) / int64(time.Second)) - intervalStart := time.Unix(0, intervalNumber*int64(r.interval)) - return fmt.Sprintf("%s-%s-", filename, intervalStart.Format(r.fileFormat)) - } - return fmt.Sprintf("%s-%s-", filename, t.Format(r.fileFormat)) -} - -func (r *intervalRotator) RotatedFiles() []string { - files, err := filepath.Glob(r.filename + "*") - if err != nil { - if r.log != nil { - r.log.Debugw("failed to list existing logs: %+v", err) - } - } - r.SortIntervalLogs(files) - return files -} - -func (r *intervalRotator) Rotate(reason rotateReason, t time.Time) error { - fi, err := os.Stat(r.ActiveFile()) - if os.IsNotExist(err) { - return nil - } else if err != nil { - return errors.Wrap(err, "failed to rotate backups") - } - - logPrefix := r.LogPrefix(r.ActiveFile(), fi.ModTime()) - files, err := filepath.Glob(logPrefix + "*") - if err != nil { - return errors.Wrap(err, "failed to list logs during rotation") - } - - var targetFilename string - if len(files) == 0 { - targetFilename = logPrefix + "1" - } else { - r.SortIntervalLogs(files) - lastLogIndex, _, err := IntervalLogIndex(files[len(files)-1]) - if err != nil { - return errors.Wrap(err, "failed to locate last log index during rotation") - } - targetFilename = logPrefix + strconv.Itoa(int(lastLogIndex)+1) - } - - if err := os.Rename(r.ActiveFile(), targetFilename); err != nil { - return errors.Wrap(err, "failed to rotate backups") - } - - if r.log != nil { - r.log.Debugw("Rotating file", "filename", r.ActiveFile(), "reason", reason) - } - - r.lastRotate = t - return nil -} - -func (r *intervalRotator) SortIntervalLogs(strings []string) { - sort.Slice( - strings, - func(i, j int) bool { - return OrderIntervalLogs(strings[i]) < OrderIntervalLogs(strings[j]) - }, - ) -} - -// OrderIntervalLogs, when given a log filename in the form [prefix]-[formattedDate]-n -// returns the filename after zero-padding the trailing n so that foo-[date]-2 sorts -// before foo-[date]-10. -func OrderIntervalLogs(filename string) string { - index, i, err := IntervalLogIndex(filename) - if err == nil { - return filename[:i] + fmt.Sprintf("%020d", index) - } - - return "" -} - -// IntervalLogIndex returns n as int given a log filename in the form [prefix]-[formattedDate]-n -func IntervalLogIndex(filename string) (uint64, int, error) { - i := len(filename) - 1 - for ; i >= 0; i-- { - if '0' > filename[i] || filename[i] > '9' { - break - } - } - i++ - - s64 := filename[i:] - u64, err := strconv.ParseUint(s64, 10, 64) - return u64, i, err -} diff --git a/libbeat/common/file/interval_rotator_test.go b/libbeat/common/file/interval_rotator_test.go deleted file mode 100644 index 729d8c713b7a..000000000000 --- a/libbeat/common/file/interval_rotator_test.go +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package file - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestSecondRotator(t *testing.T) { - a := newMockIntervalRotator(time.Second) - - clock := &testClock{time.Date(2018, 12, 31, 0, 0, 1, 100, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-00-00-01-", a.LogPrefix("foo", time.Now())) -} - -func TestMinuteRotator(t *testing.T) { - a := newMockIntervalRotator(time.Minute) - - clock := &testClock{time.Date(2018, 12, 31, 0, 1, 1, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-00-01-", a.LogPrefix("foo", time.Now())) -} - -func TestHourlyRotator(t *testing.T) { - a := newMockIntervalRotator(time.Hour) - - clock := &testClock{time.Date(2018, 12, 31, 1, 0, 1, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-01-", a.LogPrefix("foo", time.Now())) -} - -func TestDailyRotator(t *testing.T) { - a := newMockIntervalRotator(24 * time.Hour) - - clock := &testClock{time.Date(2018, 12, 31, 0, 0, 0, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-", a.LogPrefix("foo", time.Now())) -} - -func TestWeeklyRotator(t *testing.T) { - a := newMockIntervalRotator(7 * 24 * time.Hour) - - // Monday, 2018-Dec-31 - clock := &testClock{time.Date(2018, 12, 31, 0, 0, 0, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2019-01-", a.LogPrefix("foo", time.Now())) - - // Monday, 2019-Jan-7 - clock.time = clock.time.Add(7 * 24 * time.Hour) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2019-02-", a.LogPrefix("foo", time.Now())) -} - -func TestMonthlyRotator(t *testing.T) { - a := newMockIntervalRotator(30 * 24 * time.Hour) - - clock := &testClock{time.Date(2018, 12, 1, 0, 0, 0, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(30 * 24 * time.Hour) - assert.Equal(t, "foo-2018-12-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(24 * time.Hour) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2019-01-", a.LogPrefix("foo", time.Now())) -} - -func TestYearlyRotator(t *testing.T) { - a := newMockIntervalRotator(365 * 24 * time.Hour) - - clock := &testClock{time.Date(2018, 12, 31, 0, 0, 0, 0, time.Local)} - a.clock = clock - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(23 * time.Hour) - assert.Equal(t, "foo-2018-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Hour) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2019-", a.LogPrefix("foo", time.Now())) -} - -func TestArbitraryIntervalRotator(t *testing.T) { - a := newMockIntervalRotator(3 * time.Second) - - // Monday, 2018-Dec-31 - clock := &testClock{time.Date(2018, 12, 31, 0, 0, 1, 0, time.Local)} - a.clock = clock - assert.Equal(t, "foo-2018-12-30-00-00-00-", a.LogPrefix("foo", time.Date(2018, 12, 30, 0, 0, 0, 0, time.Local))) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-00-00-00-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Second) - assert.Equal(t, "foo-2018-12-31-00-00-00-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Second) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-00-00-03-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Second) - assert.Equal(t, "foo-2018-12-31-00-00-03-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Second) - assert.Equal(t, "foo-2018-12-31-00-00-03-", a.LogPrefix("foo", time.Now())) - - clock.time = clock.time.Add(time.Second) - a.lastRotate = a.clock.Now() - assert.Equal(t, "foo-2018-12-31-00-00-06-", a.LogPrefix("foo", time.Now())) -} - -func TestIntervalIsTruncatedToSeconds(t *testing.T) { - a := newMockIntervalRotator(2345 * time.Millisecond) - assert.Equal(t, 2*time.Second, a.interval) -} - -type testClock struct { - time time.Time -} - -func (t testClock) Now() time.Time { - return t.time -} - -func newMockIntervalRotator(interval time.Duration) *intervalRotator { - r := newIntervalRotator(nil, interval, "foo").(*intervalRotator) - return r -} diff --git a/libbeat/common/file/rotator.go b/libbeat/common/file/rotator.go index 633f94232ef5..e32e317dbfb4 100644 --- a/libbeat/common/file/rotator.go +++ b/libbeat/common/file/rotator.go @@ -29,22 +29,13 @@ import ( "github.com/pkg/errors" ) -type SuffixType uint32 - const ( // MaxBackupsLimit is the upper bound on the number of backup files. Any values // greater will result in an error. MaxBackupsLimit = 1024 - - SuffixCount SuffixType = iota + 1 - SuffixDate + DateFormat = "20060102" ) -var suffixes = map[string]SuffixType{ - "count": SuffixCount, - "date": SuffixDate, -} - // rotater is the interface responsible for rotating and finding files. type rotater interface { // ActiveFile returns the path to the file that is actively written. @@ -69,9 +60,9 @@ type Rotator struct { interval time.Duration permissions os.FileMode log Logger // Optional Logger (may be nil). - suffix SuffixType rotateOnStartup bool redirectStderr bool + clock clock file *os.File mutex sync.Mutex @@ -85,14 +76,6 @@ type Logger interface { // RotatorOption is a configuration option for Rotator. type RotatorOption func(r *Rotator) -// Interval sets the time interval for log rotation in addition to log -// rotation by size. The default is 0 for disabled. -func Suffix(s SuffixType) RotatorOption { - return func(r *Rotator) { - r.suffix = s - } -} - // MaxSizeBytes configures the maximum number of bytes that a file should // contain before being rotated. The default is 10 MiB. func MaxSizeBytes(n uint) RotatorOption { @@ -150,6 +133,12 @@ func RedirectStderr(redirect bool) RotatorOption { } } +func WithClock(clock clock) RotatorOption { + return func(r *Rotator) { + r.clock = clock + } +} + // NewFileRotator returns a new Rotator. func NewFileRotator(filename string, options ...RotatorOption) (*Rotator, error) { r := &Rotator{ @@ -158,7 +147,7 @@ func NewFileRotator(filename string, options ...RotatorOption) (*Rotator, error) permissions: 0600, interval: 0, rotateOnStartup: true, - suffix: SuffixCount, + clock: &realClock{}, } for _, opt := range options { @@ -179,14 +168,14 @@ func NewFileRotator(filename string, options ...RotatorOption) (*Rotator, error) return nil, errors.New("the minimum time interval for log rotation is 1 second") } - r.rot = newRotater(r.log, r.suffix, filename, r.maxBackups, r.interval) + r.rot = newDateRotater(r.log, filename, r.clock) shouldRotateOnStart := r.rotateOnStartup if _, err := os.Stat(r.rot.ActiveFile()); os.IsNotExist(err) { shouldRotateOnStart = false } - r.triggers = newTriggers(shouldRotateOnStart, r.interval, r.maxSizeBytes) + r.triggers = newTriggers(shouldRotateOnStart, r.interval, r.maxSizeBytes, r.clock) if r.log != nil { r.log.Debugw("Initialized file rotator", @@ -194,7 +183,6 @@ func NewFileRotator(filename string, options ...RotatorOption) (*Rotator, error) "max_size_bytes", r.maxSizeBytes, "max_backups", r.maxBackups, "permissions", r.permissions, - "suffix", r.suffix, ) } @@ -292,7 +280,7 @@ func (r *Rotator) openFile() error { } func (r *Rotator) rotate(reason rotateReason) error { - return r.rotateWithTime(reason, time.Now()) + return r.rotateWithTime(reason, r.clock.Now()) } // rotateWithTime closes the actively written file, and rotates it along with exising @@ -339,7 +327,7 @@ func (r *Rotator) isRotationTriggered(dataLen uint) (rotateReason, time.Time) { for _, t := range r.triggers { reason := t.TriggerRotation(dataLen) if reason != rotateReasonNoRotate { - return reason, time.Now() + return reason, r.clock.Now() } } return rotateReasonNoRotate, time.Time{} @@ -395,52 +383,37 @@ func (r *Rotator) closeFile() error { return errors.Wrap(err, "failed to close active file") } -type countRotator struct { - log Logger - filename string - intervalRotator *intervalRotator - maxBackups uint -} - type dateRotator struct { log Logger + clock clock format string filenamePrefix string currentFilename string - intervalRotator *intervalRotator -} + extension string -func newRotater(log Logger, s SuffixType, filename string, maxBackups uint, interval time.Duration) rotater { - switch s { - case SuffixCount: - if interval > 0 { - return newIntervalRotator(log, interval, filename) - } - return &countRotator{ - log: log, - filename: filename, - maxBackups: maxBackups, - } - case SuffixDate: - return newDateRotater(log, filename) - default: - return &countRotator{ - log: log, - filename: filename, - maxBackups: maxBackups, - } - } + prefixLen int + filenameLen int + extensionLen int + + // logOrderCache is used to cache log file meta information between rotations + logOrderCache map[string]logOrder } -func newDateRotater(log Logger, filename string) rotater { +func newDateRotater(log Logger, filename string, clock clock) rotater { d := &dateRotator{ log: log, + clock: clock, filenamePrefix: filename + "-", - format: "20060102150405", + extension: ".ndjson", + format: DateFormat, + logOrderCache: make(map[string]logOrder), } + d.prefixLen = len(d.filenamePrefix) + d.filenameLen = d.prefixLen + len(DateFormat) + d.extensionLen = len(d.extension) - d.currentFilename = d.filenamePrefix + time.Now().Format(d.format) - files, err := filepath.Glob(d.filenamePrefix + "*") + d.currentFilename = d.filenamePrefix + d.clock.Now().Format(d.format) + d.extension + files, err := filepath.Glob(d.filenamePrefix + "*" + d.extension) if err != nil { return d } @@ -467,7 +440,24 @@ func (d *dateRotator) Rotate(reason rotateReason, rotateTime time.Time) error { d.log.Debugw("Rotating file", "filename", d.currentFilename, "reason", reason) } - d.currentFilename = d.filenamePrefix + rotateTime.Format(d.format) + d.logOrderCache = make(map[string]logOrder, 0) + + newFileNamePrefix := d.filenamePrefix + rotateTime.Format(d.format) + files, err := filepath.Glob(newFileNamePrefix + "*" + d.extension) + if err != nil { + return fmt.Errorf("failed to get possible files: %+v", err) + } + + if len(files) == 0 { + d.currentFilename = newFileNamePrefix + d.extension + return nil + } + + d.SortModTimeLogs(files) + order := d.OrderLog(files[len(files)-1]) + + d.currentFilename = newFileNamePrefix + "-" + strconv.Itoa(order.index+1) + d.extension + return nil } @@ -479,10 +469,18 @@ func (d *dateRotator) RotatedFiles() []string { } } + for i, name := range files { + if name == d.ActiveFile() { + files = append(files[:i], files[i+1:]...) + break + } + } + d.SortModTimeLogs(files) return files } +// SortModTimeLogs puts newest file to the last func (d *dateRotator) SortModTimeLogs(strings []string) { sort.Slice( strings, @@ -492,88 +490,53 @@ func (d *dateRotator) SortModTimeLogs(strings []string) { ) } -func (d *dateRotator) OrderLog(filename string) time.Time { - ts, err := time.Parse(d.filenamePrefix+d.format, filepath.Base(filename)) - if err != nil { - return time.Time{} - } - return ts -} - -func (c *countRotator) ActiveFile() string { - return c.filename +// logOrder stores information required to sort log files +// parsed out from the following format {filename}-{datetime}-{index}.ndjson +type logOrder struct { + index int + datetime time.Time } -func (c *countRotator) RotatedFiles() []string { - files := make([]string, 0) - for i := c.maxBackups + 1; i >= 1; i-- { - name := c.backupName(i) - if _, err := os.Stat(name); os.IsNotExist(err) { - continue - } else if err != nil { - c.log.Debugw("failed to stat rotated file") - return files - } - files = append(files, name) +func (o logOrder) After(other logOrder) bool { + if o.datetime.Equal(other.datetime) { + return other.index > o.index } - - return files + return !o.datetime.After(other.datetime) } -func (c *countRotator) backupName(n uint) string { - if n == 0 { - return c.ActiveFile() +func (d *dateRotator) OrderLog(filename string) logOrder { + if o, ok := d.logOrderCache[filename]; ok { + return o } - return c.ActiveFile() + "." + strconv.Itoa(int(n)) -} -func (c *countRotator) Rotate(reason rotateReason, _ time.Time) error { - for i := c.maxBackups + 1; i > 0; i-- { - old := c.backupName(i - 1) - older := c.backupName(i) + var o logOrder + var err error - if _, err := os.Stat(old); os.IsNotExist(err) { - continue - } else if err != nil { - return errors.Wrap(err, "failed to rotate backups") - } + o.datetime, err = time.Parse(d.format, filename[d.prefixLen:d.filenameLen]) + if err != nil { + return o + } - if err := os.Remove(older); err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "failed to rotate backups") - } - if err := os.Rename(old, older); err != nil { - return errors.Wrap(err, "failed to rotate backups") - } else if i == 1 { - // Log when rotation of the main file occurs. - if c.log != nil { - c.log.Debugw("Rotating file", "filename", old, "reason", reason) - } + if d.isFilenameWithIndex(filename) { + o.index, err = d.filenameIndex(filename) + if err != nil { + return o } } - return nil -} -func (s *SuffixType) Unpack(v string) error { - i, err := strconv.Atoi(v) - if err == nil { - t := SuffixType(i) - v = t.String() - } + d.logOrderCache[filename] = o - val, ok := suffixes[v] - if !ok { - return fmt.Errorf("invalid suffix type: %+v", v) - } + return o +} - *s = val - return nil +func (d *dateRotator) isFilenameWithIndex(filename string) bool { + return d.filenameLen+d.extensionLen < len(filename) } -func (s *SuffixType) String() string { - for k, v := range suffixes { - if v == *s { - return k - } +func (d *dateRotator) filenameIndex(filename string) (int, error) { + indexStr := filename[d.filenameLen+1 : len(filename)-d.extensionLen] + if len(indexStr) > 0 { + return strconv.Atoi(indexStr) } - return "" + return 0, nil } diff --git a/libbeat/common/file/rotator_test.go b/libbeat/common/file/rotator_test.go index 585d1690e788..6294b042d130 100644 --- a/libbeat/common/file/rotator_test.go +++ b/libbeat/common/file/rotator_test.go @@ -21,8 +21,6 @@ import ( "fmt" "os" "path/filepath" - "regexp" - "sort" "sync" "testing" "time" @@ -39,43 +37,57 @@ func TestFileRotator(t *testing.T) { logp.TestingSetup() dir := t.TempDir() + logname := "sample" + c := &testClock{time.Date(2021, 11, 11, 0, 0, 0, 0, time.Local)} - filename := filepath.Join(dir, "sample.log") + filename := filepath.Join(dir, logname) r, err := file.NewFileRotator(filename, file.MaxBackups(2), file.WithLogger(logp.NewLogger("rotator").With(logp.Namespace("rotator"))), + file.WithClock(c), ) if err != nil { t.Fatal(err) } defer r.Close() + firstFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) + WriteMsg(t, r) - AssertDirContents(t, dir, "sample.log") + AssertDirContents(t, dir, firstFile) + + c.time = time.Date(2021, 11, 12, 0, 0, 0, 0, time.Local) Rotate(t, r) - AssertDirContents(t, dir, "sample.log.1") + AssertDirContents(t, dir, firstFile) WriteMsg(t, r) - AssertDirContents(t, dir, "sample.log", "sample.log.1") + + secondFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) + AssertDirContents(t, dir, firstFile, secondFile) + + c.time = time.Date(2021, 11, 13, 0, 0, 0, 0, time.Local) Rotate(t, r) - AssertDirContents(t, dir, "sample.log.1", "sample.log.2") + AssertDirContents(t, dir, firstFile, secondFile) WriteMsg(t, r) - AssertDirContents(t, dir, "sample.log", "sample.log.1", "sample.log.2") + thirdFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) + AssertDirContents(t, dir, firstFile, secondFile, thirdFile) + c.time = time.Date(2021, 11, 14, 0, 0, 0, 0, time.Local) Rotate(t, r) - AssertDirContents(t, dir, "sample.log.1", "sample.log.2") + AssertDirContents(t, dir, secondFile, thirdFile) + c.time = time.Date(2021, 11, 15, 0, 0, 0, 0, time.Local) Rotate(t, r) - AssertDirContents(t, dir, "sample.log.2", "sample.log.3") + AssertDirContents(t, dir, secondFile, thirdFile) } func TestFileRotatorConcurrently(t *testing.T) { dir := t.TempDir() - filename := filepath.Join(dir, "sample.log") + filename := filepath.Join(dir, "sample") r, err := file.NewFileRotator(filename, file.MaxBackups(2)) if err != nil { t.Fatal(err) @@ -97,29 +109,27 @@ func TestDailyRotation(t *testing.T) { dir := t.TempDir() logname := "daily" - dateFormat := "2006-01-02" - today := time.Now().Format(dateFormat) - yesterday := time.Now().AddDate(0, 0, -1).Format(dateFormat) - twoDaysAgo := time.Now().AddDate(0, 0, -2).Format(dateFormat) + yesterday := time.Now().AddDate(0, 0, -1).Format(file.DateFormat) + twoDaysAgo := time.Now().AddDate(0, 0, -2).Format(file.DateFormat) // seed directory with existing log files files := []string{ - logname + "-" + yesterday + "-1", - logname + "-" + yesterday + "-2", - logname + "-" + yesterday + "-3", - logname + "-" + yesterday + "-4", - logname + "-" + yesterday + "-5", - logname + "-" + yesterday + "-6", - logname + "-" + yesterday + "-7", - logname + "-" + yesterday + "-8", - logname + "-" + yesterday + "-9", - logname + "-" + yesterday + "-10", - logname + "-" + yesterday + "-11", - logname + "-" + yesterday + "-12", - logname + "-" + yesterday + "-13", - logname + "-" + twoDaysAgo + "-1", - logname + "-" + twoDaysAgo + "-2", - logname + "-" + twoDaysAgo + "-3", + logname + "-" + yesterday + "-1.ndjson", + logname + "-" + yesterday + "-2.ndjson", + logname + "-" + yesterday + "-3.ndjson", + logname + "-" + yesterday + "-4.ndjson", + logname + "-" + yesterday + "-5.ndjson", + logname + "-" + yesterday + "-6.ndjson", + logname + "-" + yesterday + "-7.ndjson", + logname + "-" + yesterday + "-8.ndjson", + logname + "-" + yesterday + "-9.ndjson", + logname + "-" + yesterday + "-10.ndjson", + logname + "-" + yesterday + "-11.ndjson", + logname + "-" + yesterday + "-12.ndjson", + logname + "-" + yesterday + "-13.ndjson", + logname + "-" + twoDaysAgo + "-1.ndjson", + logname + "-" + twoDaysAgo + "-2.ndjson", + logname + "-" + twoDaysAgo + "-3.ndjson", } for _, f := range files { @@ -139,25 +149,26 @@ func TestDailyRotation(t *testing.T) { Rotate(t, r) - AssertDirContents(t, dir, logname+"-"+yesterday+"-12", logname+"-"+yesterday+"-13") + AssertDirContents(t, dir, logname+"-"+yesterday+"-12.ndjson", logname+"-"+yesterday+"-13.ndjson") WriteMsg(t, r) - AssertDirContents(t, dir, logname+"-"+yesterday+"-12", logname+"-"+yesterday+"-13", logname) + today := time.Now().Format(file.DateFormat) + AssertDirContents(t, dir, logname+"-"+yesterday+"-12.ndjson", logname+"-"+yesterday+"-13.ndjson", logname+"-"+today+".ndjson") Rotate(t, r) - AssertDirContents(t, dir, logname+"-"+yesterday+"-13", logname+"-"+today+"-1") + AssertDirContents(t, dir, logname+"-"+yesterday+"-13.ndjson", logname+"-"+today+".ndjson") WriteMsg(t, r) - AssertDirContents(t, dir, logname+"-"+yesterday+"-13", logname+"-"+today+"-1", logname) + AssertDirContents(t, dir, logname+"-"+yesterday+"-13.ndjson", logname+"-"+today+".ndjson", logname+"-"+today+"-1.ndjson") for i := 0; i < (int(maxSizeBytes)/len(logMessage))+1; i++ { WriteMsg(t, r) } - AssertDirContents(t, dir, logname+"-"+today+"-1", logname+"-"+today+"-2", logname) + AssertDirContents(t, dir, logname+"-"+today+"-1.ndjson", logname+"-"+today+"-2.ndjson", logname+"-"+today+"-3.ndjson") } // Tests the FileConfig.RotateOnStartup parameter @@ -165,13 +176,15 @@ func TestRotateOnStartup(t *testing.T) { dir := t.TempDir() logname := "rotate_on_open" - filename := filepath.Join(dir, logname) + c := &testClock{time.Date(2021, 11, 11, 0, 0, 0, 0, time.Local)} + firstFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) + filename := filepath.Join(dir, firstFile) // Create an existing log file with this name. CreateFile(t, filename) - AssertDirContents(t, dir, logname) + AssertDirContents(t, dir, firstFile) - r, err := file.NewFileRotator(filename, file.RotateOnStartup(false)) + r, err := file.NewFileRotator(filepath.Join(dir, logname), file.RotateOnStartup(false), file.WithClock(c)) if err != nil { t.Fatal(err) } @@ -179,33 +192,37 @@ func TestRotateOnStartup(t *testing.T) { WriteMsg(t, r) // The line should have been appended to the existing file without rotation. - AssertDirContents(t, dir, logname) + AssertDirContents(t, dir, firstFile) // Close the first rotator early (the deferred close will be a no-op if // we haven't hit an error by now), so it can't interfere with the second one. r.Close() // Create a second rotator with the default setting of rotateOnStartup=true - r, err = file.NewFileRotator(filename) + c = &testClock{time.Date(2021, 11, 12, 0, 0, 0, 0, time.Local)} + r, err = file.NewFileRotator(filepath.Join(dir, logname), file.WithClock(c)) if err != nil { t.Fatal(err) } defer r.Close() // The directory contents shouldn't change until the first Write. - AssertDirContents(t, dir, logname) + AssertDirContents(t, dir, firstFile) + + secondFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) WriteMsg(t, r) - AssertDirContents(t, dir, logname, logname+".1") + AssertDirContents(t, dir, firstFile, secondFile) } -func TestRotateDateSuffix(t *testing.T) { +func TestRotate(t *testing.T) { dir := t.TempDir() logname := "beatname" filename := filepath.Join(dir, logname) - r, err := file.NewFileRotator(filename, file.Suffix(file.SuffixDate), file.MaxBackups(1)) + c := &testClock{time.Date(2021, 11, 11, 0, 0, 0, 0, time.Local)} + r, err := file.NewFileRotator(filename, file.MaxBackups(1), file.WithClock(c)) if err != nil { t.Fatal(err) } @@ -213,24 +230,24 @@ func TestRotateDateSuffix(t *testing.T) { WriteMsg(t, r) - firstExpectedPattern := fmt.Sprintf("%s-%s.*", logname, time.Now().Format("20060102150405")) - AssertDirContentsPattern(t, dir, firstExpectedPattern) + firstFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) + AssertDirContents(t, dir, firstFile) - time.Sleep(2 * time.Second) - secondExpectedPattern := fmt.Sprintf("%s-%s.*", logname, time.Now().Format("20060102150405")) + c.time = time.Date(2021, 11, 13, 0, 0, 0, 0, time.Local) + secondFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) Rotate(t, r) WriteMsg(t, r) - AssertDirContentsPattern(t, dir, firstExpectedPattern, secondExpectedPattern) + AssertDirContents(t, dir, firstFile, secondFile) - time.Sleep(2 * time.Second) - thirdExpectedPattern := fmt.Sprintf("%s-%s.*", logname, time.Now().Format("20060102150405")) + c.time = time.Date(2021, 11, 15, 0, 0, 0, 0, time.Local) + thirdFile := fmt.Sprintf("%s-%s.ndjson", logname, c.Now().Format(file.DateFormat)) Rotate(t, r) WriteMsg(t, r) - AssertDirContentsPattern(t, dir, secondExpectedPattern, thirdExpectedPattern) + AssertDirContents(t, dir, secondFile, thirdFile) } func CreateFile(t *testing.T, filename string) { @@ -258,36 +275,7 @@ func AssertDirContents(t *testing.T, dir string, files ...string) { t.Fatal(err) } - sort.Strings(files) - sort.Strings(names) - assert.EqualValues(t, files, names) -} - -func AssertDirContentsPattern(t *testing.T, dir string, patterns ...string) { - t.Helper() - - f, err := os.Open(dir) - if err != nil { - t.Fatal(err) - } - - names, err := f.Readdirnames(-1) - if err != nil { - t.Fatal(err) - } - if len(patterns) != len(names) { - t.Fatal("unexpected number of files") - } - - sort.Strings(patterns) - sort.Strings(names) - for i := 0; i < len(patterns); i++ { - matches, err := regexp.MatchString(patterns[i], names[i]) - if err != nil { - t.Fatal(err) - } - assert.True(t, matches, "pattern: %s name: %s", patterns[i], names[i]) - } + assert.ElementsMatch(t, files, names) } func WriteMsg(t *testing.T, r *file.Rotator) { @@ -307,3 +295,11 @@ func Rotate(t *testing.T, r *file.Rotator) { t.Fatal(err) } } + +type testClock struct { + time time.Time +} + +func (t testClock) Now() time.Time { + return t.time +} diff --git a/libbeat/common/file/trigger.go b/libbeat/common/file/trigger.go index d96d748f9221..22c128a334bb 100644 --- a/libbeat/common/file/trigger.go +++ b/libbeat/common/file/trigger.go @@ -52,14 +52,14 @@ type trigger interface { TriggerRotation(dataLen uint) rotateReason } -func newTriggers(rotateOnStartup bool, interval time.Duration, maxSizeBytes uint) []trigger { +func newTriggers(rotateOnStartup bool, interval time.Duration, maxSizeBytes uint, clock clock) []trigger { triggers := make([]trigger, 0) if rotateOnStartup { triggers = append(triggers, &initTrigger{}) } if interval > 0 { - triggers = append(triggers, newIntervalTrigger(interval)) + triggers = append(triggers, newIntervalTrigger(interval, clock)) } if maxSizeBytes > 0 { triggers = append(triggers, &sizeTrigger{maxSizeBytes: maxSizeBytes, size: 0}) @@ -113,8 +113,8 @@ func (realClock) Now() time.Time { return time.Now() } -func newIntervalTrigger(interval time.Duration) trigger { - t := intervalTrigger{interval: interval, clock: realClock{}} +func newIntervalTrigger(interval time.Duration, clock clock) trigger { + t := intervalTrigger{interval: interval, clock: clock} switch interval { case time.Second: diff --git a/libbeat/docs/loggingconfig.asciidoc b/libbeat/docs/loggingconfig.asciidoc index 4b47c45d5fbd..d6232e2cb07e 100644 --- a/libbeat/docs/loggingconfig.asciidoc +++ b/libbeat/docs/loggingconfig.asciidoc @@ -246,15 +246,6 @@ Intervals must be at least 1s. Values of 1m, 1h, 24h, 7*24h, 30*24h, and 365*24h are boundary-aligned with minutes, hours, days, weeks, months, and years as reported by the local system clock. All other intervals are calculated from the unix epoch. Defaults to disabled. - -[float] -==== `logging.files.suffix` - -When a log rotation happens it can either rename older files with -an incresing index if `count` is configured. The other option is `date` -that appends the current date and time to the end of the filename. -When the log is rotated a new file is created and older files -remain untouched. endif::serverless[] [float] diff --git a/libbeat/logp/config.go b/libbeat/logp/config.go index c5de43ae51a9..1e82b6e7dd88 100644 --- a/libbeat/logp/config.go +++ b/libbeat/logp/config.go @@ -19,8 +19,6 @@ package logp import ( "time" - - "github.com/elastic/beats/v7/libbeat/common/file" ) // Config contains the configuration options for the logger. To create a Config @@ -47,15 +45,14 @@ type Config struct { // FileConfig contains the configuration options for the file output. type FileConfig struct { - Path string `config:"path" yaml:"path"` - Name string `config:"name" yaml:"name"` - Suffix file.SuffixType `config:"suffix" yaml:"suffix"` - MaxSize uint `config:"rotateeverybytes" yaml:"rotateeverybytes" validate:"min=1"` - MaxBackups uint `config:"keepfiles" yaml:"keepfiles" validate:"max=1024"` - Permissions uint32 `config:"permissions"` - Interval time.Duration `config:"interval"` - RotateOnStartup bool `config:"rotateonstartup"` - RedirectStderr bool `config:"redirect_stderr" yaml:"redirect_stderr"` + Path string `config:"path" yaml:"path"` + Name string `config:"name" yaml:"name"` + MaxSize uint `config:"rotateeverybytes" yaml:"rotateeverybytes" validate:"min=1"` + MaxBackups uint `config:"keepfiles" yaml:"keepfiles" validate:"max=1024"` + Permissions uint32 `config:"permissions"` + Interval time.Duration `config:"interval"` + RotateOnStartup bool `config:"rotateonstartup"` + RedirectStderr bool `config:"redirect_stderr" yaml:"redirect_stderr"` } // MetricsConfig contains configuration used by the monitor to output metrics into the logstream. @@ -76,7 +73,6 @@ func DefaultConfig(environment Environment) Config { return Config{ Level: defaultLevel, Files: FileConfig{ - Suffix: file.SuffixCount, MaxSize: 10 * 1024 * 1024, MaxBackups: 7, Permissions: 0600, diff --git a/libbeat/logp/core.go b/libbeat/logp/core.go index c85a5feeaec6..552c81e92015 100644 --- a/libbeat/logp/core.go +++ b/libbeat/logp/core.go @@ -241,7 +241,6 @@ func makeFileOutput(cfg Config) (zapcore.Core, error) { file.Interval(cfg.Files.Interval), file.RotateOnStartup(cfg.Files.RotateOnStartup), file.RedirectStderr(cfg.Files.RedirectStderr), - file.Suffix(cfg.Files.Suffix), ) if err != nil { return nil, errors.Wrap(err, "failed to create file rotator") diff --git a/libbeat/logp/core_test.go b/libbeat/logp/core_test.go index 293f57098eb0..f8537eb6aa7b 100644 --- a/libbeat/logp/core_test.go +++ b/libbeat/logp/core_test.go @@ -153,7 +153,7 @@ func TestLoggingECSFields(t *testing.T) { Level: DebugLevel, development: true, Files: FileConfig{ - Name: "beat1.log", + Name: "beat1", }, } ToObserverOutput()(&cfg) diff --git a/libbeat/outputs/fileout/config.go b/libbeat/outputs/fileout/config.go index 28441c93bb02..e80f0a27be90 100644 --- a/libbeat/outputs/fileout/config.go +++ b/libbeat/outputs/fileout/config.go @@ -25,19 +25,17 @@ import ( ) type config struct { - Path string `config:"path"` - Filename string `config:"filename"` - Suffix file.SuffixType `config:"suffix"` - RotateEveryKb uint `config:"rotate_every_kb" validate:"min=1"` - NumberOfFiles uint `config:"number_of_files"` - Codec codec.Config `config:"codec"` - Permissions uint32 `config:"permissions"` - RotateOnStartup bool `config:"rotate_on_startup"` + Path string `config:"path"` + Filename string `config:"filename"` + RotateEveryKb uint `config:"rotate_every_kb" validate:"min=1"` + NumberOfFiles uint `config:"number_of_files"` + Codec codec.Config `config:"codec"` + Permissions uint32 `config:"permissions"` + RotateOnStartup bool `config:"rotate_on_startup"` } func defaultConfig() config { return config{ - Suffix: file.SuffixCount, NumberOfFiles: 7, RotateEveryKb: 10 * 1024, Permissions: 0600, diff --git a/libbeat/outputs/fileout/file.go b/libbeat/outputs/fileout/file.go index 48a65adc1c0b..b4a10e38396a 100644 --- a/libbeat/outputs/fileout/file.go +++ b/libbeat/outputs/fileout/file.go @@ -84,7 +84,6 @@ func (out *fileOutput) init(beat beat.Info, c config) error { var err error out.rotator, err = file.NewFileRotator( path, - file.Suffix(c.Suffix), file.MaxSizeBytes(c.RotateEveryKb*1024), file.MaxBackups(c.NumberOfFiles), file.Permissions(os.FileMode(c.Permissions)), diff --git a/libbeat/tests/system/base.py b/libbeat/tests/system/base.py index 7fd9f1dbb490..a768d80e31ea 100644 --- a/libbeat/tests/system/base.py +++ b/libbeat/tests/system/base.py @@ -1,9 +1,11 @@ import os +from datetime import datetime from beat.beat import TestCase from elasticsearch import Elasticsearch, NotFoundError class BaseTest(TestCase): + today = datetime.now().strftime("%Y%m%d") @classmethod def setUpClass(self): diff --git a/libbeat/tests/system/beat/beat.py b/libbeat/tests/system/beat/beat.py index 195741b1d317..e7a2c60640aa 100644 --- a/libbeat/tests/system/beat/beat.py +++ b/libbeat/tests/system/beat/beat.py @@ -119,6 +119,7 @@ def __del__(self): class TestCase(unittest.TestCase, ComposeMixin): + today = datetime.now().strftime("%Y%m%d") @classmethod def setUpClass(self): @@ -207,7 +208,7 @@ def start_beat(self, config = self.beat_name + ".yml" if output is None: - output = self.beat_name + ".log" + output = self.beat_name + "-" + self.today + ".ndjson" args = [cmd, "-systemTest"] if os.getenv("TEST_COVERAGE") == "true": @@ -264,7 +265,7 @@ def read_output(self, # Init defaults if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" jsons = [] with open(os.path.join(self.working_dir, output_file), "r", encoding="utf_8") as f: @@ -288,7 +289,7 @@ def read_output_json(self, output_file=None): # Init defaults if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" jsons = [] with open(os.path.join(self.working_dir, output_file), "r", encoding="utf_8") as f: @@ -368,7 +369,7 @@ def get_log(self, logfile=None): Returns the log as a string. """ if logfile is None: - logfile = self.beat_name + ".log" + logfile = self.beat_name + "-" + self.today + ".ndjson" with open(os.path.join(self.working_dir, logfile), 'r', encoding="utf_8") as f: data = f.read() @@ -380,7 +381,7 @@ def get_log_lines(self, logfile=None): Returns the log lines as a list of strings """ if logfile is None: - logfile = self.beat_name + ".log" + logfile = self.beat_name + "-" + self.today + ".ndjson" with open(os.path.join(self.working_dir, logfile), 'r', encoding="utf_8") as f: data = f.readlines() @@ -417,8 +418,9 @@ def log_contains_count(self, msg, logfile=None, ignore_case=False): # Init defaults if logfile is None: - logfile = self.beat_name + ".log" + logfile = self.beat_name + "-" + self.today + ".ndjson" + print("logfile", logfile, self.working_dir) try: with open(os.path.join(self.working_dir, logfile), "r", encoding="utf_8") as f: for line in f: @@ -430,7 +432,8 @@ def log_contains_count(self, msg, logfile=None, ignore_case=False): line = line.lower() if line.find(msg) >= 0: counter = counter + 1 - except IOError: + except IOError as e: + print(e) counter = -1 return counter @@ -442,7 +445,7 @@ def log_contains_countmap(self, pattern, capture_group, logfile=None): counts = {} if logfile is None: - logfile = self.beat_name + ".log" + logfile = self.beat_name + "-" + self.today + ".ndjson" try: with open(os.path.join(self.working_dir, logfile), "r", encoding="utf_8") as f: @@ -462,7 +465,7 @@ def log_contains_countmap(self, pattern, capture_group, logfile=None): def output_lines(self, output_file=None): """ Count number of lines in a file.""" if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" try: with open(os.path.join(self.working_dir, output_file), "r", encoding="utf_8") as f: @@ -477,7 +480,7 @@ def output_has(self, lines, output_file=None): # Init defaults if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" try: with open(os.path.join(self.working_dir, output_file, ), "r", encoding="utf_8") as f: @@ -492,7 +495,7 @@ def output_is_empty(self, output_file=None): # Init defaults if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" try: with open(os.path.join(self.working_dir, output_file, ), "r", encoding="utf_8") as f: @@ -656,7 +659,7 @@ def output_count(self, pred, output_file=None): # Init defaults if output_file is None: - output_file = "output/" + self.beat_name + output_file = "output/" + self.beat_name + "-" + self.today + ".ndjson" try: with open(os.path.join(self.working_dir, output_file), "r", encoding="utf_8") as f: diff --git a/libbeat/tests/system/test_base.py b/libbeat/tests/system/test_base.py index 97615e7ec00e..fbb8b324f162 100644 --- a/libbeat/tests/system/test_base.py +++ b/libbeat/tests/system/test_base.py @@ -165,8 +165,7 @@ def run(): # remove log, restart beat and check meta file did not change # and same UUID is used in log output. - - os.remove(os.path.join(self.working_dir, "mockbeat.log")) + os.remove(os.path.join(self.working_dir, "mockbeat-" + self.today + ".ndjson")) meta1 = run() assert self.log_contains("Beat ID: {}".format(meta1["uuid"])) diff --git a/libbeat/tests/system/test_logging.py b/libbeat/tests/system/test_logging.py index 4295bfd1776b..4380e25b55c1 100644 --- a/libbeat/tests/system/test_logging.py +++ b/libbeat/tests/system/test_logging.py @@ -39,11 +39,11 @@ def test_file_default(self): """ self.run_beat_with_args("Mockbeat is alive!", logging_args=[]) - self.assert_contains_ecs_log(logfile="logs/mockbeat") + self.assert_contains_ecs_log(logfile="logs/mockbeat-"+self.today+".ndjson") def test_file_ecs(self): """ logs to file with ECS format """ self.run_beat_with_args("Mockbeat is alive!") - self.assert_contains_ecs_log(logfile="logs/mockbeat") + self.assert_contains_ecs_log(logfile="logs/mockbeat-"+self.today+".ndjson") diff --git a/libbeat/tests/system/test_umask.py b/libbeat/tests/system/test_umask.py index e78214e2d9c3..d6a7b7f391c1 100644 --- a/libbeat/tests/system/test_umask.py +++ b/libbeat/tests/system/test_umask.py @@ -30,7 +30,7 @@ def test_output_file_perms(self): """ Test that output file permissions respect default umask """ - output_file_path = os.path.join(self.working_dir, "output", "mockbeat") + output_file_path = os.path.join(self.working_dir, "output", "mockbeat-" + self.today + ".ndjson") perms = stat.S_IMODE(os.lstat(output_file_path).st_mode) self.assertEqual(perms, self.output_file_permissions & ~TestUmask.DEFAULT_UMASK) diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index d78e42dcf8c4..178a5cb2411e 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -2266,11 +2266,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. metricbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Metricbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 3377abc029a2..a34efacdc331 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1938,11 +1938,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. packetbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Packetbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/packetbeat/tests/system/packetbeat.py b/packetbeat/tests/system/packetbeat.py index 32a9366ee339..c4727d131837 100644 --- a/packetbeat/tests/system/packetbeat.py +++ b/packetbeat/tests/system/packetbeat.py @@ -33,7 +33,7 @@ def setUpClass(self): def run_packetbeat(self, pcap, cmd=None, config="packetbeat.yml", - output="packetbeat.log", + output=None, extra_args=[], debug_selectors=[], exit_code=0, @@ -44,6 +44,9 @@ def run_packetbeat(self, pcap, the caller. """ + if output is None: + output = "packetbeat-" + self.today + ".ndjson" + if cmd is None: cmd = self.beat_path + "/packetbeat.test" @@ -87,7 +90,7 @@ def run_packetbeat(self, pcap, def start_packetbeat(self, cmd=None, config="packetbeat.yml", - output="packetbeat.log", + output=None, extra_args=[], debug_selectors=[]): """ @@ -95,6 +98,9 @@ def start_packetbeat(self, caller is responsible for stopping / waiting for the Proc instance. """ + if output is None: + output = "packetbeat-" + self.today + ".ndjson" + if cmd is None: cmd = self.beat_path + "/packetbeat.test" @@ -119,9 +125,14 @@ def start_packetbeat(self, return proc def read_output(self, - output_file="output/packetbeat", + output_file=None, types=None, required_fields=None): + + if output_file is None: + output_file = "output/packetbeat-"+self.today+".ndjson" + print(output_file) + jsons = [] with open(os.path.join(self.working_dir, output_file), "r", encoding='utf_8') as f: for line in f: diff --git a/packetbeat/tests/system/test_0002_thrift_basics.py b/packetbeat/tests/system/test_0002_thrift_basics.py index 6e0154a437ce..a1a66742bdcf 100644 --- a/packetbeat/tests/system/test_0002_thrift_basics.py +++ b/packetbeat/tests/system/test_0002_thrift_basics.py @@ -208,7 +208,7 @@ def test_thrift_send_request_response(self): self.run_packetbeat(pcap="thrift_integration.pcap", debug_selectors=["thrift"]) - objs = self.read_output() + objs = self.read_output(output_file="output/packetbeat-" + self.today + "-1.ndjson") assert all(["request" not in o for o in objs]) assert all(["response" not in o for o in objs]) diff --git a/packetbeat/tests/system/test_0006_wsgi.py b/packetbeat/tests/system/test_0006_wsgi.py index 6f905942449d..02e52b885a36 100644 --- a/packetbeat/tests/system/test_0006_wsgi.py +++ b/packetbeat/tests/system/test_0006_wsgi.py @@ -100,7 +100,7 @@ def test_send_headers_options(self): ) self.run_packetbeat(pcap="wsgi_loopback.pcap") - objs = self.read_output() + objs = self.read_output(output_file="output/packetbeat-" + self.today + "-1.ndjson") assert len(objs) == 1 o = objs[0] @@ -119,7 +119,7 @@ def test_send_headers_options(self): ) self.run_packetbeat(pcap="wsgi_loopback.pcap") - objs = self.read_output() + objs = self.read_output(output_file="output/packetbeat-" + self.today + "-2.ndjson") assert len(objs) == 1 o = objs[0] diff --git a/winlogbeat/tests/system/test_config.py b/winlogbeat/tests/system/test_config.py index 306f6cf38ef8..aefab4344ba8 100644 --- a/winlogbeat/tests/system/test_config.py +++ b/winlogbeat/tests/system/test_config.py @@ -82,7 +82,7 @@ def run_config_tst(self, pcap=None, exit_code=0): args.extend(["test", "config"]) - output = "winlogbeat.log" + output = "winlogbeat-" + self.today + ".ndjson" with open(os.path.join(self.working_dir, output), "wb") as outfile: proc = subprocess.Popen(args, diff --git a/winlogbeat/tests/system/test_wineventlog.py b/winlogbeat/tests/system/test_wineventlog.py index 347b8585d059..9bbf5a7ded43 100644 --- a/winlogbeat/tests/system/test_wineventlog.py +++ b/winlogbeat/tests/system/test_wineventlog.py @@ -52,7 +52,7 @@ def test_resume_reading_events(self): # remove the output file, otherwise there is a race condition # in read_events() below where it reads the results of the previous # execution - os.unlink(os.path.join(self.working_dir, "output", self.beat_name)) + os.unlink(os.path.join(self.working_dir, "output", self.beat_name + "-" + self.today + ".ndjson")) msg = "Second event" self.write_event_log(msg) diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 77886958368c..1705648185a4 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -1366,11 +1366,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. winlogbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Winlogbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index bab59c339c1f..c5f30eecbe0c 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -1499,11 +1499,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. auditbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Auditbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go index dedec28762af..19cd40cda913 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go @@ -234,10 +234,8 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa }, }, "paths": []string{ - filepath.Join(paths.Home(), "logs", "elastic-agent-json.log"), - filepath.Join(paths.Home(), "logs", "elastic-agent-json.log*"), - filepath.Join(paths.Home(), "logs", "elastic-agent-watcher-json.log"), - filepath.Join(paths.Home(), "logs", "elastic-agent-watcher-json.log*"), + filepath.Join(paths.Home(), "logs", "elastic-agent-*.ndjson"), + filepath.Join(paths.Home(), "logs", "elastic-agent-watcher-*.ndjson"), }, "index": fmt.Sprintf("logs-elastic_agent-%s", monitoringNamespace), "processors": []map[string]interface{}{ diff --git a/x-pack/elastic-agent/pkg/core/logger/logger.go b/x-pack/elastic-agent/pkg/core/logger/logger.go index 77cc4260accc..a63bc94f9de1 100644 --- a/x-pack/elastic-agent/pkg/core/logger/logger.go +++ b/x-pack/elastic-agent/pkg/core/logger/logger.go @@ -103,7 +103,6 @@ func DefaultLoggingConfig() *Config { cfg.ToFiles = true cfg.Files.Path = paths.Logs() cfg.Files.Name = agentName - cfg.Files.Suffix = file.SuffixDate return &cfg } @@ -115,7 +114,7 @@ func makeInternalFileOutput(cfg *Config) (zapcore.Core, error) { // defaultCfg is used to set the defaults for the file rotation of the internal logging // these settings cannot be changed by a user configuration defaultCfg := logp.DefaultConfig(logp.DefaultEnvironment) - filename := filepath.Join(paths.Home(), "logs", fmt.Sprintf("%s-json.log", cfg.Beat)) + filename := filepath.Join(paths.Home(), "logs", cfg.Beat) rotator, err := file.NewFileRotator(filename, file.MaxSizeBytes(defaultCfg.Files.MaxSize), @@ -124,7 +123,6 @@ func makeInternalFileOutput(cfg *Config) (zapcore.Core, error) { file.Interval(defaultCfg.Files.Interval), file.RotateOnStartup(defaultCfg.Files.RotateOnStartup), file.RedirectStderr(defaultCfg.Files.RedirectStderr), - file.Suffix(cfg.Files.Suffix), ) if err != nil { return nil, errors.New("failed to create internal file rotator") diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go index f96f5ecf9164..e00860ec1f10 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go @@ -131,7 +131,7 @@ func (b *Monitor) EnrichArgs(spec program.Spec, pipelineID string, args []string if isSidecar { logFile += "_monitor" } - logFile = fmt.Sprintf("%s-json.log", logFile) + logFile = fmt.Sprintf("%s", logFile) appendix = append(appendix, "-E", "logging.files.path="+loggingPath, "-E", "logging.files.name="+logFile, diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go index 240ce5adbb22..d56aee0ef2b3 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go @@ -16,9 +16,9 @@ import ( const ( // args: data path, pipeline name, application name - logFileFormat = "%s/logs/%s/%s-json.log" + logFileFormat = "%s/logs/%s/%s" // args: data path, install path, pipeline name, application name - logFileFormatWin = "%s\\logs\\%s\\%s-json.log" + logFileFormatWin = "%s\\logs\\%s\\%s" // args: pipeline name, application name mbEndpointFileFormatWin = `npipe:///%s-%s` diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 428230017f76..08c3cf4bb790 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -4508,11 +4508,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. filebeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Filebeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index 4b6dab7943f3..397214f8cd50 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -1237,11 +1237,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. functionbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Functionbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index 1eb37188303a..6bac78d08c20 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -1589,11 +1589,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. heartbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Heartbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index bcece50b8328..575581600bd6 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -2787,11 +2787,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. metricbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Metricbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/osquerybeat/osquerybeat.reference.yml b/x-pack/osquerybeat/osquerybeat.reference.yml index 13dfcc2089ed..c22416ddb193 100644 --- a/x-pack/osquerybeat/osquerybeat.reference.yml +++ b/x-pack/osquerybeat/osquerybeat.reference.yml @@ -956,11 +956,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. osquerybeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Osquerybeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index 3377abc029a2..a34efacdc331 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -1938,11 +1938,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. packetbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Packetbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 09afd2e6208a..982b46591ec9 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -1409,11 +1409,6 @@ logging.files: # file. Defaults to true. # rotateonstartup: true - # Rotated files are either suffixed with a number e.g. winlogbeat.1 when - # renamed during rotation. Or when set to date, the date is added to - # the end of the file. On rotation a new file is created, older files are untouched. - #suffix: count - # ============================= X-Pack Monitoring ============================== # Winlogbeat can export internal metrics to a central Elasticsearch monitoring # cluster. This requires xpack monitoring to be enabled in Elasticsearch. The From 668da78eb298f6fc7637b724e73977ec290902ea Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Mon, 22 Nov 2021 10:43:25 +0100 Subject: [PATCH 009/172] Add null (`\u0000`) as a valid line terminator (#28998) Add null (`\u0000`) as a valid line terminator called `null_terminator`. Closes: #27061 --- CHANGELOG.next.asciidoc | 1 + filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl | 6 ++++-- filebeat/filebeat.reference.yml | 6 ++++-- libbeat/reader/readfile/line_terminator.go | 4 ++++ x-pack/filebeat/filebeat.reference.yml | 6 ++++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 66ba47603199..f97755a0e024 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -64,6 +64,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Replace usages of `host.user.*` fields with `user.*` in `cisco`, `microsoft` and `oracle` modules. {pull}28620[28620] - Remove `docker` input. Please use `filestream` input with `container` parser or `container` input. {pull}28817[28817] - Change `threatintel` module to use new `threat.*` ECS fields. {pull}29014[29014] +- `filestream` and `log` inputs accept null (`\u0000`) as line terminator. {pull}28998[28998] *Heartbeat* diff --git a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl index a47e70d98c20..8da4a2e75fd1 100644 --- a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl +++ b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl @@ -94,7 +94,8 @@ filebeat.inputs: #max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto ### Recursive glob configuration @@ -348,7 +349,8 @@ filebeat.inputs: #message_max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto # The ingest pipeline ID associated with this input. If this is set, it diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 69c6e855c109..0ae039ad589a 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -501,7 +501,8 @@ filebeat.inputs: #max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto ### Recursive glob configuration @@ -755,7 +756,8 @@ filebeat.inputs: #message_max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto # The ingest pipeline ID associated with this input. If this is set, it diff --git a/libbeat/reader/readfile/line_terminator.go b/libbeat/reader/readfile/line_terminator.go index 68ab24736c24..bcd82e36741a 100644 --- a/libbeat/reader/readfile/line_terminator.go +++ b/libbeat/reader/readfile/line_terminator.go @@ -44,6 +44,8 @@ const ( LineSeparator // ParagraphSeparator is the unicode char PS ParagraphSeparator + // NullTerminator + NullTerminator ) var ( @@ -57,6 +59,7 @@ var ( "next_line": NextLine, "line_separator": LineSeparator, "paragraph_separator": ParagraphSeparator, + "null_terminator": NullTerminator, } lineTerminatorCharacters = map[LineTerminator][]byte{ @@ -69,6 +72,7 @@ var ( NextLine: []byte{'\u0085'}, LineSeparator: []byte("\u2028"), ParagraphSeparator: []byte("\u2029"), + NullTerminator: []byte{'\u0000'}, } ) diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 08c3cf4bb790..c25163576d10 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -2489,7 +2489,8 @@ filebeat.inputs: #max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto ### Recursive glob configuration @@ -2743,7 +2744,8 @@ filebeat.inputs: #message_max_bytes: 10485760 # Characters which separate the lines. Valid values: auto, line_feed, vertical_tab, form_feed, - # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator. + # carriage_return, carriage_return_line_feed, next_line, line_separator, paragraph_separator, + # null_terminator #line_terminator: auto # The ingest pipeline ID associated with this input. If this is set, it From 389da9416417bc29708f6b5134daa7c3a28e12fd Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 22 Nov 2021 18:39:37 +0100 Subject: [PATCH 010/172] Fix discovery of Nomad allocations (#28700) In some cases there can be multiple events during the startup of Nomad allocations. These updates were being ignored, so the allocation was not discovered, missing events. --- CHANGELOG.next.asciidoc | 3 ++- x-pack/libbeat/common/nomad/watcher.go | 10 +++++++-- x-pack/libbeat/common/nomad/watcher_test.go | 24 +++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index f97755a0e024..b528432faf0a 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -138,7 +138,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Output errors when Kibana index pattern setup fails. {pull}20121[20121] - Fix issue in autodiscover that kept inputs stopped after config updates. {pull}20305[20305] - Add service resource in k8s cluster role. {pull}20546[20546] -- Periodic metrics in logs will now report `libbeat.output.events.active` and `beat.memstats.rss` +- Periodic metrics in logs will now report `libbeat.output.events.active` and `beat.memstats.rss` as gauges (rather than counters). {pull}22877[22877] +- Fix discovery of Nomad allocations with multiple events during startup. {pull}28700[28700] - Allows disable pod events enrichment with deployment name {pull}28521[28521] - Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] diff --git a/x-pack/libbeat/common/nomad/watcher.go b/x-pack/libbeat/common/nomad/watcher.go index 31cb5590ff9b..5293d02e4746 100644 --- a/x-pack/libbeat/common/nomad/watcher.go +++ b/x-pack/libbeat/common/nomad/watcher.go @@ -130,7 +130,13 @@ func (w *watcher) sync() error { w.logger.Debugf("Found %d allocations", len(allocations)) for _, alloc := range allocations { // the allocation has not changed since last seen, ignore - if w.waitIndex > alloc.AllocModifyIndex { + if w.waitIndex > alloc.ModifyIndex { + w.logger.Debugf( + "Skip allocation.id=%s ClientStatus=%s because w.waitIndex=%v > alloc.ModifyIndex=%v", + alloc.ID, + alloc.ClientStatus, + fmt.Sprint(w.waitIndex), + fmt.Sprint(alloc.ModifyIndex)) continue } @@ -156,7 +162,7 @@ func (w *watcher) sync() error { case AllocClientStatusRunning: // Handle in-place allocation updates (like adding tags to a service definition) that // don't trigger a new allocation - updated := (w.waitIndex != 0) && (alloc.CreateIndex < w.waitIndex) && (alloc.AllocModifyIndex >= w.waitIndex) + updated := (w.waitIndex != 0) && (alloc.CreateIndex < w.waitIndex) && (alloc.ModifyIndex >= w.waitIndex) w.logger.Debugf("allocation.id=%s waitIndex=%v CreateIndex=%v ModifyIndex=%v AllocModifyIndex=%v updated=%v", alloc.ID, w.waitIndex, alloc.CreateIndex, alloc.ModifyIndex, diff --git a/x-pack/libbeat/common/nomad/watcher_test.go b/x-pack/libbeat/common/nomad/watcher_test.go index 197a929e9909..a8cd6555acc8 100644 --- a/x-pack/libbeat/common/nomad/watcher_test.go +++ b/x-pack/libbeat/common/nomad/watcher_test.go @@ -242,6 +242,30 @@ func TestAllocationWatcher(t *testing.T) { deleted: nil, }, }, + { + name: "old allocation index new modify index should be detected", + node: api.Node{ID: uuid.Must(uuid.NewV4()).String(), Name: "nomad1"}, + allocs: []api.Allocation{ + { + ModifyIndex: 20, CreateIndex: 11, + AllocModifyIndex: 11, TaskGroup: "group1", + NodeName: "nomad1", ClientStatus: AllocClientStatusRunning, + }, + }, + waitIndex: 24, + initialWaitIndex: 17, + expected: watcherEvents{ + added: nil, + updated: []api.Allocation{ + { + ModifyIndex: 20, CreateIndex: 11, + AllocModifyIndex: 11, TaskGroup: "group1", + NodeName: "nomad1", ClientStatus: AllocClientStatusRunning, + }, + }, + deleted: nil, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 6ad6bee11da2fa1243491cdfde5c235de8a971bb Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Mon, 22 Nov 2021 12:59:14 -0800 Subject: [PATCH 011/172] Enable pprof for elastic-agent and beats (#28983) Enable the /debug/pprof/ endpoints for all beats that the elastic-agent starts. Enable the pprof endpoints on elastic-agent if agent.monitoring.pprof is true (default true). Agent endpoint can be toggled in case it is located on a network and not localhost/unix socket/windows N pipe. --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl | 3 +++ .../elastic-agent/_meta/config/common.reference.p2.yml.tmpl | 3 +++ .../elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl | 3 +++ x-pack/elastic-agent/elastic-agent.docker.yml | 3 +++ x-pack/elastic-agent/elastic-agent.reference.yml | 3 +++ x-pack/elastic-agent/elastic-agent.yml | 3 +++ x-pack/elastic-agent/pkg/agent/cmd/run.go | 4 ++++ .../elastic-agent/pkg/core/monitoring/beats/beats_monitor.go | 1 + x-pack/elastic-agent/pkg/core/monitoring/config/config.go | 2 ++ 10 files changed, 26 insertions(+) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 4ebf989b89be..d0de29fdea8e 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -149,3 +149,4 @@ - Add diagnostics command to gather beat metadata. {pull}28265[28265] - Add diagnostics collect command to gather beat metadata, config, policy, and logs and bundle it into an archive. {pull}28461[28461] - Add `KIBANA_FLEET_SERVICE_TOKEN` to Elastic Agent container. {pull}28096[28096] +- Enable pprof endpoints for beats processes. Allow pprof endpoints for elastic-agent if enabled. {pull}28983[28983] diff --git a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl index 1850c003f46d..23d6203c2ecc 100644 --- a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl @@ -33,6 +33,9 @@ inputs: # logs: true # # enables metrics monitoring # metrics: true +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl index f7593c383ac8..312730db5920 100644 --- a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl @@ -107,6 +107,9 @@ inputs: # logs: false # # enables metrics monitoring # metrics: false +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl index 0b73c9fcdb76..78c64b51494b 100644 --- a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl @@ -107,6 +107,9 @@ inputs: # logs: false # # enables metrics monitoring # metrics: false +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.docker.yml b/x-pack/elastic-agent/elastic-agent.docker.yml index cb77ab59ffc9..81b48af034dd 100644 --- a/x-pack/elastic-agent/elastic-agent.docker.yml +++ b/x-pack/elastic-agent/elastic-agent.docker.yml @@ -107,6 +107,9 @@ inputs: # logs: false # # enables metrics monitoring # metrics: false +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.reference.yml b/x-pack/elastic-agent/elastic-agent.reference.yml index 5456097ce3a3..e0c4077f282d 100644 --- a/x-pack/elastic-agent/elastic-agent.reference.yml +++ b/x-pack/elastic-agent/elastic-agent.reference.yml @@ -113,6 +113,9 @@ inputs: # logs: false # # enables metrics monitoring # metrics: false +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.yml b/x-pack/elastic-agent/elastic-agent.yml index 8204503be516..70926508570e 100644 --- a/x-pack/elastic-agent/elastic-agent.yml +++ b/x-pack/elastic-agent/elastic-agent.yml @@ -39,6 +39,9 @@ inputs: # logs: true # # enables metrics monitoring # metrics: true +# # exposes /debug/pprof/ endpoints +# # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost +# pprof: true # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/pkg/agent/cmd/run.go b/x-pack/elastic-agent/pkg/agent/cmd/run.go index 56a41e068957..1c8c1dd4916f 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/run.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/run.go @@ -313,6 +313,10 @@ func setupMetrics(agentInfo *info.AgentInfo, logger *logger.Logger, operatingSys } s.Start() + if cfg.Pprof { + s.AttachPprof() + } + // return server stopper return s.Stop, nil } diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go index e00860ec1f10..d506c22a6cba 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go @@ -122,6 +122,7 @@ func (b *Monitor) EnrichArgs(spec program.Spec, pipelineID string, args []string appendix = append(appendix, "-E", "http.enabled=true", "-E", "http.host="+endpoint, + "-E", "http.pprof.enabled=true", ) } diff --git a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go index 7e1dbc77273a..10a3a6bd4a91 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go @@ -15,6 +15,7 @@ type MonitoringConfig struct { LogMetrics bool `yaml:"-" config:"-"` HTTP *MonitoringHTTPConfig `yaml:"http" config:"http"` Namespace string `yaml:"namespace" config:"namespace"` + Pprof bool `yaml:"pprof" config:"pprof"` } // MonitoringHTTPConfig is a config defining HTTP endpoint published by agent @@ -38,5 +39,6 @@ func DefaultConfig() *MonitoringConfig { Port: defaultPort, }, Namespace: defaultNamespace, + Pprof: true, } } From dbca099f0c8eabaedadb49e3ea47d8ca5a235498 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Mon, 22 Nov 2021 15:46:23 -0600 Subject: [PATCH 012/172] [Heartbeat] Log error on dupe monitor ID instead of strict req (#29041) --- CHANGELOG.next.asciidoc | 1 + heartbeat/beater/heartbeat.go | 6 +-- heartbeat/monitors/factory.go | 62 +++++++++++++++++++++++++--- heartbeat/monitors/factory_test.go | 63 +++++++++++++++++++++++++--- heartbeat/monitors/monitor.go | 66 +++++++++++++++--------------- heartbeat/monitors/monitor_test.go | 42 ++----------------- 6 files changed, 152 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b528432faf0a..ac413500ed2d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -67,6 +67,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - `filestream` and `log` inputs accept null (`\u0000`) as line terminator. {pull}28998[28998] *Heartbeat* +- Change behavior in case of duplicate monitor IDs in configs to be last monitor wins. {pull}29041[29041] *Journalbeat* diff --git a/heartbeat/beater/heartbeat.go b/heartbeat/beater/heartbeat.go index f9623753d3a2..c019e37ea72a 100644 --- a/heartbeat/beater/heartbeat.go +++ b/heartbeat/beater/heartbeat.go @@ -78,7 +78,7 @@ func New(b *beat.Beat, rawConfig *common.Config) (beat.Beater, error) { config: parsedConfig, scheduler: scheduler, // dynamicFactory is the factory used for dynamic configs, e.g. autodiscover / reload - dynamicFactory: monitors.NewFactory(b.Info, scheduler), + dynamicFactory: monitors.NewFactory(b.Info, scheduler, plugin.GlobalPluginsReg), } return bt, nil } @@ -198,11 +198,9 @@ func runRunOnceSingleConfig(cfg *common.Config, publishClient *core.SyncClient, // RunStaticMonitors runs the `heartbeat.monitors` portion of the yaml config if present. func (bt *Heartbeat) RunStaticMonitors(b *beat.Beat) (stop func(), err error) { - factory := monitors.NewFactory(b.Info, bt.scheduler) - var runners []cfgfile.Runner for _, cfg := range bt.config.Monitors { - created, err := factory.Create(b.Publisher, cfg) + created, err := bt.dynamicFactory.Create(b.Publisher, cfg) if err != nil { if errors.Is(err, monitors.ErrMonitorDisabled) { logp.Info("skipping disabled monitor: %s", err) diff --git a/heartbeat/monitors/factory.go b/heartbeat/monitors/factory.go index d2b013d3c015..7f660cbb087a 100644 --- a/heartbeat/monitors/factory.go +++ b/heartbeat/monitors/factory.go @@ -19,6 +19,7 @@ package monitors import ( "fmt" + "sync" "github.com/elastic/beats/v7/heartbeat/monitors/plugin" "github.com/elastic/beats/v7/heartbeat/monitors/stdfields" @@ -27,6 +28,7 @@ import ( "github.com/elastic/beats/v7/libbeat/cfgfile" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/fmtstr" + "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/processors" "github.com/elastic/beats/v7/libbeat/processors/actions" "github.com/elastic/beats/v7/libbeat/processors/add_data_stream" @@ -37,8 +39,12 @@ import ( // RunnerFactory that can be used to create cfg.Runner cast versions of Monitor // suitable for config reloading. type RunnerFactory struct { - info beat.Info - sched *scheduler.Scheduler + info beat.Info + sched *scheduler.Scheduler + byId map[string]*Monitor + mtx *sync.Mutex + pluginsReg *plugin.PluginsReg + logger *logp.Logger } type publishSettings struct { @@ -61,8 +67,15 @@ type publishSettings struct { } // NewFactory takes a scheduler and creates a RunnerFactory that can create cfgfile.Runner(Monitor) objects. -func NewFactory(info beat.Info, sched *scheduler.Scheduler) *RunnerFactory { - return &RunnerFactory{info, sched} +func NewFactory(info beat.Info, sched *scheduler.Scheduler, pluginsReg *plugin.PluginsReg) *RunnerFactory { + return &RunnerFactory{ + info: info, + sched: sched, + byId: map[string]*Monitor{}, + mtx: &sync.Mutex{}, + pluginsReg: pluginsReg, + logger: logp.NewLogger("monitor-factory"), + } } // Create makes a new Runner for a new monitor with the given Config. @@ -78,8 +91,45 @@ func (f *RunnerFactory) Create(p beat.Pipeline, c *common.Config) (cfgfile.Runne } p = pipetool.WithClientConfigEdit(p, configEditor) - monitor, err := newMonitor(c, plugin.GlobalPluginsReg, p, f.sched) - return monitor, err + + f.mtx.Lock() + defer f.mtx.Unlock() + + // This is a callback executed on stop of a monitor, it ensures we delete the entry in + // byId. + // It's a little tricky, because it handles the problem of this function being + // occasionally invoked twice in one stack. + // f.mtx would be locked given that golang does not support reentrant locks. + // The important thing is clearing the map, not ensuring it stops exactly on time + // so we can defer its removal from the map with a goroutine, thus breaking out of the current stack + // and ensuring the cleanup happen soon enough. + safeStop := func(m *Monitor) { + go func() { + // We can safely relock now, since we're in a new goroutine. + f.mtx.Lock() + defer f.mtx.Unlock() + + // If this element hasn't already been removed or replaced with a new + // instance delete it from the map. Check monitor identity via pointer equality. + if curM, ok := f.byId[m.stdFields.ID]; ok && curM == m { + delete(f.byId, m.stdFields.ID) + } + }() + } + monitor, err := newMonitor(c, f.pluginsReg, p, f.sched, safeStop) + if err != nil { + return nil, err + } + + if mon, ok := f.byId[monitor.stdFields.ID]; ok { + f.logger.Warnf("monitor ID %s is configured for multiple monitors! IDs should be unique values, last seen config will win", monitor.stdFields.ID) + // Stop the old monitor, since we'll swap our new one in place + mon.Stop() + } + + f.byId[monitor.stdFields.ID] = monitor + + return monitor, nil } // CheckConfig checks to see if the given monitor config is valid. diff --git a/heartbeat/monitors/factory_test.go b/heartbeat/monitors/factory_test.go index 27b119392eec..4849529cec45 100644 --- a/heartbeat/monitors/factory_test.go +++ b/heartbeat/monitors/factory_test.go @@ -23,19 +23,22 @@ import ( "github.com/stretchr/testify/require" + "github.com/elastic/beats/v7/heartbeat/scheduler" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/beat/events" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/fmtstr" + "github.com/elastic/beats/v7/libbeat/monitoring" "github.com/elastic/beats/v7/libbeat/processors/add_data_stream" ) +var binfo = beat.Info{ + Beat: "heartbeat", + IndexPrefix: "heartbeat", + Version: "8.0.0", +} + func TestPreProcessors(t *testing.T) { - binfo := beat.Info{ - Beat: "heartbeat", - IndexPrefix: "heartbeat", - Version: "8.0.0", - } tests := map[string]struct { settings publishSettings expectedIndex string @@ -143,3 +146,53 @@ func TestPreProcessors(t *testing.T) { }) } } + +func TestDuplicateMonitorIDs(t *testing.T) { + serverMonConf := mockPluginConf(t, "custom", "@every 1ms", "http://example.net") + badConf := mockBadPluginConf(t, "custom", "@every 1ms") + reg, built, closed := mockPluginsReg() + pipelineConnector := &MockPipelineConnector{} + + sched := scheduler.New(1, monitoring.NewRegistry()) + err := sched.Start() + require.NoError(t, err) + defer sched.Stop() + + f := NewFactory(binfo, sched, reg) + makeTestMon := func() (*Monitor, error) { + mIface, err := f.Create(pipelineConnector, serverMonConf) + if mIface == nil { + return nil, err + } else { + return mIface.(*Monitor), err + } + } + + // Ensure that an error is returned on a bad config + _, m0Err := newMonitor(badConf, reg, pipelineConnector, sched, nil) + require.Error(t, m0Err) + + // Would fail if the previous newMonitor didn't free the monitor.id + m1, m1Err := makeTestMon() + require.NoError(t, m1Err) + m1.Start() + m2, m2Err := makeTestMon() + require.NoError(t, m2Err) + m2.Start() + // Change the name so we can ensure that this is the currently active monitor + m2.stdFields.Name = "mon2" + // This used to trigger an error, but shouldn't any longer, we just log + // the error, and ensure the last monitor wins + require.NoError(t, m2Err) + + m, ok := f.byId[m2.stdFields.ID] + require.True(t, ok) + require.Equal(t, m2.stdFields.Name, m.stdFields.Name) + m1.Stop() + m2.Stop() + + // 3 are counted as built, even the bad config + require.Equal(t, 3, built.Load()) + // Only 2 closes, because the bad config isn't closed + require.Equal(t, 2, closed.Load()) +} diff --git a/heartbeat/monitors/monitor.go b/heartbeat/monitors/monitor.go index f93483d79334..9cdbb8ecfd68 100644 --- a/heartbeat/monitors/monitor.go +++ b/heartbeat/monitors/monitor.go @@ -37,17 +37,22 @@ import ( // ErrMonitorDisabled is returned when the monitor plugin is marked as disabled. var ErrMonitorDisabled = errors.New("monitor not loaded, plugin is disabled") +const ( + MON_INIT = iota + MON_STARTED + MON_STOPPED +) + // Monitor represents a configured recurring monitoring configuredJob loaded from a config file. Starting it // will cause it to run with the given scheduler until Stop() is called. type Monitor struct { stdFields stdfields.StdMonitorFields pluginName string config *common.Config - registrar *plugin.PluginsReg - uniqueName string scheduler *scheduler.Scheduler configuredJobs []*configuredJob enabled bool + state int // endpoints is a count of endpoints this monitor measures. endpoints int // internalsMtx is used to synchronize access to critical @@ -69,32 +74,21 @@ func (m *Monitor) String() string { } func checkMonitorConfig(config *common.Config, registrar *plugin.PluginsReg) error { - m, err := newMonitor(config, registrar, nil, nil) - if m != nil { - m.Stop() // Stop the monitor to free up the ID from uniqueness checks - } - return err -} + _, err := newMonitor(config, registrar, nil, nil, nil) -// uniqueMonitorIDs is used to keep track of explicitly configured monitor IDs and ensure no duplication within a -// given heartbeat instance. -var uniqueMonitorIDs sync.Map - -// ErrDuplicateMonitorID is returned when a monitor attempts to start using an ID already in use by another monitor. -type ErrDuplicateMonitorID struct{ ID string } - -func (e ErrDuplicateMonitorID) Error() string { - return fmt.Sprintf("monitor ID %s is configured for multiple monitors! IDs must be unique values.", e.ID) + return err } -// newMonitor Creates a new monitor, without leaking resources in the event of an error. +// newMonitor creates a new monitor, without leaking resources in the event of an error. +// you do not need to call Stop(), it will be safely garbage collected unless Start is called. func newMonitor( config *common.Config, registrar *plugin.PluginsReg, pipelineConnector beat.PipelineConnector, scheduler *scheduler.Scheduler, + onStop func(*Monitor), ) (*Monitor, error) { - m, err := newMonitorUnsafe(config, registrar, pipelineConnector, scheduler) + m, err := newMonitorUnsafe(config, registrar, pipelineConnector, scheduler, onStop) if m != nil && err != nil { m.Stop() } @@ -108,6 +102,7 @@ func newMonitorUnsafe( registrar *plugin.PluginsReg, pipelineConnector beat.PipelineConnector, scheduler *scheduler.Scheduler, + onStop func(*Monitor), ) (*Monitor, error) { // Extract just the Id, Type, and Enabled fields from the config // We'll parse things more precisely later once we know what exact type of @@ -135,14 +130,10 @@ func newMonitorUnsafe( internalsMtx: sync.Mutex{}, config: config, stats: pluginFactory.Stats, + state: MON_INIT, } - if m.stdFields.ID != "" { - // Ensure we don't have duplicate IDs - if _, loaded := uniqueMonitorIDs.LoadOrStore(m.stdFields.ID, m); loaded { - return m, ErrDuplicateMonitorID{m.stdFields.ID} - } - } else { + if m.stdFields.ID == "" { // If there's no explicit ID generate one hash, err := m.configHash() if err != nil { @@ -152,7 +143,14 @@ func newMonitorUnsafe( } p, err := pluginFactory.Create(config) - m.close = p.Close + + m.close = func() error { + if onStop != nil { + onStop(m) + } + return p.Close() + } + wrappedJobs := wrappers.WrapCommon(p.Jobs, m.stdFields) m.endpoints = p.Endpoints @@ -217,14 +215,18 @@ func (m *Monitor) Start() { } m.stats.StartMonitor(int64(m.endpoints)) + m.state = MON_STARTED } -// Stop stops the Monitor's execution in its configured scheduler. -// This is safe to call even if the Monitor was never started. +// Stop stops the monitor without freeing it in global dedup +// needed by dedup itself to avoid a reentrant lock. func (m *Monitor) Stop() { m.internalsMtx.Lock() defer m.internalsMtx.Unlock() - defer m.freeID() + + if m.state == MON_STOPPED { + return + } for _, t := range m.configuredJobs { t.Stop() @@ -238,9 +240,5 @@ func (m *Monitor) Stop() { } m.stats.StopMonitor(int64(m.endpoints)) -} - -func (m *Monitor) freeID() { - // Free up the monitor ID for reuse - uniqueMonitorIDs.Delete(m.stdFields.ID) + m.state = MON_STOPPED } diff --git a/heartbeat/monitors/monitor_test.go b/heartbeat/monitors/monitor_test.go index 0f00828bf9b2..9a0962ef8b27 100644 --- a/heartbeat/monitors/monitor_test.go +++ b/heartbeat/monitors/monitor_test.go @@ -39,7 +39,7 @@ func TestMonitor(t *testing.T) { require.NoError(t, err) defer sched.Stop() - mon, err := newMonitor(serverMonConf, reg, pipelineConnector, sched) + mon, err := newMonitor(serverMonConf, reg, pipelineConnector, sched, nil) require.NoError(t, err) mon.Start() @@ -78,43 +78,6 @@ func TestMonitor(t *testing.T) { assert.Equal(t, true, pcClient.closed) } -func TestDuplicateMonitorIDs(t *testing.T) { - serverMonConf := mockPluginConf(t, "custom", "@every 1ms", "http://example.net") - badConf := mockBadPluginConf(t, "custom", "@every 1ms") - reg, built, closed := mockPluginsReg() - pipelineConnector := &MockPipelineConnector{} - - sched := scheduler.New(1, monitoring.NewRegistry()) - err := sched.Start() - require.NoError(t, err) - defer sched.Stop() - - makeTestMon := func() (*Monitor, error) { - return newMonitor(serverMonConf, reg, pipelineConnector, sched) - } - - // Ensure that an error is returned on a bad config - _, m0Err := newMonitor(badConf, reg, pipelineConnector, sched) - require.Error(t, m0Err) - - // Would fail if the previous newMonitor didn't free the monitor.id - m1, m1Err := makeTestMon() - require.NoError(t, m1Err) - _, m2Err := makeTestMon() - require.Error(t, m2Err) - m1.Stop() - m3, m3Err := makeTestMon() - require.NoError(t, m3Err) - m3.Stop() - - // We count 3 because built doesn't count successful builds, - // just attempted creations of monitors - require.Equal(t, 3, built.Load()) - // Only one stops because the others errored on create - require.Equal(t, 2, closed.Load()) - require.NoError(t, m3Err) -} - func TestCheckInvalidConfig(t *testing.T) { serverMonConf := mockInvalidPluginConf(t) reg, built, closed := mockPluginsReg() @@ -125,7 +88,8 @@ func TestCheckInvalidConfig(t *testing.T) { require.NoError(t, err) defer sched.Stop() - m, err := newMonitor(serverMonConf, reg, pipelineConnector, sched) + m, err := newMonitor(serverMonConf, reg, pipelineConnector, sched, nil) + require.Error(t, err) // This could change if we decide the contract for newMonitor should always return a monitor require.Nil(t, m, "For this test to work we need a nil value for the monitor.") From 9b154ad3bc2d5cfa028392300072750f9ad1b8e1 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Tue, 23 Nov 2021 09:13:22 +0100 Subject: [PATCH 013/172] [Elastic-Agent] IUse itnernal port for local fleet server (#28993) [Elastic-Agent] IUse itnernal port for local fleet server (#28993) --- x-pack/elastic-agent/pkg/agent/cmd/enroll.go | 2 + .../elastic-agent/pkg/agent/cmd/enroll_cmd.go | 37 +++++++++++++++---- .../pkg/agent/configuration/fleet_server.go | 13 ++++--- .../pkg/agent/program/supported.go | 2 +- x-pack/elastic-agent/spec/fleet-server.yml | 1 + 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go index a80a9abc22bb..126161fa4c4a 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go @@ -291,6 +291,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { fPolicy, _ := cmd.Flags().GetString("fleet-server-policy") fHost, _ := cmd.Flags().GetString("fleet-server-host") fPort, _ := cmd.Flags().GetUint16("fleet-server-port") + fInternalPort, _ := cmd.Flags().GetUint16("fleet-server-internal-port") fCert, _ := cmd.Flags().GetString("fleet-server-cert") fCertKey, _ := cmd.Flags().GetString("fleet-server-cert-key") fInsecure, _ := cmd.Flags().GetBool("fleet-server-insecure-http") @@ -336,6 +337,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { SpawnAgent: !fromInstall, Headers: mapFromEnvList(fHeaders), Timeout: fTimeout, + InternalPort: fInternalPort, }, } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go index 3a96a25330cf..25365c9afe92 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go @@ -44,11 +44,13 @@ import ( ) const ( - maxRetriesstoreAgentInfo = 5 - waitingForAgent = "Waiting for Elastic Agent to start" - waitingForFleetServer = "Waiting for Elastic Agent to start Fleet Server" - defaultFleetServerHost = "0.0.0.0" - defaultFleetServerPort = 8220 + maxRetriesstoreAgentInfo = 5 + waitingForAgent = "Waiting for Elastic Agent to start" + waitingForFleetServer = "Waiting for Elastic Agent to start Fleet Server" + defaultFleetServerHost = "0.0.0.0" + defaultFleetServerPort = 8220 + defaultFleetServerInternalHost = "localhost" + defaultFleetServerInternalPort = 8221 ) var ( @@ -80,6 +82,7 @@ type enrollCmdFleetServerOption struct { PolicyID string Host string Port uint16 + InternalPort uint16 Cert string CertKey string Insecure bool @@ -91,6 +94,7 @@ type enrollCmdFleetServerOption struct { // enrollCmdOption define all the supported enrollment option. type enrollCmdOption struct { URL string `yaml:"url,omitempty"` + InternalURL string `yaml:"-"` CAs []string `yaml:"ca,omitempty"` CASha256 []string `yaml:"ca_sha256,omitempty"` Insecure bool `yaml:"insecure,omitempty"` @@ -306,7 +310,7 @@ func (c *enrollCmd) fleetServerBootstrap(ctx context.Context, persistentConfig m fleetConfig, err := createFleetServerBootstrapConfig( c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, c.options.FleetServer.PolicyID, - c.options.FleetServer.Host, c.options.FleetServer.Port, + c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.Headers, c.options.ProxyURL, @@ -401,6 +405,14 @@ func (c *enrollCmd) prepareFleetTLS() error { if c.options.URL == "" { return errors.New("url is required when a certificate is provided") } + + if c.options.FleetServer.InternalPort > 0 { + if c.options.FleetServer.InternalPort != defaultFleetServerInternalPort { + c.log.Warnf("Internal endpoint configured to: %d. Changing this value is not supported.", c.options.FleetServer.InternalPort) + } + c.options.InternalURL = fmt.Sprintf("%s:%d", defaultFleetServerInternalHost, c.options.FleetServer.InternalPort) + } + return nil } @@ -504,7 +516,7 @@ func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]inte serverConfig, err := createFleetServerBootstrapConfig( c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, c.options.FleetServer.PolicyID, - c.options.FleetServer.Host, c.options.FleetServer.Port, + c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.Headers, c.options.ProxyURL, c.options.ProxyDisabled, c.options.ProxyHeaders, @@ -516,6 +528,10 @@ func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]inte // no longer need bootstrap at this point serverConfig.Server.Bootstrap = false fleetConfig.Server = serverConfig.Server + // use internal URL for future requests + if c.options.InternalURL != "" { + fleetConfig.Client.Host = c.options.InternalURL + } } configToStore := map[string]interface{}{ @@ -836,7 +852,7 @@ func storeAgentInfo(s saver, reader io.Reader) error { func createFleetServerBootstrapConfig( connStr, serviceToken, policyID, host string, - port uint16, + port uint16, internalPort uint16, cert, key, esCA string, headers map[string]string, proxyURL string, @@ -865,6 +881,9 @@ func createFleetServerBootstrapConfig( if port == 0 { port = defaultFleetServerPort } + if internalPort == 0 { + internalPort = defaultFleetServerInternalPort + } if len(headers) > 0 { if es.Headers == nil { es.Headers = make(map[string]string) @@ -888,6 +907,7 @@ func createFleetServerBootstrapConfig( Host: host, Port: port, } + if policyID != "" { cfg.Server.Policy = &configuration.FleetServerPolicyConfig{ID: policyID} } @@ -905,6 +925,7 @@ func createFleetServerBootstrapConfig( if localFleetServer { cfg.Client.Transport.Proxy.Disable = true + cfg.Server.InternalPort = internalPort } if err := cfg.Valid(); err != nil { diff --git a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go index 25298c6e2b56..425d899a55b3 100644 --- a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go +++ b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go @@ -13,12 +13,13 @@ import ( // FleetServerConfig is the configuration written so Elastic Agent can run Fleet Server. type FleetServerConfig struct { - Bootstrap bool `config:"bootstrap" yaml:"bootstrap,omitempty"` - Policy *FleetServerPolicyConfig `config:"policy" yaml:"policy,omitempty"` - Output FleetServerOutputConfig `config:"output" yaml:"output,omitempty"` - Host string `config:"host" yaml:"host,omitempty"` - Port uint16 `config:"port" yaml:"port,omitempty"` - TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` + Bootstrap bool `config:"bootstrap" yaml:"bootstrap,omitempty"` + Policy *FleetServerPolicyConfig `config:"policy" yaml:"policy,omitempty"` + Output FleetServerOutputConfig `config:"output" yaml:"output,omitempty"` + Host string `config:"host" yaml:"host,omitempty"` + Port uint16 `config:"port" yaml:"port,omitempty"` + InternalPort uint16 `config:"internal_port" yaml:"internal_port,omitempty"` + TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` } // FleetServerPolicyConfig is the configuration for the policy Fleet Server should run on. diff --git a/x-pack/elastic-agent/pkg/agent/program/supported.go b/x-pack/elastic-agent/pkg/agent/program/supported.go index c655b2394024..70e7c6f716fb 100644 --- a/x-pack/elastic-agent/pkg/agent/program/supported.go +++ b/x-pack/elastic-agent/pkg/agent/program/supported.go @@ -25,7 +25,7 @@ func init() { // spec/metricbeat.yml // spec/osquerybeat.yml // spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("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") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/x-pack/elastic-agent/spec/fleet-server.yml b/x-pack/elastic-agent/spec/fleet-server.yml index abb4ad4a502f..ea7af0e3b89f 100644 --- a/x-pack/elastic-agent/spec/fleet-server.yml +++ b/x-pack/elastic-agent/spec/fleet-server.yml @@ -32,6 +32,7 @@ rules: selectors: - fleet.server.host - fleet.server.port + - fleet.server.internal_port - fleet.server.ssl path: inputs.0.server From 78f3a3b0a4fd15d6583b105fb240f9b2985268be Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 23 Nov 2021 10:32:36 +0100 Subject: [PATCH 014/172] Fix parsing of apache trace log levels (#28717) Apache levels may contain numbers as sublevels such as trace1. --- CHANGELOG.next.asciidoc | 1 + .../module/apache/error/ingest/pipeline.yml | 4 +++- .../module/apache/error/test/sublevel.log | 2 ++ .../error/test/sublevel.log-expected.json | 21 +++++++++++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 filebeat/module/apache/error/test/sublevel.log create mode 100644 filebeat/module/apache/error/test/sublevel.log-expected.json diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ac413500ed2d..b94e52cf135d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -185,6 +185,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support for username in cisco asa security negotiation logs {pull}26975[26975] - Relax time parsing and capture group and session type in Cisco ASA module {issue}24710[24710] {pull}28325[28325] - Correctly track bytes read when max_bytes is exceeded. {issue}28317[28317] {pull}28352[28352] +- Fix parsing of apache log levels including numbers. {pull}28717[28717] - Upgrade azure-eventhub sdk reference, contains potential checkpoint fixes. {pull}28919[28919] - Revert usageDetails api version to 2019-01-01. {pull}28995[28995] - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] diff --git a/filebeat/module/apache/error/ingest/pipeline.yml b/filebeat/module/apache/error/ingest/pipeline.yml index 4b8495dd9c89..ae35a6fb3716 100644 --- a/filebeat/module/apache/error/ingest/pipeline.yml +++ b/filebeat/module/apache/error/ingest/pipeline.yml @@ -11,10 +11,12 @@ processors: patterns: - \[%{APACHE_TIME:apache.error.timestamp}\] \[%{LOGLEVEL:log.level}\]( \[client %{IPORHOST:source.address}(:%{POSINT:source.port})?\])? %{GREEDYDATA:message} - - \[%{APACHE_TIME:apache.error.timestamp}\] \[%{DATA:apache.error.module}:%{LOGLEVEL:log.level}\] + - \[%{APACHE_TIME:apache.error.timestamp}\] \[%{DATA:apache.error.module}:%{APACHE_LOGLEVEL:log.level}\] \[pid %{NUMBER:process.pid:long}(:tid %{NUMBER:process.thread.id:long})?\]( \[client %{IPORHOST:source.address}(:%{POSINT:source.port})?\])? %{GREEDYDATA:message} pattern_definitions: + # Apache log level can have numeric sub-levels such as trace1. + APACHE_LOGLEVEL: '%{LOGLEVEL}[0-9]*' APACHE_TIME: '%{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}' ignore_missing: true - grok: diff --git a/filebeat/module/apache/error/test/sublevel.log b/filebeat/module/apache/error/test/sublevel.log new file mode 100644 index 000000000000..e4ad2fbd87b9 --- /dev/null +++ b/filebeat/module/apache/error/test/sublevel.log @@ -0,0 +1,2 @@ +[Wed Oct 20 19:20:59.121211 2021] [rewrite:trace3] [pid 121591:tid 140413273032448] mod_rewrite.c(470): [client 10.121.192.8:38350] 10.121.192.8 - - [dev.elastic.co/sid#55a374e851c8][rid#7fb438083ac0/initial] applying pattern '^/import/?(.*)$' to uri '/' + diff --git a/filebeat/module/apache/error/test/sublevel.log-expected.json b/filebeat/module/apache/error/test/sublevel.log-expected.json new file mode 100644 index 000000000000..26ad0e275386 --- /dev/null +++ b/filebeat/module/apache/error/test/sublevel.log-expected.json @@ -0,0 +1,21 @@ +[ + { + "@timestamp": "2021-10-20T19:20:59.121-02:00", + "apache.error.module": "rewrite", + "event.category": "web", + "event.dataset": "apache.error", + "event.kind": "event", + "event.module": "apache", + "event.original": "[Wed Oct 20 19:20:59.121211 2021] [rewrite:trace3] [pid 121591:tid 140413273032448] mod_rewrite.c(470): [client 10.121.192.8:38350] 10.121.192.8 - - [dev.elastic.co/sid#55a374e851c8][rid#7fb438083ac0/initial] applying pattern '^/import/?(.*)$' to uri '/'", + "event.timezone": "-02:00", + "event.type": "info", + "fileset.name": "error", + "input.type": "log", + "log.level": "trace3", + "log.offset": 0, + "message": "mod_rewrite.c(470): [client 10.121.192.8:38350] 10.121.192.8 - - [dev.elastic.co/sid#55a374e851c8][rid#7fb438083ac0/initial] applying pattern '^/import/?(.*)$' to uri '/'", + "process.pid": 121591, + "process.thread.id": 140413273032448, + "service.type": "apache" + } +] From 0e18dbe4ad0124e7307a4b44a2bc6a2634d9514a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 23 Nov 2021 10:40:59 +0100 Subject: [PATCH 015/172] Remove deprecated `--template` and `--index-policy` flags (#28870) --- CHANGELOG.next.asciidoc | 1 + auditbeat/tests/system/test_base.py | 6 +++--- filebeat/tests/system/test_base.py | 22 +++------------------- heartbeat/cmd/root.go | 5 ----- heartbeat/tests/system/test_base.py | 6 +++--- libbeat/cmd/setup.go | 20 -------------------- libbeat/docs/command-reference.asciidoc | 10 ---------- libbeat/tests/system/test_ilm.py | 17 ----------------- libbeat/tests/system/test_template.py | 8 ++------ metricbeat/tests/system/test_base.py | 8 ++++---- 10 files changed, 16 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b94e52cf135d..9fff422ab10e 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -27,6 +27,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - add_process_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - add_docker_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] +- Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] *Auditbeat* diff --git a/auditbeat/tests/system/test_base.py b/auditbeat/tests/system/test_base.py index 3a007eb4f877..2f7f645c750c 100644 --- a/auditbeat/tests/system/test_base.py +++ b/auditbeat/tests/system/test_base.py @@ -35,9 +35,9 @@ def test_start_stop(self): assert self.log_contains("auditbeat stopped") @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - def test_template(self): + def test_index_management(self): """ - Test that the template can be loaded with `setup --template` + Test that the template can be loaded with `setup --index-management` """ dirs = [self.temp_dir("auditbeat_test")] with PathCleanup(dirs): @@ -51,7 +51,7 @@ def test_template(self): } }], elasticsearch={"host": self.get_elasticsearch_url()}) - self.run_beat(extra_args=["setup", "--template"], exit_code=0) + self.run_beat(extra_args=["setup", "--index-management"], exit_code=0) assert self.log_contains('Loaded index template') assert len(es.cat.templates(name='auditbeat-*', h='name')) > 0 diff --git a/filebeat/tests/system/test_base.py b/filebeat/tests/system/test_base.py index a55fb279459f..6082c07f609e 100644 --- a/filebeat/tests/system/test_base.py +++ b/filebeat/tests/system/test_base.py @@ -28,31 +28,15 @@ def test_base(self): assert "input.type" in output @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - def test_template(self): + def test_index_management(self): """ - Test that the template can be loaded with `setup --template` + Test that the template can be loaded with `setup --index-management` """ es = Elasticsearch([self.get_elasticsearch_url()]) self.render_config_template( elasticsearch={"host": self.get_elasticsearch_url()}, ) - exit_code = self.run_beat(extra_args=["setup", "--template"]) - - assert exit_code == 0 - assert self.log_contains('Loaded index template') - assert len(es.cat.templates(name='filebeat-*', h='name')) > 0 - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - def test_template_migration(self): - """ - Test that the template can be loaded with `setup --template` - """ - es = Elasticsearch([self.get_elasticsearch_url()]) - self.render_config_template( - elasticsearch={"host": self.get_elasticsearch_url()}, - ) - exit_code = self.run_beat(extra_args=["setup", "--template", - "-E", "setup.template.overwrite=true", "-E", "migration.6_to_7.enabled=true"]) + exit_code = self.run_beat(extra_args=["setup", "--index-management"]) assert exit_code == 0 assert self.log_contains('Loaded index template') diff --git a/heartbeat/cmd/root.go b/heartbeat/cmd/root.go index 5a99e97c56f2..06f3961c2792 100644 --- a/heartbeat/cmd/root.go +++ b/heartbeat/cmd/root.go @@ -18,7 +18,6 @@ package cmd import ( - "fmt" // include all heartbeat specific autodiscovery builders _ "github.com/elastic/beats/v7/heartbeat/autodiscover/builder/hints" @@ -80,10 +79,6 @@ func Initialize(settings instance.Settings) *cmd.BeatsRootCmd { ` setup.ResetFlags() setup.Flags().Bool(cmd.IndexManagementKey, false, "Setup all components related to Elasticsearch index management, including template, ilm policy and rollover alias") - setup.Flags().MarkDeprecated(cmd.TemplateKey, fmt.Sprintf("use --%s instead", cmd.IndexManagementKey)) - setup.Flags().MarkDeprecated(cmd.ILMPolicyKey, fmt.Sprintf("use --%s instead", cmd.IndexManagementKey)) - setup.Flags().Bool(cmd.TemplateKey, false, "Setup index template") - setup.Flags().Bool(cmd.ILMPolicyKey, false, "Setup ILM policy") return rootCmd } diff --git a/heartbeat/tests/system/test_base.py b/heartbeat/tests/system/test_base.py index 141658049fb0..172960209d39 100644 --- a/heartbeat/tests/system/test_base.py +++ b/heartbeat/tests/system/test_base.py @@ -194,9 +194,9 @@ def run_fields(self, expected, local=None, top=None): return doc @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - def test_template(self): + def test_index_management(self): """ - Test that the template can be loaded with `setup --template` + Test that the template can be loaded with `setup --index-management` """ es = Elasticsearch([self.get_elasticsearch_url()]) self.render_config_template( @@ -206,7 +206,7 @@ def test_template(self): }], elasticsearch={"host": self.get_elasticsearch_url()}, ) - exit_code = self.run_beat(extra_args=["setup", "--template"]) + exit_code = self.run_beat(extra_args=["setup", "--index-management"]) assert exit_code == 0 assert self.log_contains('Loaded index template') diff --git a/libbeat/cmd/setup.go b/libbeat/cmd/setup.go index 711ddfd027cb..01c2b110a6b5 100644 --- a/libbeat/cmd/setup.go +++ b/libbeat/cmd/setup.go @@ -34,16 +34,6 @@ const ( PipelineKey = "pipelines" //IndexManagementKey used for loading all components related to ES index management in setup cmd IndexManagementKey = "index-management" - - //TemplateKey used for loading template in setup cmd - // - //Deprecated: use IndexManagementKey instead - TemplateKey = "template" - - //ILMPolicyKey used for loading ilm in setup cmd - // - //Deprecated: use IndexManagementKey instead - ILMPolicyKey = "ilm-policy" ) func genSetupCmd(settings instance.Settings, beatCreator beat.Creator) *cobra.Command { @@ -68,8 +58,6 @@ func genSetupCmd(settings instance.Settings, beatCreator beat.Creator) *cobra.Co DashboardKey: false, PipelineKey: false, IndexManagementKey: false, - TemplateKey: false, - ILMPolicyKey: false, } var setupAll = true @@ -100,10 +88,6 @@ func genSetupCmd(settings instance.Settings, beatCreator beat.Creator) *cobra.Co s.Pipeline = true case IndexManagementKey: s.IndexManagement = true - case ILMPolicyKey: - s.ILMPolicy = true - case TemplateKey: - s.Template = true } } } @@ -118,10 +102,6 @@ func genSetupCmd(settings instance.Settings, beatCreator beat.Creator) *cobra.Co setup.Flags().Bool(PipelineKey, false, "Setup Ingest pipelines") setup.Flags().Bool(IndexManagementKey, false, "Setup all components related to Elasticsearch index management, including template, ilm policy and rollover alias") - setup.Flags().Bool(TemplateKey, false, "Setup index template") - setup.Flags().MarkDeprecated(TemplateKey, fmt.Sprintf("please use --%s instead", IndexManagementKey)) - setup.Flags().Bool(ILMPolicyKey, false, "Setup ILM policy") - setup.Flags().MarkDeprecated(ILMPolicyKey, fmt.Sprintf("please use --%s instead", IndexManagementKey)) return &setup } diff --git a/libbeat/docs/command-reference.asciidoc b/libbeat/docs/command-reference.asciidoc index 833f698682d3..38cc5937ff0f 100644 --- a/libbeat/docs/command-reference.asciidoc +++ b/libbeat/docs/command-reference.asciidoc @@ -802,16 +802,6 @@ ifdef::apm-server[] Registers the <> definitions set in `ingest/pipeline/definition.json`. endif::apm-server[] -*`--template`*:: -deprecated:[7.2] -Sets up the index template only. -It is recommended to use `--index-management` instead. - -*`--ilm-policy`*:: -deprecated:[7.2] -Sets up the index lifecycle management policy. -It is recommended to use `--index-management` instead. - {global-flags} *EXAMPLES* diff --git a/libbeat/tests/system/test_ilm.py b/libbeat/tests/system/test_ilm.py index 12c79fad61d6..672f51327f64 100644 --- a/libbeat/tests/system/test_ilm.py +++ b/libbeat/tests/system/test_ilm.py @@ -191,23 +191,6 @@ def render_config(self, **kwargs): **kwargs ) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_ilm_policy_and_template(self): - """ - Test combination of ilm policy and template setup - """ - self.render_config() - - # NOTE: --template is deprecated for 8.0.0./ - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, "--template"]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_alias_created(self.alias_name) - self.idxmgmt.assert_policy_created(self.policy_name) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') def test_setup_ilm_default(self): diff --git a/libbeat/tests/system/test_template.py b/libbeat/tests/system/test_template.py index cc80e284f4e5..6a81a6bd036c 100644 --- a/libbeat/tests/system/test_template.py +++ b/libbeat/tests/system/test_template.py @@ -181,7 +181,7 @@ def setUp(self): super(TestCommandSetupTemplate, self).setUp() # auto-derived default settings, if nothing else is set - self.setupCmd = "--template" + self.setupCmd = "--index-management" self.index_name = self.beat_name + "-9.9.9" self.custom_alias = self.beat_name + "_foo" self.policy_name = self.beat_name @@ -209,7 +209,7 @@ def test_setup(self): """ self.render_config() exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, "--ilm-policy"]) + extra_args=["setup", self.setupCmd]) assert exit_code == 0 self.idxmgmt.assert_ilm_template_loaded(self.index_name, self.policy_name, self.index_name) @@ -230,8 +230,6 @@ def test_setup_template_default(self): self.idxmgmt.assert_ilm_template_loaded(self.index_name, self.policy_name, self.index_name) self.idxmgmt.assert_index_template_index_pattern(self.index_name, [self.index_name + "-*"]) - # when running `setup --template` - # write_alias and rollover_policy related to ILM are also created self.idxmgmt.assert_alias_created(self.index_name) self.idxmgmt.assert_policy_created(self.policy_name) @@ -249,8 +247,6 @@ def test_setup_template_disabled(self): assert exit_code == 0 self.idxmgmt.assert_index_template_not_loaded(self.index_name) - # when running `setup --template` and `setup.template.enabled=false` - # write_alias and rollover_policy related to ILM are still created self.idxmgmt.assert_alias_created(self.index_name) self.idxmgmt.assert_policy_created(self.policy_name) diff --git a/metricbeat/tests/system/test_base.py b/metricbeat/tests/system/test_base.py index 5d7cf103929e..43b548013e97 100644 --- a/metricbeat/tests/system/test_base.py +++ b/metricbeat/tests/system/test_base.py @@ -39,9 +39,9 @@ def test_start_stop(self): assert self.log_contains("metricbeat stopped") @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - def test_template(self): + def test_index_management(self): """ - Test that the template can be loaded with `setup --template` + Test that the template can be loaded with `setup --index-management` """ es = Elasticsearch([self.get_elasticsearch_url()]) self.render_config_template( @@ -52,7 +52,7 @@ def test_template(self): }], elasticsearch={"host": self.get_elasticsearch_url()}, ) - exit_code = self.run_beat(extra_args=["setup", "--template", "-E", "setup.template.overwrite=true"]) + exit_code = self.run_beat(extra_args=["setup", "--index-management", "-E", "setup.template.overwrite=true"]) assert exit_code == 0 assert self.log_contains('Loaded index template') @@ -100,7 +100,7 @@ def test_migration(self): }], elasticsearch={"host": self.get_elasticsearch_url()}, ) - exit_code = self.run_beat(extra_args=["setup", "--template", + exit_code = self.run_beat(extra_args=["setup", "--index-management", "-E", "setup.template.overwrite=true", "-E", "migration.6_to_7.enabled=true"]) assert exit_code == 0 From 6ef54eeca718460cde00946daa26e1fd883a53b9 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 23 Nov 2021 11:22:37 +0000 Subject: [PATCH 016/172] heartbeat: remove w2008 in the CI (#29093) --- heartbeat/Jenkinsfile.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/heartbeat/Jenkinsfile.yml b/heartbeat/Jenkinsfile.yml index 2eeaf4864647..c6603f1b9695 100644 --- a/heartbeat/Jenkinsfile.yml +++ b/heartbeat/Jenkinsfile.yml @@ -79,11 +79,6 @@ stages: platforms: ## override default labels in this specific stage. - "windows-10" stage: extended - windows-2008: - mage: "mage build unitTest" - platforms: ## override default labels in this specific stage. - - "windows-2008-r2" - stage: extended windows-8: mage: "mage build unitTest" platforms: ## override default labels in this specific stage. From 39554cd10c1f790644f7f4bad346ff88bc0ef7e7 Mon Sep 17 00:00:00 2001 From: Michael Katsoulis Date: Tue, 23 Nov 2021 13:37:23 +0200 Subject: [PATCH 017/172] Revert "Move labels and annotations under kubernetes.namespace. (#27917)" (#29069) * Revert "Move labels and annotations under kubernetes.namespace. (#27917)" This reverts commit bb36e727bc0e9806272eb043dfded9cba032ba6e. * Remove TODOs for 8.0 * Revert changes to Agent * Revert changelog entry --- CHANGELOG.next.asciidoc | 1 - auditbeat/docs/fields.asciidoc | 35 +- auditbeat/include/fields.go | 2 +- filebeat/docs/fields.asciidoc | 35 +- filebeat/include/fields.go | 2 +- heartbeat/docs/fields.asciidoc | 35 +- heartbeat/include/fields.go | 2 +- journalbeat/docs/fields.asciidoc | 35 +- journalbeat/include/fields.go | 2 +- .../autodiscover/providers/kubernetes/pod.go | 7 +- .../providers/kubernetes/pod_test.go | 292 +-- .../providers/kubernetes/service.go | 5 +- .../providers/kubernetes/service_test.go | 84 +- .../k8skeystore/kubernetes_keystore.go | 2 +- .../k8skeystore/kubernetes_keystore_test.go | 18 +- .../common/kubernetes/metadata/namespace.go | 55 +- .../kubernetes/metadata/namespace_test.go | 38 +- .../common/kubernetes/metadata/pod_test.go | 38 +- .../common/kubernetes/metadata/resource.go | 2 +- .../kubernetes/metadata/resource_test.go | 8 +- .../kubernetes/metadata/service_test.go | 26 +- .../add_kubernetes_metadata/_meta/fields.yml | 25 +- .../add_kubernetes_metadata/indexers_test.go | 16 +- metricbeat/docs/fields.asciidoc | 35 +- metricbeat/include/fields/fields.go | 2 +- .../module/kubernetes/container/data.go | 4 +- metricbeat/module/kubernetes/event/event.go | 4 +- metricbeat/module/kubernetes/pod/data.go | 4 +- .../_meta/test/ksm.v1.3.0.expected | 210 +- .../_meta/test/ksm.v1.8.0.expected | 248 +- .../_meta/test/ksm.v2.0.0.expected | 438 ++-- .../testdata/ksm-v1_3_0.plain-expected.json | 306 ++- .../state_container/state_container.go | 2 +- .../_meta/test/ksm.v1.8.0.expected | 4 +- .../_meta/test/ksm.v2.0.0.expected | 4 +- .../kubernetes/state_cronjob/state_cronjob.go | 2 +- .../state_daemonset/_meta/data.json | 6 +- .../_meta/test/ksm.v1.3.0.expected | 4 +- .../_meta/test/ksm.v1.8.0.expected | 4 +- .../_meta/test/ksm.v2.0.0.expected | 30 +- .../_meta/testdata/docs.plain-expected.json | 12 +- .../state_daemonset/state_daemonset.go | 2 +- .../_meta/test/ksm.v1.3.0.expected | 16 +- .../_meta/test/ksm.v1.8.0.expected | 24 +- .../_meta/test/ksm.v2.0.0.expected | 34 +- .../testdata/ksm-v1.3.0.plain-expected.json | 64 +- .../testdata/ksm-v1.8.0.plain-expected.json | 246 +- .../state_deployment/state_deployment.go | 2 +- .../state_job/_meta/test/ksm.v1.8.0.expected | 4 +- .../state_job/_meta/test/ksm.v2.0.0.expected | 4 +- ...e-state-metrics-v1.8.0.plain-expected.json | 2108 +++++++---------- .../module/kubernetes/state_job/state_job.go | 2 +- .../_meta/test/ksm.unit.v1.8.0.expected | 28 +- .../_meta/test/ksm.v1.8.0.expected | 16 +- .../_meta/test/ksm.v2.0.0.expected | 4 +- .../state_persistentvolumeclaim.go | 2 +- .../kubernetes/state_pod/_meta/data.json | 8 +- .../state_pod/_meta/test/ksm.v1.3.0.expected | 72 +- .../state_pod/_meta/test/ksm.v1.8.0.expected | 106 +- .../state_pod/_meta/test/ksm.v2.0.0.expected | 196 +- .../_meta/testdata/docs.plain-expected.json | 90 +- .../module/kubernetes/state_pod/state_pod.go | 2 +- .../state_replicaset/_meta/data.json | 8 +- .../_meta/test/ksm.v1.3.0.expected | 42 +- .../_meta/test/ksm.v1.8.0.expected | 28 +- .../_meta/test/ksm.v2.0.0.expected | 40 +- .../_meta/testdata/docs.plain-expected.json | 58 +- .../state_replicaset/state_replicaset.go | 2 +- .../_meta/test/ksm.v1.8.0.expected | 270 +-- .../state_resourcequota.go | 2 +- .../_meta/test/ksm.unit.v1.8.0.expected | 58 +- .../_meta/test/ksm.v1.3.0.expected | 56 +- .../_meta/test/ksm.v1.8.0.expected | 34 +- .../_meta/test/ksm.v2.0.0.expected | 24 +- .../kubernetes/state_service/state_service.go | 2 +- .../state_statefulset/_meta/data.json | 18 +- .../_meta/test/ksm.unit.v2.0.0.expected | 4 +- .../_meta/test/ksm.v1.8.0.expected | 4 +- .../_meta/testdata/docs.plain-expected.json | 40 +- .../state_statefulset/state_statefulset.go | 2 +- .../module/kubernetes/util/kubernetes.go | 2 +- metricbeat/module/kubernetes/volume/data.go | 4 +- .../openmetrics/collector/_meta/data.json | 2 +- .../prometheus/collector/_meta/data.json | 6 +- packetbeat/docs/fields.asciidoc | 35 +- packetbeat/include/fields.go | 2 +- winlogbeat/docs/fields.asciidoc | 35 +- winlogbeat/include/fields.go | 2 +- .../composable/providers/kubernetes/pod.go | 18 +- .../providers/kubernetes/pod_test.go | 46 +- .../providers/kubernetes/service.go | 9 +- .../providers/kubernetes/service_test.go | 6 +- .../module/coredns/log/test/coredns-json.log | 6 +- .../log/test/coredns-json.log-expected.json | 16 +- .../module/envoyproxy/log/test/envoy-json.log | 4 +- .../log/test/envoy-json.log-expected.json | 6 +- x-pack/functionbeat/docs/fields.asciidoc | 35 +- x-pack/functionbeat/include/fields.go | 2 +- x-pack/heartbeat/include/fields.go | 2 +- .../prometheus/collector/_meta/data.json | 5 +- x-pack/osquerybeat/docs/fields.asciidoc | 35 +- x-pack/osquerybeat/include/fields.go | 2 +- 102 files changed, 2386 insertions(+), 3700 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9fff422ab10e..8308f6c3a419 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -19,7 +19,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove deprecated config option aws_partition. {pull}28120[28120] - Improve stats API {pull}27963[27963] - Enable IMDSv2 support for `add_cloud_metadata` processor on AWS. {issue}22101[22101] {pull}28285[28285] -- Update kubernetes.namespace from keyword to group field and add name, labels, annotations, uuid as its fields {pull}27917[27917] - Libbeat: logp package forces ECS compliant logs. Logs are JSON formatted. Options to enable ECS/JSON have been removed. {issue}15544[15544] {pull}28573[28573] - Previously, RE2 and thus Golang had a bug where `(|a)*` matched more characters than `(|a)+`. To stay consistent with PCRE, the bug was fixed. Configurations that rely on the old, buggy behaviour has to be adjusted. See more about Golang bug: https://github.com/golang/go/issues/46123 {pull}27543[27543] - Update docker client. {pull}28716[28716] diff --git a/auditbeat/docs/fields.asciidoc b/auditbeat/docs/fields.asciidoc index 57191196dea2..646b9cb9f694 100644 --- a/auditbeat/docs/fields.asciidoc +++ b/auditbeat/docs/fields.asciidoc @@ -18222,47 +18222,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/auditbeat/include/fields.go b/auditbeat/include/fields.go index 298c6653d6e4..6d8c386ba384 100644 --- a/auditbeat/include/fields.go +++ b/auditbeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/filebeat/docs/fields.asciidoc b/filebeat/docs/fields.asciidoc index 34b05a0fd246..0dd3105d3996 100644 --- a/filebeat/docs/fields.asciidoc +++ b/filebeat/docs/fields.asciidoc @@ -86641,47 +86641,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/filebeat/include/fields.go b/filebeat/include/fields.go index 71cfa106bc26..920a6dc8e7ea 100644 --- a/filebeat/include/fields.go +++ b/filebeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/heartbeat/docs/fields.asciidoc b/heartbeat/docs/fields.asciidoc index ad0359e269f0..1be13cd88271 100644 --- a/heartbeat/docs/fields.asciidoc +++ b/heartbeat/docs/fields.asciidoc @@ -15804,47 +15804,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/heartbeat/include/fields.go b/heartbeat/include/fields.go index d56c982c2e21..e512932b269e 100644 --- a/heartbeat/include/fields.go +++ b/heartbeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/journalbeat/docs/fields.asciidoc b/journalbeat/docs/fields.asciidoc index d09008547350..f69b2225c1ff 100644 --- a/journalbeat/docs/fields.asciidoc +++ b/journalbeat/docs/fields.asciidoc @@ -16149,47 +16149,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/journalbeat/include/fields.go b/journalbeat/include/fields.go index 244c702bf9e0..0e063a35e4e7 100644 --- a/journalbeat/include/fields.go +++ b/journalbeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/libbeat/autodiscover/providers/kubernetes/pod.go b/libbeat/autodiscover/providers/kubernetes/pod.go index e380712f1820..2e637cda41dd 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod.go +++ b/libbeat/autodiscover/providers/kubernetes/pod.go @@ -189,8 +189,7 @@ func (p *pod) GenerateHints(event bus.Event) bus.Event { } // Look at all the namespace level default annotations and do a merge with priority going to the pod annotations. - rawNsAnn, err := kubeMeta.GetValue("namespace.annotations") - if err == nil { + if rawNsAnn, ok := kubeMeta["namespace_annotations"]; ok { namespaceAnnotations, _ := rawNsAnn.(common.MapStr) if len(namespaceAnnotations) != 0 { annotations.DeepUpdateNoOverwrite(namespaceAnnotations) @@ -385,7 +384,7 @@ func (p *pod) containerPodEvents(flag string, pod *kubernetes.Pod, c *containerI "runtime": c.runtime, } if len(namespaceAnnotations) != 0 { - kubemeta.Put("namespace.annotations", namespaceAnnotations) + kubemeta["namespace_annotations"] = namespaceAnnotations } ports := c.spec.Ports @@ -437,7 +436,7 @@ func (p *pod) podEvent(flag string, pod *kubernetes.Pod, ports common.MapStr, in kubemeta = kubemeta.Clone() kubemeta["annotations"] = annotations if len(namespaceAnnotations) != 0 { - kubemeta.Put("namespace.annotations", namespaceAnnotations) + kubemeta["namespace_annotations"] = namespaceAnnotations } // Don't set a port on the event diff --git a/libbeat/autodiscover/providers/kubernetes/pod_test.go b/libbeat/autodiscover/providers/kubernetes/pod_test.go index 266a15fb1593..ed24f4554169 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod_test.go +++ b/libbeat/autodiscover/providers/kubernetes/pod_test.go @@ -162,19 +162,17 @@ func TestGenerateHints(t *testing.T) { "co.elastic.logs/json.keys_under_root": "true", "not.to.include": "true", }), + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "prometheus", + "co.elastic.metrics/period": "10s", + "co.elastic.metrics.foobar/period": "15s", + }), "container": common.MapStr{ "name": "foobar", "id": "abc", "runtime": "docker", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "prometheus", - "co.elastic.metrics/period": "10s", - "co.elastic.metrics.foobar/period": "15s", - }), - }, + "namespace": "ns", }, }, result: bus.Event{ @@ -184,19 +182,17 @@ func TestGenerateHints(t *testing.T) { "co.elastic.logs/json.keys_under_root": "true", "not.to.include": "true", }), + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/period": "10s", + "co.elastic.metrics.foobar/period": "15s", + "co.elastic.metrics/module": "prometheus", + }), "container": common.MapStr{ "name": "foobar", "id": "abc", "runtime": "docker", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/period": "10s", - "co.elastic.metrics.foobar/period": "15s", - "co.elastic.metrics/module": "prometheus", - }), - }, + "namespace": "ns", }, "hints": common.MapStr{ "logs": common.MapStr{ @@ -231,14 +227,12 @@ func TestGenerateHints(t *testing.T) { "co.elastic.metrics.foobar/period": "15s", "not.to.include": "true", }), - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "dropwizard", - "co.elastic.metrics/period": "60s", - "co.elastic.metrics.foobar/period": "25s", - }), - }, + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "dropwizard", + "co.elastic.metrics/period": "60s", + "co.elastic.metrics.foobar/period": "25s", + }), + "namespace": "ns", "container": common.MapStr{ "name": "foobar", "id": "abc", @@ -254,19 +248,17 @@ func TestGenerateHints(t *testing.T) { "co.elastic.metrics.foobar/period": "15s", "not.to.include": "true", }), + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "dropwizard", + "co.elastic.metrics/period": "60s", + "co.elastic.metrics.foobar/period": "25s", + }), "container": common.MapStr{ "name": "foobar", "id": "abc", "runtime": "docker", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "dropwizard", - "co.elastic.metrics/period": "60s", - "co.elastic.metrics.foobar/period": "25s", - }), - }, + "namespace": "ns", }, "hints": common.MapStr{ "metrics": common.MapStr{ @@ -287,36 +279,32 @@ func TestGenerateHints(t *testing.T) { { event: bus.Event{ "kubernetes": common.MapStr{ + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "prometheus", + "co.elastic.metrics/period": "10s", + "co.elastic.metrics.foobar/period": "15s", + }), "container": common.MapStr{ "name": "foobar", "id": "abc", "runtime": "docker", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "prometheus", - "co.elastic.metrics/period": "10s", - "co.elastic.metrics.foobar/period": "15s", - }), - }, + "namespace": "ns", }, }, result: bus.Event{ "kubernetes": common.MapStr{ + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "prometheus", + "co.elastic.metrics/period": "10s", + "co.elastic.metrics.foobar/period": "15s", + }), "container": common.MapStr{ "name": "foobar", "id": "abc", "runtime": "docker", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "prometheus", - "co.elastic.metrics/period": "10s", - "co.elastic.metrics.foobar/period": "15s", - }), - }, + "namespace": "ns", }, "hints": common.MapStr{ "metrics": common.MapStr{ @@ -419,16 +407,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -461,16 +445,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -555,16 +535,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -597,16 +573,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -646,16 +618,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -736,16 +704,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -776,16 +740,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -823,16 +783,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -960,16 +916,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -998,16 +950,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1071,16 +1019,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1111,16 +1055,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1201,16 +1141,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1241,16 +1177,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1288,16 +1220,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1392,16 +1320,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1434,16 +1358,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1481,16 +1401,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1561,16 +1477,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1603,16 +1515,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1685,16 +1593,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1727,16 +1631,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1840,16 +1740,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1883,16 +1779,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1933,16 +1825,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -1983,16 +1871,12 @@ func TestPod_EmitEvent(t *testing.T) { "node": common.MapStr{ "name": "node", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "pod": common.MapStr{ "name": "filebeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", diff --git a/libbeat/autodiscover/providers/kubernetes/service.go b/libbeat/autodiscover/providers/kubernetes/service.go index 80942728fcc1..9b3c6a0aa77d 100644 --- a/libbeat/autodiscover/providers/kubernetes/service.go +++ b/libbeat/autodiscover/providers/kubernetes/service.go @@ -140,8 +140,7 @@ func (s *service) GenerateHints(event bus.Event) bus.Event { } // Look at all the namespace level default annotations and do a merge with priority going to the pod annotations. - rawNsAnn, err := kubeMeta.GetValue("namespace.annotations") - if err == nil { + if rawNsAnn, ok := kubeMeta["namespace_annotations"]; ok { nsAnn, _ := rawNsAnn.(common.MapStr) if len(nsAnn) != 0 { annotations.DeepUpdateNoOverwrite(nsAnn) @@ -215,7 +214,7 @@ func (s *service) emit(svc *kubernetes.Service, flag string) { for k, v := range namespace.GetAnnotations() { safemapstr.Put(nsAnns, k, v) } - kubemeta.Put("namespace.annotations", nsAnns) + kubemeta["namespace_annotations"] = nsAnns } } } diff --git a/libbeat/autodiscover/providers/kubernetes/service_test.go b/libbeat/autodiscover/providers/kubernetes/service_test.go index 1a8dd4696c61..c9ee77646326 100644 --- a/libbeat/autodiscover/providers/kubernetes/service_test.go +++ b/libbeat/autodiscover/providers/kubernetes/service_test.go @@ -108,15 +108,13 @@ func TestGenerateHints_Service(t *testing.T) { "co.elastic.metrics/module": "prometheus", "not.to.include": "true", }), + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/period": "10s", + }), "service": common.MapStr{ "name": "foobar", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/period": "10s", - }), - }, + "namespace": "ns", }, }, result: bus.Event{ @@ -128,12 +126,10 @@ func TestGenerateHints_Service(t *testing.T) { "service": common.MapStr{ "name": "foobar", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/period": "10s", - }), - }, + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/period": "10s", + }), + "namespace": "ns", }, "hints": common.MapStr{ "metrics": common.MapStr{ @@ -154,13 +150,11 @@ func TestGenerateHints_Service(t *testing.T) { "co.elastic.metrics/period": "10s", "not.to.include": "true", }), - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "dropwizard", - "co.elastic.metrics/period": "60s", - }), - }, + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "dropwizard", + "co.elastic.metrics/period": "60s", + }), + "namespace": "ns", "service": common.MapStr{ "name": "foobar", }, @@ -173,13 +167,11 @@ func TestGenerateHints_Service(t *testing.T) { "co.elastic.metrics/period": "10s", "not.to.include": "true", }), - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "dropwizard", - "co.elastic.metrics/period": "60s", - }), - }, + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "dropwizard", + "co.elastic.metrics/period": "60s", + }), + "namespace": "ns", "service": common.MapStr{ "name": "foobar", }, @@ -198,30 +190,26 @@ func TestGenerateHints_Service(t *testing.T) { { event: bus.Event{ "kubernetes": common.MapStr{ + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "prometheus", + "co.elastic.metrics/period": "10s", + }), "service": common.MapStr{ "name": "foobar", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "prometheus", - "co.elastic.metrics/period": "10s", - }), - }, + "namespace": "ns", }, }, result: bus.Event{ "kubernetes": common.MapStr{ + "namespace_annotations": getNestedAnnotations(common.MapStr{ + "co.elastic.metrics/module": "prometheus", + "co.elastic.metrics/period": "10s", + }), "service": common.MapStr{ "name": "foobar", }, - "namespace": common.MapStr{ - "name": "ns", - "annotations": getNestedAnnotations(common.MapStr{ - "co.elastic.metrics/module": "prometheus", - "co.elastic.metrics/period": "10s", - }), - }, + "namespace": "ns", }, "hints": common.MapStr{ "metrics": common.MapStr{ @@ -298,16 +286,12 @@ func TestEmitEvent_Service(t *testing.T) { "name": "metricbeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "service": common.MapStr{ "name": "metricbeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", @@ -389,16 +373,12 @@ func TestEmitEvent_Service(t *testing.T) { "name": "metricbeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "annotations": common.MapStr{}, }, "meta": common.MapStr{ "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "service": common.MapStr{ "name": "metricbeat", "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", diff --git a/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore.go b/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore.go index 3497a0a03619..0279e0a9a4dd 100644 --- a/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore.go +++ b/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore.go @@ -62,7 +62,7 @@ func (kr *KubernetesKeystoresRegistry) GetKeystore(event bus.Event) keystore.Key namespace := "" if val, ok := event["kubernetes"]; ok { kubernetesMeta := val.(common.MapStr) - ns, err := kubernetesMeta.GetValue("namespace.name") + ns, err := kubernetesMeta.GetValue("namespace") if err != nil { kr.logger.Debugf("Cannot retrieve kubernetes namespace from event: %s", event) return nil diff --git a/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore_test.go b/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore_test.go index 68656b0b4e73..359479b9eb89 100644 --- a/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore_test.go +++ b/libbeat/common/kubernetes/k8skeystore/kubernetes_keystore_test.go @@ -34,10 +34,10 @@ import ( func TestGetKeystore(t *testing.T) { kRegistry := NewKubernetesKeystoresRegistry(nil, nil) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": "my_namespace"}}}) - k2 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": "my_namespace"}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": "my_namespace"}}) + k2 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": "my_namespace"}}) assert.Equal(t, k1, k2) - k3 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": "my_namespace_2"}}}) + k3 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": "my_namespace_2"}}) assert.NotEqual(t, k2, k3) } @@ -64,7 +64,7 @@ func TestGetKeystoreAndRetrieve(t *testing.T) { } kRegistry := NewKubernetesKeystoresRegistry(nil, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "kubernetes.test_namespace.testing_secret.secret_value" secure, err := k1.Retrieve(key) if err != nil { @@ -100,7 +100,7 @@ func TestGetKeystoreAndRetrieveWithNonAllowedNamespace(t *testing.T) { } kRegistry := NewKubernetesKeystoresRegistry(logger, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "kubernetes.test_namespace_HACK.testing_secret.secret_value" _, err = k1.Retrieve(key) assert.Error(t, err) @@ -130,7 +130,7 @@ func TestGetKeystoreAndRetrieveWithWrongKeyFormat(t *testing.T) { } kRegistry := NewKubernetesKeystoresRegistry(logger, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "HACK_test_namespace_HACK.testing_secret.secret_value" _, err = k1.Retrieve(key) assert.Error(t, err) @@ -142,7 +142,7 @@ func TestGetKeystoreAndRetrieveWithNoSecretsExistent(t *testing.T) { ns := "test_namespace" kRegistry := NewKubernetesKeystoresRegistry(logger, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "kubernetes.test_namespace.testing_secret.secret_value" _, err := k1.Retrieve(key) assert.Error(t, err) @@ -172,7 +172,7 @@ func TestGetKeystoreAndRetrieveWithWrongSecretName(t *testing.T) { } kRegistry := NewKubernetesKeystoresRegistry(logger, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "kubernetes.test_namespace.testing_secret_WRONG.secret_value" _, err = k1.Retrieve(key) assert.Error(t, err) @@ -202,7 +202,7 @@ func TestGetKeystoreAndRetrieveWithWrongSecretValue(t *testing.T) { } kRegistry := NewKubernetesKeystoresRegistry(logger, client) - k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": common.MapStr{"name": ns}}}) + k1 := kRegistry.GetKeystore(bus.Event{"kubernetes": common.MapStr{"namespace": ns}}) key := "kubernetes.test_namespace.testing_secret.secret_value_WRONG" _, err = k1.Retrieve(key) assert.Error(t, err) diff --git a/libbeat/common/kubernetes/metadata/namespace.go b/libbeat/common/kubernetes/metadata/namespace.go index 424eab15d9af..920a0ecf2a15 100644 --- a/libbeat/common/kubernetes/metadata/namespace.go +++ b/libbeat/common/kubernetes/metadata/namespace.go @@ -70,7 +70,7 @@ func (n *namespace) GenerateK8s(obj kubernetes.Resource, opts ...FieldOptions) c } meta := n.resource.GenerateK8s(resource, obj, opts...) - meta = unifyResourceMetadata(meta) + meta = flattenMetadata(meta) // TODO: Add extra fields in here if need be return meta @@ -94,39 +94,25 @@ func (n *namespace) GenerateFromName(name string, opts ...FieldOptions) common.M return nil } -// unifyResourceMetadata moves all the resource's metadata (labels, annotations) -// under the resource field -// example input: -// "kubernetes": common.MapStr{ -// "labels": common.MapStr{ -// "foo": "bar", -// }, -// "annotations": common.MapStr{ -// "spam": "baz", -// }, -// "namespace": common.MapStr{ -// "name": name, -// "uid": uid, -// }, -// }, -// example output: -// "kubernetes": common.MapStr{ -// "namespace": common.MapStr{ -// "name": name, -// "uid": uid, -// "labels": common.MapStr{ -// "foo": "bar", -// }, -// "annotations": common.MapStr{ -// "spam": "baz", -// }, -// }, -// }, -func unifyResourceMetadata(in common.MapStr) common.MapStr { - resourceValues, ok := in[resource].(common.MapStr) +func flattenMetadata(in common.MapStr) common.MapStr { + out := common.MapStr{} + rawFields, err := in.GetValue(resource) + if err != nil { + return nil + } + + fields, ok := rawFields.(common.MapStr) if !ok { - return in + return nil } + for k, v := range fields { + if k == "name" { + out[resource] = v + } else { + out[resource+"_"+k] = v + } + } + populateFromKeys := []string{"labels", "annotations"} for _, key := range populateFromKeys { rawValues, err := in.GetValue(key) @@ -135,10 +121,9 @@ func unifyResourceMetadata(in common.MapStr) common.MapStr { } values, ok := rawValues.(common.MapStr) if ok { - resourceValues.Put(key, values) - in.Delete(key) + out[resource+"_"+key] = values } } - return in + return out } diff --git a/libbeat/common/kubernetes/metadata/namespace_test.go b/libbeat/common/kubernetes/metadata/namespace_test.go index 12f4f1377d96..65ae39d8f5f4 100644 --- a/libbeat/common/kubernetes/metadata/namespace_test.go +++ b/libbeat/common/kubernetes/metadata/namespace_test.go @@ -61,20 +61,16 @@ func TestNamespace_Generate(t *testing.T) { APIVersion: "v1", }, }, - output: common.MapStr{ - "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": name, - "uid": uid, - "labels": common.MapStr{ - "foo": "bar", - }, - "annotations": common.MapStr{ - "spam": "baz", - }, - }, + output: common.MapStr{"kubernetes": common.MapStr{ + "namespace": name, + "namespace_uid": uid, + "namespace_labels": common.MapStr{ + "foo": "bar", }, - }, + "namespace_annotations": common.MapStr{ + "spam": "baz", + }, + }}, }, } @@ -121,15 +117,13 @@ func TestNamespace_GenerateFromName(t *testing.T) { }, }, output: common.MapStr{ - "namespace": common.MapStr{ - "name": name, - "uid": uid, - "labels": common.MapStr{ - "foo": "bar", - }, - "annotations": common.MapStr{ - "spam": "baz", - }, + "namespace": name, + "namespace_uid": uid, + "namespace_labels": common.MapStr{ + "foo": "bar", + }, + "namespace_annotations": common.MapStr{ + "spam": "baz", }, }, }, diff --git a/libbeat/common/kubernetes/metadata/pod_test.go b/libbeat/common/kubernetes/metadata/pod_test.go index 0ea6053a1fbe..12e2da4fd3c9 100644 --- a/libbeat/common/kubernetes/metadata/pod_test.go +++ b/libbeat/common/kubernetes/metadata/pod_test.go @@ -133,9 +133,7 @@ func TestPod_Generate(t *testing.T) { "annotations": common.MapStr{ "app": "production", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "node": common.MapStr{ "name": "testnode", }, @@ -181,9 +179,7 @@ func TestPod_Generate(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "owner", }, @@ -238,9 +234,7 @@ func TestPod_Generate(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "daemonset": common.MapStr{ "name": "owner", }, @@ -295,9 +289,7 @@ func TestPod_Generate(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "nginx-deployment", }, @@ -355,9 +347,7 @@ func TestPod_Generate(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "nginx-deployment", }, @@ -432,9 +422,7 @@ func TestPod_GenerateFromName(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "node": common.MapStr{ "name": "testnode", }, @@ -484,9 +472,7 @@ func TestPod_GenerateFromName(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "owner", }, @@ -593,12 +579,10 @@ func TestPod_GenerateWithNodeNamespace(t *testing.T) { "uid": uid, "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "default", - "uid": uid, - "labels": common.MapStr{ - "nskey": "nsvalue", - }, + "namespace": "default", + "namespace_uid": uid, + "namespace_labels": common.MapStr{ + "nskey": "nsvalue", }, "node": common.MapStr{ "name": "testnode", diff --git a/libbeat/common/kubernetes/metadata/resource.go b/libbeat/common/kubernetes/metadata/resource.go index e9591eebbcf5..b15e39b3775c 100644 --- a/libbeat/common/kubernetes/metadata/resource.go +++ b/libbeat/common/kubernetes/metadata/resource.go @@ -107,7 +107,7 @@ func (r *Resource) GenerateK8s(kind string, obj kubernetes.Resource, options ... } if accessor.GetNamespace() != "" { - safemapstr.Put(meta, "namespace.name", accessor.GetNamespace()) + safemapstr.Put(meta, "namespace", accessor.GetNamespace()) } // Add controller metadata if present diff --git a/libbeat/common/kubernetes/metadata/resource_test.go b/libbeat/common/kubernetes/metadata/resource_test.go index 2cbe6d3a9705..5ed6f20fce0a 100644 --- a/libbeat/common/kubernetes/metadata/resource_test.go +++ b/libbeat/common/kubernetes/metadata/resource_test.go @@ -67,9 +67,7 @@ func TestResource_Generate(t *testing.T) { "labels": common.MapStr{ "foo": "bar", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", }, }, }, @@ -108,9 +106,7 @@ func TestResource_Generate(t *testing.T) { "labels": common.MapStr{ "foo": "bar", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "owner", }, diff --git a/libbeat/common/kubernetes/metadata/service_test.go b/libbeat/common/kubernetes/metadata/service_test.go index 197627aa92cb..a4b070b55a22 100644 --- a/libbeat/common/kubernetes/metadata/service_test.go +++ b/libbeat/common/kubernetes/metadata/service_test.go @@ -81,9 +81,7 @@ func TestService_Generate(t *testing.T) { "app": "istiod", "istio": "pilot", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", }, }, }, @@ -132,9 +130,7 @@ func TestService_Generate(t *testing.T) { "app": "istiod", "istio": "pilot", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "owner", }, @@ -188,9 +184,7 @@ func TestService_GenerateFromName(t *testing.T) { "labels": common.MapStr{ "foo": "bar", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", }, }, { @@ -227,9 +221,7 @@ func TestService_GenerateFromName(t *testing.T) { "labels": common.MapStr{ "foo": "bar", }, - "namespace": common.MapStr{ - "name": "default", - }, + "namespace": "default", "deployment": common.MapStr{ "name": "owner", }, @@ -303,12 +295,10 @@ func TestService_GenerateWithNamespace(t *testing.T) { "labels": common.MapStr{ "foo": "bar", }, - "namespace": common.MapStr{ - "name": "default", - "uid": uid, - "labels": common.MapStr{ - "nskey": "nsvalue", - }, + "namespace": "default", + "namespace_uid": uid, + "namespace_labels": common.MapStr{ + "nskey": "nsvalue", }, }, }, diff --git a/libbeat/processors/add_kubernetes_metadata/_meta/fields.yml b/libbeat/processors/add_kubernetes_metadata/_meta/fields.yml index c390f48e1cfc..80be2c80bba2 100644 --- a/libbeat/processors/add_kubernetes_metadata/_meta/fields.yml +++ b/libbeat/processors/add_kubernetes_metadata/_meta/fields.yml @@ -25,28 +25,9 @@ Kubernetes Pod IP - name: namespace - type: group - fields: - - name: name - type: keyword - description: > - Kubernetes namespace name - - name: uuid - type: keyword - description: > - Kubernetes namespace uuid - - name: labels.* - type: object - object_type: keyword - object_type_mapping_type: "*" - description: > - Kubernetes namespace labels map - - name: annotations.* - type: object - object_type: keyword - object_type_mapping_type: "*" - description: > - Kubernetes namespace annotations map + type: keyword + description: > + Kubernetes namespace - name: node.name type: keyword diff --git a/libbeat/processors/add_kubernetes_metadata/indexers_test.go b/libbeat/processors/add_kubernetes_metadata/indexers_test.go index 058d838592ac..853345c8bd57 100644 --- a/libbeat/processors/add_kubernetes_metadata/indexers_test.go +++ b/libbeat/processors/add_kubernetes_metadata/indexers_test.go @@ -73,9 +73,7 @@ func TestPodIndexer(t *testing.T) { "labels": common.MapStr{ "labelkey": "labelvalue", }, - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "node": common.MapStr{ "name": "testnode", }, @@ -127,9 +125,7 @@ func TestPodUIDIndexer(t *testing.T) { "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "node": common.MapStr{ "name": "testnode", }, @@ -187,9 +183,7 @@ func TestContainerIndexer(t *testing.T) { "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", "ip": "127.0.0.5", }, - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "node": common.MapStr{ "name": "testnode", }, @@ -437,9 +431,7 @@ func TestIpPortIndexer(t *testing.T) { "uid": "005f3b90-4b9d-12f8-acf0-31020a840133", "ip": "1.2.3.4", }, - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "node": common.MapStr{ "name": "testnode", }, diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 886ec623bbca..c68ea577da3a 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -41165,47 +41165,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/metricbeat/include/fields/fields.go b/metricbeat/include/fields/fields.go index f3cf04b8ba1c..ff66aa3b03c9 100644 --- a/metricbeat/include/fields/fields.go +++ b/metricbeat/include/fields/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/metricbeat/module/kubernetes/container/data.go b/metricbeat/module/kubernetes/container/data.go index 78c6d29b83ed..53a795624d98 100644 --- a/metricbeat/module/kubernetes/container/data.go +++ b/metricbeat/module/kubernetes/container/data.go @@ -43,9 +43,7 @@ func eventMapping(content []byte, perfMetrics *util.PerfMetricsCache) ([]common. for _, container := range pod.Containers { containerEvent := common.MapStr{ mb.ModuleDataKey: common.MapStr{ - "namespace": common.MapStr{ - "name": pod.PodRef.Namespace, - }, + "namespace": pod.PodRef.Namespace, "node": common.MapStr{ "name": node.NodeName, }, diff --git a/metricbeat/module/kubernetes/event/event.go b/metricbeat/module/kubernetes/event/event.go index 639e7d6ec15e..a1504b6ff059 100644 --- a/metricbeat/module/kubernetes/event/event.go +++ b/metricbeat/module/kubernetes/event/event.go @@ -126,10 +126,8 @@ func generateMapStrFromEvent(eve *kubernetes.Event, dedotConfig dedotConfig) com "timestamp": common.MapStr{ "created": kubernetes.Time(&eve.ObjectMeta.CreationTimestamp).UTC(), }, - "namespace": common.MapStr{ - "name": eve.ObjectMeta.GetNamespace(), - }, "name": eve.ObjectMeta.GetName(), + "namespace": eve.ObjectMeta.GetNamespace(), "self_link": eve.ObjectMeta.GetSelfLink(), "generate_name": eve.ObjectMeta.GetGenerateName(), "uid": eve.ObjectMeta.GetUID(), diff --git a/metricbeat/module/kubernetes/pod/data.go b/metricbeat/module/kubernetes/pod/data.go index 8e4ffc759eb6..bb24d31905c9 100644 --- a/metricbeat/module/kubernetes/pod/data.go +++ b/metricbeat/module/kubernetes/pod/data.go @@ -59,9 +59,7 @@ func eventMapping(content []byte, perfMetrics *util.PerfMetricsCache) ([]common. podEvent := common.MapStr{ mb.ModuleDataKey: common.MapStr{ - "namespace": common.MapStr{ - "name": pod.PodRef.Namespace, - }, + "namespace": pod.PodRef.Namespace, "node": common.MapStr{ "name": node.NodeName, }, diff --git a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.3.0.expected index 004b0ee99681..9bfecbe3c398 100644 --- a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.3.0.expected @@ -10,9 +10,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -53,37 +51,30 @@ { "RootFields": { "container": { - "id": "ab382dbe8f8265f88ee9fec7de142f778da4a5fd9fe0334e3bdb6fe851124c08", + "id": "e9568dfef1dd249cabac4bf09e6bf4a239fe738ae20eba072b6516676fce4bf6", "image": { - "name": "k8s.gcr.io/kube-addon-manager:v8.6" + "name": "gcr.io/google_containers/kube-apiserver-amd64:v1.9.7" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-addon-manager-minikube" + "name": "kube-apiserver-minikube" } }, "MetricSetFields": { "cpu": { "request": { - "cores": 0.005 - } - }, - "id": "docker://ab382dbe8f8265f88ee9fec7de142f778da4a5fd9fe0334e3bdb6fe851124c08", - "memory": { - "request": { - "bytes": 52428800 + "cores": 0.25 } }, - "name": "kube-addon-manager", + "id": "docker://e9568dfef1dd249cabac4bf09e6bf4a239fe738ae20eba072b6516676fce4bf6", + "name": "kube-apiserver", "status": { "phase": "running", "ready": true, @@ -104,32 +95,25 @@ { "RootFields": { "container": { - "id": "e9568dfef1dd249cabac4bf09e6bf4a239fe738ae20eba072b6516676fce4bf6", + "id": "76c260259ddfd0267b5acb4e514465215ef1ebfa93a4057d592828772e6b39f5", "image": { - "name": "gcr.io/google_containers/kube-apiserver-amd64:v1.9.7" + "name": "gcr.io/google_containers/kube-proxy-amd64:v1.9.7" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-apiserver-minikube" + "name": "kube-proxy-znhg6" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.25 - } - }, - "id": "docker://e9568dfef1dd249cabac4bf09e6bf4a239fe738ae20eba072b6516676fce4bf6", - "name": "kube-apiserver", + "id": "docker://76c260259ddfd0267b5acb4e514465215ef1ebfa93a4057d592828772e6b39f5", + "name": "kube-proxy", "status": { "phase": "running", "ready": true, @@ -150,43 +134,30 @@ { "RootFields": { "container": { - "id": "948c4ebd8ca4fdf352e7fbf7f5c5d381af7e615ced435dc42fde0c1d25851320", + "id": "4beb9aab887ca162c9cb3534c4826156636241052cd548153eaa2a170b6d102f", "image": { - "name": "k8s.gcr.io/addon-resizer:1.7" + "name": "gcr.io/google_containers/kube-controller-manager-amd64:v1.9.7" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-state-metrics-6479d88c5c-5b6cl" + "name": "kube-controller-manager-minikube" } }, "MetricSetFields": { "cpu": { - "limit": { - "cores": 0.1 - }, - "request": { - "cores": 0.1 - } - }, - "id": "docker://948c4ebd8ca4fdf352e7fbf7f5c5d381af7e615ced435dc42fde0c1d25851320", - "memory": { - "limit": { - "bytes": 31457280 - }, "request": { - "bytes": 31457280 + "cores": 0.2 } }, - "name": "addon-resizer", + "id": "docker://4beb9aab887ca162c9cb3534c4826156636241052cd548153eaa2a170b6d102f", + "name": "kube-controller-manager", "status": { "phase": "running", "ready": true, @@ -207,27 +178,41 @@ { "RootFields": { "container": { - "id": "76c260259ddfd0267b5acb4e514465215ef1ebfa93a4057d592828772e6b39f5", + "id": "948c4ebd8ca4fdf352e7fbf7f5c5d381af7e615ced435dc42fde0c1d25851320", "image": { - "name": "gcr.io/google_containers/kube-proxy-amd64:v1.9.7" + "name": "k8s.gcr.io/addon-resizer:1.7" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-proxy-znhg6" + "name": "kube-state-metrics-6479d88c5c-5b6cl" } }, "MetricSetFields": { - "id": "docker://76c260259ddfd0267b5acb4e514465215ef1ebfa93a4057d592828772e6b39f5", - "name": "kube-proxy", + "cpu": { + "limit": { + "cores": 0.1 + }, + "request": { + "cores": 0.1 + } + }, + "id": "docker://948c4ebd8ca4fdf352e7fbf7f5c5d381af7e615ced435dc42fde0c1d25851320", + "memory": { + "limit": { + "bytes": 31457280 + }, + "request": { + "bytes": 31457280 + } + }, + "name": "addon-resizer", "status": { "phase": "running", "ready": true, @@ -256,9 +241,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -302,9 +285,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -348,32 +329,25 @@ { "RootFields": { "container": { - "id": "4beb9aab887ca162c9cb3534c4826156636241052cd548153eaa2a170b6d102f", + "id": "6e96fd8a687409b2314dcc01f209bb0c813c2fb08b8f75ad1695e120d41e1a2a", "image": { - "name": "gcr.io/google_containers/kube-controller-manager-amd64:v1.9.7" + "name": "gcr.io/google_containers/etcd-amd64:3.1.11" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-controller-manager-minikube" + "name": "etcd-minikube" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.2 - } - }, - "id": "docker://4beb9aab887ca162c9cb3534c4826156636241052cd548153eaa2a170b6d102f", - "name": "kube-controller-manager", + "id": "docker://6e96fd8a687409b2314dcc01f209bb0c813c2fb08b8f75ad1695e120d41e1a2a", + "name": "etcd", "status": { "phase": "running", "ready": true, @@ -394,43 +368,35 @@ { "RootFields": { "container": { - "id": "88951e0178ea5131fa3e2d7cafacb3a7e63700795dd6fa0d40ed2e4ac1f52f9c", + "id": "ab382dbe8f8265f88ee9fec7de142f778da4a5fd9fe0334e3bdb6fe851124c08", "image": { - "name": "quay.io/coreos/kube-state-metrics:v1.3.0" + "name": "k8s.gcr.io/kube-addon-manager:v8.6" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-state-metrics-6479d88c5c-5b6cl" + "name": "kube-addon-manager-minikube" } }, "MetricSetFields": { "cpu": { - "limit": { - "cores": 0.101 - }, "request": { - "cores": 0.101 + "cores": 0.005 } }, - "id": "docker://88951e0178ea5131fa3e2d7cafacb3a7e63700795dd6fa0d40ed2e4ac1f52f9c", + "id": "docker://ab382dbe8f8265f88ee9fec7de142f778da4a5fd9fe0334e3bdb6fe851124c08", "memory": { - "limit": { - "bytes": 106954752 - }, "request": { - "bytes": 106954752 + "bytes": 52428800 } }, - "name": "kube-state-metrics", + "name": "kube-addon-manager", "status": { "phase": "running", "ready": true, @@ -451,41 +417,44 @@ { "RootFields": { "container": { - "id": "aad0addd205dc72dc7abc8f9d02a1b429a2f2e1df3acc60431ca6b79746c093b", + "id": "88951e0178ea5131fa3e2d7cafacb3a7e63700795dd6fa0d40ed2e4ac1f52f9c", "image": { - "name": "gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.7" + "name": "quay.io/coreos/kube-state-metrics:v1.3.0" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-dns-6f4fd4bdf-wlmht" + "name": "kube-state-metrics-6479d88c5c-5b6cl" } }, "MetricSetFields": { "cpu": { + "limit": { + "cores": 0.101 + }, "request": { - "cores": 0.01 + "cores": 0.101 } }, - "id": "docker://aad0addd205dc72dc7abc8f9d02a1b429a2f2e1df3acc60431ca6b79746c093b", + "id": "docker://88951e0178ea5131fa3e2d7cafacb3a7e63700795dd6fa0d40ed2e4ac1f52f9c", "memory": { + "limit": { + "bytes": 106954752 + }, "request": { - "bytes": 20971520 + "bytes": 106954752 } }, - "name": "sidecar", + "name": "kube-state-metrics", "status": { "phase": "running", "ready": true, - "reason": "OOMKilled", "restarts": 0 } }, @@ -511,9 +480,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -544,30 +511,39 @@ { "RootFields": { "container": { - "id": "6e96fd8a687409b2314dcc01f209bb0c813c2fb08b8f75ad1695e120d41e1a2a", + "id": "aad0addd205dc72dc7abc8f9d02a1b429a2f2e1df3acc60431ca6b79746c093b", "image": { - "name": "gcr.io/google_containers/etcd-amd64:3.1.11" + "name": "gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.7" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "etcd-minikube" + "name": "kube-dns-6f4fd4bdf-wlmht" } }, "MetricSetFields": { - "id": "docker://6e96fd8a687409b2314dcc01f209bb0c813c2fb08b8f75ad1695e120d41e1a2a", - "name": "etcd", + "cpu": { + "request": { + "cores": 0.01 + } + }, + "id": "docker://aad0addd205dc72dc7abc8f9d02a1b429a2f2e1df3acc60431ca6b79746c093b", + "memory": { + "request": { + "bytes": 20971520 + } + }, + "name": "sidecar", "status": { "phase": "running", "ready": true, + "reason": "OOMKilled", "restarts": 0 } }, @@ -593,9 +569,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, diff --git a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.8.0.expected index ce83e9114458..4277911c4b3f 100644 --- a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v1.8.0.expected @@ -2,31 +2,38 @@ { "RootFields": { "container": { - "id": "30216f9823ca7d3454987075dd7256b665b14b2333c9a6762b127b6378516609", + "id": "f13c53a3ed0f3626b33b3c588d6913257320f65714eff28f25ead8f7663dc93b", "image": { - "name": "busybox:latest" + "name": "k8s.gcr.io/kube-addon-manager:v9.0.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "hello-1578512100-vr7wj" + "name": "kube-addon-manager-minikube" } }, "MetricSetFields": { - "id": "docker://30216f9823ca7d3454987075dd7256b665b14b2333c9a6762b127b6378516609", - "name": "hello", + "cpu": { + "request": { + "cores": 0.005 + } + }, + "id": "docker://f13c53a3ed0f3626b33b3c588d6913257320f65714eff28f25ead8f7663dc93b", + "memory": { + "request": { + "bytes": 52428800 + } + }, + "name": "kube-addon-manager", "status": { - "phase": "terminated", - "ready": false, - "reason": "Completed", + "phase": "running", + "ready": true, "restarts": 0 } }, @@ -52,9 +59,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -90,40 +95,25 @@ { "RootFields": { "container": { - "id": "15ada7864628d1c8007c01420e5887a501590d3bc9c25628a4770172ad615112", + "id": "c152296116c064db311061cf6c39cff2de8d66339c954505cb68816464cf4a03", "image": { - "name": "k8s.gcr.io/coredns:1.6.2" + "name": "k8s.gcr.io/kube-proxy:v1.16.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "coredns-5644d7b6d9-k6wsp" + "name": "kube-proxy-dwg6l" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.1 - } - }, - "id": "docker://15ada7864628d1c8007c01420e5887a501590d3bc9c25628a4770172ad615112", - "memory": { - "limit": { - "bytes": 178257920 - }, - "request": { - "bytes": 73400320 - } - }, - "name": "coredns", + "id": "docker://c152296116c064db311061cf6c39cff2de8d66339c954505cb68816464cf4a03", + "name": "kube-proxy", "status": { "phase": "running", "ready": true, @@ -144,27 +134,30 @@ { "RootFields": { "container": { - "id": "a4cec783af3614b137f4b449eebf3ac61eaf0a8661cb2f4847741be5a24de0bf", + "id": "465ebffafd7fc238a2fa2e764255efcbff88d5513f4c68f57d70932985428d12", "image": { - "name": "k8s.gcr.io/nginx-slim:0.8" + "name": "k8s.gcr.io/kube-controller-manager:v1.16.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "web-0" + "name": "kube-controller-manager-minikube" } }, "MetricSetFields": { - "id": "docker://a4cec783af3614b137f4b449eebf3ac61eaf0a8661cb2f4847741be5a24de0bf", - "name": "nginx", + "cpu": { + "request": { + "cores": 0.2 + } + }, + "id": "docker://465ebffafd7fc238a2fa2e764255efcbff88d5513f4c68f57d70932985428d12", + "name": "kube-controller-manager", "status": { "phase": "running", "ready": true, @@ -185,30 +178,29 @@ { "RootFields": { "container": { - "id": "e0b05fcb32abf937c395942e0234b5dfc834206149bbb95afa585c51693650f3", + "id": "30216f9823ca7d3454987075dd7256b665b14b2333c9a6762b127b6378516609", "image": { - "name": "gcr.io/k8s-minikube/storage-provisioner:v1.8.1" + "name": "busybox:latest" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" }, "pod": { - "name": "storage-provisioner" + "name": "hello-1578512100-vr7wj" } }, "MetricSetFields": { - "id": "docker://e0b05fcb32abf937c395942e0234b5dfc834206149bbb95afa585c51693650f3", - "name": "storage-provisioner", + "id": "docker://30216f9823ca7d3454987075dd7256b665b14b2333c9a6762b127b6378516609", + "name": "hello", "status": { - "phase": "running", - "ready": true, + "phase": "terminated", + "ready": false, + "reason": "Completed", "restarts": 0 } }, @@ -226,37 +218,38 @@ { "RootFields": { "container": { - "id": "f13c53a3ed0f3626b33b3c588d6913257320f65714eff28f25ead8f7663dc93b", + "id": "f8fe5be1dbb1931d702c89235c79965730cbcced7b0ced9895f6c54c1ae8e5c3", "image": { - "name": "k8s.gcr.io/kube-addon-manager:v9.0.2" + "name": "k8s.gcr.io/coredns:1.6.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-addon-manager-minikube" + "name": "coredns-5644d7b6d9-fhwjd" } }, "MetricSetFields": { "cpu": { "request": { - "cores": 0.005 + "cores": 0.1 } }, - "id": "docker://f13c53a3ed0f3626b33b3c588d6913257320f65714eff28f25ead8f7663dc93b", + "id": "docker://f8fe5be1dbb1931d702c89235c79965730cbcced7b0ced9895f6c54c1ae8e5c3", "memory": { + "limit": { + "bytes": 178257920 + }, "request": { - "bytes": 52428800 + "bytes": 73400320 } }, - "name": "kube-addon-manager", + "name": "coredns", "status": { "phase": "running", "ready": true, @@ -277,27 +270,25 @@ { "RootFields": { "container": { - "id": "669cc415d86b872450deaada60c73cca387ca23a7b0f21c5b146467b95cf1f76", + "id": "e0b05fcb32abf937c395942e0234b5dfc834206149bbb95afa585c51693650f3", "image": { - "name": "k8s.gcr.io/nginx-slim:0.8" + "name": "gcr.io/k8s-minikube/storage-provisioner:v1.8.1" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "web-1" + "name": "storage-provisioner" } }, "MetricSetFields": { - "id": "docker://669cc415d86b872450deaada60c73cca387ca23a7b0f21c5b146467b95cf1f76", - "name": "nginx", + "id": "docker://e0b05fcb32abf937c395942e0234b5dfc834206149bbb95afa585c51693650f3", + "name": "storage-provisioner", "status": { "phase": "running", "ready": true, @@ -318,32 +309,25 @@ { "RootFields": { "container": { - "id": "cdaefb4df2f2add498f884fdc717a6ca8d2681c1636934747de600e6427e0c0d", + "id": "2e0519a3fcd62acea8f4253b994ce53356d89171c0eb0920a13fe58b637d8cdb", "image": { - "name": "k8s.gcr.io/kube-apiserver:v1.16.2" + "name": "quay.io/coreos/kube-state-metrics:v1.8.0" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-apiserver-minikube" + "name": "kube-state-metrics-898d4db8d-dqmtg" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.25 - } - }, - "id": "docker://cdaefb4df2f2add498f884fdc717a6ca8d2681c1636934747de600e6427e0c0d", - "name": "kube-apiserver", + "id": "docker://2e0519a3fcd62acea8f4253b994ce53356d89171c0eb0920a13fe58b637d8cdb", + "name": "kube-state-metrics", "status": { "phase": "running", "ready": true, @@ -364,27 +348,38 @@ { "RootFields": { "container": { - "id": "c152296116c064db311061cf6c39cff2de8d66339c954505cb68816464cf4a03", + "id": "15ada7864628d1c8007c01420e5887a501590d3bc9c25628a4770172ad615112", "image": { - "name": "k8s.gcr.io/kube-proxy:v1.16.2" + "name": "k8s.gcr.io/coredns:1.6.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-proxy-dwg6l" + "name": "coredns-5644d7b6d9-k6wsp" } }, "MetricSetFields": { - "id": "docker://c152296116c064db311061cf6c39cff2de8d66339c954505cb68816464cf4a03", - "name": "kube-proxy", + "cpu": { + "request": { + "cores": 0.1 + } + }, + "id": "docker://15ada7864628d1c8007c01420e5887a501590d3bc9c25628a4770172ad615112", + "memory": { + "limit": { + "bytes": 178257920 + }, + "request": { + "bytes": 73400320 + } + }, + "name": "coredns", "status": { "phase": "running", "ready": true, @@ -405,40 +400,25 @@ { "RootFields": { "container": { - "id": "f8fe5be1dbb1931d702c89235c79965730cbcced7b0ced9895f6c54c1ae8e5c3", + "id": "669cc415d86b872450deaada60c73cca387ca23a7b0f21c5b146467b95cf1f76", "image": { - "name": "k8s.gcr.io/coredns:1.6.2" + "name": "k8s.gcr.io/nginx-slim:0.8" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" }, "pod": { - "name": "coredns-5644d7b6d9-fhwjd" + "name": "web-1" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.1 - } - }, - "id": "docker://f8fe5be1dbb1931d702c89235c79965730cbcced7b0ced9895f6c54c1ae8e5c3", - "memory": { - "limit": { - "bytes": 178257920 - }, - "request": { - "bytes": 73400320 - } - }, - "name": "coredns", + "id": "docker://669cc415d86b872450deaada60c73cca387ca23a7b0f21c5b146467b95cf1f76", + "name": "nginx", "status": { "phase": "running", "ready": true, @@ -459,27 +439,30 @@ { "RootFields": { "container": { - "id": "2e0519a3fcd62acea8f4253b994ce53356d89171c0eb0920a13fe58b637d8cdb", + "id": "cdaefb4df2f2add498f884fdc717a6ca8d2681c1636934747de600e6427e0c0d", "image": { - "name": "quay.io/coreos/kube-state-metrics:v1.8.0" + "name": "k8s.gcr.io/kube-apiserver:v1.16.2" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-state-metrics-898d4db8d-dqmtg" + "name": "kube-apiserver-minikube" } }, "MetricSetFields": { - "id": "docker://2e0519a3fcd62acea8f4253b994ce53356d89171c0eb0920a13fe58b637d8cdb", - "name": "kube-state-metrics", + "cpu": { + "request": { + "cores": 0.25 + } + }, + "id": "docker://cdaefb4df2f2add498f884fdc717a6ca8d2681c1636934747de600e6427e0c0d", + "name": "kube-apiserver", "status": { "phase": "running", "ready": true, @@ -508,9 +491,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, @@ -541,32 +522,25 @@ { "RootFields": { "container": { - "id": "465ebffafd7fc238a2fa2e764255efcbff88d5513f4c68f57d70932985428d12", + "id": "a4cec783af3614b137f4b449eebf3ac61eaf0a8661cb2f4847741be5a24de0bf", "image": { - "name": "k8s.gcr.io/kube-controller-manager:v1.16.2" + "name": "k8s.gcr.io/nginx-slim:0.8" }, "runtime": "docker" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" }, "pod": { - "name": "kube-controller-manager-minikube" + "name": "web-0" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.2 - } - }, - "id": "docker://465ebffafd7fc238a2fa2e764255efcbff88d5513f4c68f57d70932985428d12", - "name": "kube-controller-manager", + "id": "docker://a4cec783af3614b137f4b449eebf3ac61eaf0a8661cb2f4847741be5a24de0bf", + "name": "nginx", "status": { "phase": "running", "ready": true, diff --git a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v2.0.0.expected index b1824708ae83..a8f3b293465e 100644 --- a/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_container/_meta/test/ksm.v2.0.0.expected @@ -2,43 +2,38 @@ { "RootFields": { "container": { - "id": "3037e577635e9cbcefe1f273e5b06784d36807af76158e4add887e840c42e1ef", + "id": "3101d1525d6133851881f4b7cd439033663daefeb4849e5322d1428f09620628", "image": { - "name": "docker.io/kindest/kindnetd:v20210326-1e038dc5" + "name": "k8s.gcr.io/coredns:1.6.2" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-control-plane" }, "pod": { - "name": "kindnet-tg7tl" + "name": "coredns-5644d7b6d9-zgdsx" } }, "MetricSetFields": { "cpu": { - "limit": { - "cores": 0.1 - }, "request": { "cores": 0.1 } }, - "id": "containerd://3037e577635e9cbcefe1f273e5b06784d36807af76158e4add887e840c42e1ef", + "id": "containerd://3101d1525d6133851881f4b7cd439033663daefeb4849e5322d1428f09620628", "memory": { "limit": { - "bytes": 52428800 + "bytes": 178257920 }, "request": { - "bytes": 52428800 + "bytes": 73400320 } }, - "name": "kindnet-cni", + "name": "coredns", "status": { "phase": "running", "ready": true, @@ -59,72 +54,33 @@ { "RootFields": { "container": { - "id": "a55ee307ef431d293c02a7eb96417963d7b81b298a8ebfac2f77fe4ca58e1461", + "id": "ffdc200c097349d8ed96f5768387d276751497297730121e6335a31c2d3332a4", "image": { - "name": "k8s.gcr.io/kube-proxy:v1.16.15" + "name": "k8s.gcr.io/kube-apiserver:v1.16.15" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" }, "pod": { - "name": "kube-proxy-cm525" + "name": "kube-apiserver-kind-control-plane" } }, "MetricSetFields": { - "id": "containerd://a55ee307ef431d293c02a7eb96417963d7b81b298a8ebfac2f77fe4ca58e1461", - "name": "kube-proxy", + "cpu": { + "request": { + "cores": 0.25 + } + }, + "id": "containerd://ffdc200c097349d8ed96f5768387d276751497297730121e6335a31c2d3332a4", + "name": "kube-apiserver", "status": { "phase": "running", "ready": true, - "restarts": 4 - } - }, - "Index": "", - "ID": "", - "Namespace": "kubernetes.container", - "Timestamp": "0001-01-01T00:00:00Z", - "Error": null, - "Host": "", - "Service": "", - "Took": 0, - "Period": 0, - "DisableTimeSeries": false - }, - { - "RootFields": { - "container": { - "id": "a84953a247df489898d85ecfd0f893c2655ed1915ac902b309ee6e3658c7e258", - "image": { - "name": "docker.io/library/busybox:latest" - }, - "runtime": "containerd" - } - }, - "ModuleFields": { - "namespace": { - "name": "default" - }, - "node": { - "name": "kind-worker" - }, - "pod": { - "name": "hello-zf6gh" - } - }, - "MetricSetFields": { - "id": "containerd://a84953a247df489898d85ecfd0f893c2655ed1915ac902b309ee6e3658c7e258", - "name": "hello", - "status": { - "phase": "terminated", - "ready": false, - "reason": "Completed", "restarts": 0 } }, @@ -150,9 +106,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-worker2" }, @@ -183,32 +137,25 @@ { "RootFields": { "container": { - "id": "1c1919c3b07bf3369b5e1a4bf187762f2724b3bc7eb113239af3919f12202337", + "id": "8af6de6644ef1e5bb36b9d1f87d65e9b893096ae2c0f3e57061fad70f094d1be", "image": { - "name": "k8s.gcr.io/kube-controller-manager:v1.16.15" + "name": "k8s.gcr.io/kube-proxy:v1.16.15" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker" }, "pod": { - "name": "kube-controller-manager-kind-control-plane" + "name": "kube-proxy-22znl" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.2 - } - }, - "id": "containerd://1c1919c3b07bf3369b5e1a4bf187762f2724b3bc7eb113239af3919f12202337", - "name": "kube-controller-manager", + "id": "containerd://8af6de6644ef1e5bb36b9d1f87d65e9b893096ae2c0f3e57061fad70f094d1be", + "name": "kube-proxy", "status": { "phase": "running", "ready": true, @@ -229,31 +176,29 @@ { "RootFields": { "container": { - "id": "8af6de6644ef1e5bb36b9d1f87d65e9b893096ae2c0f3e57061fad70f094d1be", + "id": "02b0705f60dc6131a6b5d4e9a48e2510463f89a0f77e7e1bafa6b5f45cc595e8", "image": { - "name": "k8s.gcr.io/kube-proxy:v1.16.15" + "name": "docker.io/odise/busybox-python:latest" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "kind-worker" }, "pod": { - "name": "kube-proxy-22znl" + "name": "hello-python-566b5479f5-ndwdl" } }, "MetricSetFields": { - "id": "containerd://8af6de6644ef1e5bb36b9d1f87d65e9b893096ae2c0f3e57061fad70f094d1be", - "name": "kube-proxy", + "id": "containerd://02b0705f60dc6131a6b5d4e9a48e2510463f89a0f77e7e1bafa6b5f45cc595e8", + "name": "hello-python", "status": { "phase": "running", "ready": true, - "restarts": 4 + "restarts": 18 } }, "Index": "", @@ -270,7 +215,7 @@ { "RootFields": { "container": { - "id": "9afadbf7fd5374d1849b008e8ad4287cdbfbbf499bab9740bf0c7a5cd6730ad9", + "id": "09603a8146bd6aacb32d55a1e52e929143f003ea30c84052f765efca129fd90a", "image": { "name": "docker.io/kindest/kindnetd:v20210326-1e038dc5" }, @@ -278,14 +223,12 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker" + "name": "kind-control-plane" }, "pod": { - "name": "kindnet-9fgst" + "name": "kindnet-kch2v" } }, "MetricSetFields": { @@ -297,7 +240,7 @@ "cores": 0.1 } }, - "id": "containerd://9afadbf7fd5374d1849b008e8ad4287cdbfbbf499bab9740bf0c7a5cd6730ad9", + "id": "containerd://09603a8146bd6aacb32d55a1e52e929143f003ea30c84052f765efca129fd90a", "memory": { "limit": { "bytes": 52428800 @@ -327,39 +270,34 @@ { "RootFields": { "container": { - "id": "fae8ef6fa6ea716f5ce0a65a1b2407d1e4839b04452d6013cdb6d5be8db8ada0", + "id": "cd368e1731c278b039642fab2fe90902e2cfa470fd70a7ccfd5c2549a552cea5", "image": { - "name": "docker.io/library/redis:5.0.4" + "name": "k8s.gcr.io/kube-scheduler:v1.16.15" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-control-plane" }, "pod": { - "name": "redis" + "name": "kube-scheduler-kind-control-plane" } }, "MetricSetFields": { "cpu": { - "limit": { - "cores": 0.1 - }, "request": { "cores": 0.1 } }, - "id": "containerd://fae8ef6fa6ea716f5ce0a65a1b2407d1e4839b04452d6013cdb6d5be8db8ada0", - "name": "redis", + "id": "containerd://cd368e1731c278b039642fab2fe90902e2cfa470fd70a7ccfd5c2549a552cea5", + "name": "kube-scheduler", "status": { "phase": "running", "ready": true, - "restarts": 1 + "restarts": 4 } }, "Index": "", @@ -376,36 +314,29 @@ { "RootFields": { "container": { - "id": "cd368e1731c278b039642fab2fe90902e2cfa470fd70a7ccfd5c2549a552cea5", + "id": "1a223dbb8b51a7404836789fd049701a9e4df7bb69878fb893ab10419ff4eb29", "image": { - "name": "k8s.gcr.io/kube-scheduler:v1.16.15" + "name": "docker.io/rancher/local-path-provisioner:v0.0.14" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "local-path-storage", "node": { "name": "kind-control-plane" }, "pod": { - "name": "kube-scheduler-kind-control-plane" + "name": "local-path-provisioner-5bf465b47d-h8hjn" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.1 - } - }, - "id": "containerd://cd368e1731c278b039642fab2fe90902e2cfa470fd70a7ccfd5c2549a552cea5", - "name": "kube-scheduler", + "id": "containerd://1a223dbb8b51a7404836789fd049701a9e4df7bb69878fb893ab10419ff4eb29", + "name": "local-path-provisioner", "status": { "phase": "running", "ready": true, - "restarts": 4 + "restarts": 8 } }, "Index": "", @@ -422,7 +353,7 @@ { "RootFields": { "container": { - "id": "90560da422742a41de53c281969942c25f24d7b6bf73af6e4f226ee62338f640", + "id": "d66f649ad0f6c1822039f1c4ea27b6f792f6a86029bf862e77afa2966042a1ce", "image": { "name": "docker.elastic.co/beats/metricbeat:7.15.0-SNAPSHOT" }, @@ -430,14 +361,12 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker" + "name": "kind-worker2" }, "pod": { - "name": "metricbeat-bvr2v" + "name": "metricbeat-55fp7" } }, "MetricSetFields": { @@ -446,7 +375,7 @@ "cores": 0.1 } }, - "id": "containerd://90560da422742a41de53c281969942c25f24d7b6bf73af6e4f226ee62338f640", + "id": "containerd://d66f649ad0f6c1822039f1c4ea27b6f792f6a86029bf862e77afa2966042a1ce", "memory": { "limit": { "bytes": 209715200 @@ -484,9 +413,7 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" }, @@ -530,31 +457,37 @@ { "RootFields": { "container": { - "id": "3f9250f160ca15f681b8c7da78fdf34cd8be8a86fde3910b682ad413b940a8c5", + "id": "fae8ef6fa6ea716f5ce0a65a1b2407d1e4839b04452d6013cdb6d5be8db8ada0", "image": { - "name": "k8s.gcr.io/etcd:3.3.15-0" + "name": "docker.io/library/redis:5.0.4" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { - "name": "kind-control-plane" + "name": "kind-worker2" }, "pod": { - "name": "etcd-kind-control-plane" + "name": "redis" } }, "MetricSetFields": { - "id": "containerd://3f9250f160ca15f681b8c7da78fdf34cd8be8a86fde3910b682ad413b940a8c5", - "name": "etcd", + "cpu": { + "limit": { + "cores": 0.1 + }, + "request": { + "cores": 0.1 + } + }, + "id": "containerd://fae8ef6fa6ea716f5ce0a65a1b2407d1e4839b04452d6013cdb6d5be8db8ada0", + "name": "redis", "status": { "phase": "running", "ready": true, - "restarts": 0 + "restarts": 1 } }, "Index": "", @@ -571,36 +504,45 @@ { "RootFields": { "container": { - "id": "ffdc200c097349d8ed96f5768387d276751497297730121e6335a31c2d3332a4", + "id": "9afadbf7fd5374d1849b008e8ad4287cdbfbbf499bab9740bf0c7a5cd6730ad9", "image": { - "name": "k8s.gcr.io/kube-apiserver:v1.16.15" + "name": "docker.io/kindest/kindnetd:v20210326-1e038dc5" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker" }, "pod": { - "name": "kube-apiserver-kind-control-plane" + "name": "kindnet-9fgst" } }, "MetricSetFields": { "cpu": { + "limit": { + "cores": 0.1 + }, "request": { - "cores": 0.25 + "cores": 0.1 } }, - "id": "containerd://ffdc200c097349d8ed96f5768387d276751497297730121e6335a31c2d3332a4", - "name": "kube-apiserver", + "id": "containerd://9afadbf7fd5374d1849b008e8ad4287cdbfbbf499bab9740bf0c7a5cd6730ad9", + "memory": { + "limit": { + "bytes": 52428800 + }, + "request": { + "bytes": 52428800 + } + }, + "name": "kindnet-cni", "status": { "phase": "running", "ready": true, - "restarts": 0 + "restarts": 4 } }, "Index": "", @@ -617,44 +559,29 @@ { "RootFields": { "container": { - "id": "3101d1525d6133851881f4b7cd439033663daefeb4849e5322d1428f09620628", + "id": "ae513b826459c9382984bea986eb3546aa45fd0e650051cb9591ab7a8efed6ea", "image": { - "name": "k8s.gcr.io/coredns:1.6.2" + "name": "k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.1.0" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker" }, "pod": { - "name": "coredns-5644d7b6d9-zgdsx" + "name": "kube-state-metrics-f655d484d-hj69w" } }, "MetricSetFields": { - "cpu": { - "request": { - "cores": 0.1 - } - }, - "id": "containerd://3101d1525d6133851881f4b7cd439033663daefeb4849e5322d1428f09620628", - "memory": { - "limit": { - "bytes": 178257920 - }, - "request": { - "bytes": 73400320 - } - }, - "name": "coredns", + "id": "containerd://ae513b826459c9382984bea986eb3546aa45fd0e650051cb9591ab7a8efed6ea", + "name": "kube-state-metrics", "status": { "phase": "running", "ready": true, - "restarts": 4 + "restarts": 2 } }, "Index": "", @@ -671,7 +598,7 @@ { "RootFields": { "container": { - "id": "d66f649ad0f6c1822039f1c4ea27b6f792f6a86029bf862e77afa2966042a1ce", + "id": "90560da422742a41de53c281969942c25f24d7b6bf73af6e4f226ee62338f640", "image": { "name": "docker.elastic.co/beats/metricbeat:7.15.0-SNAPSHOT" }, @@ -679,14 +606,12 @@ } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-worker" }, "pod": { - "name": "metricbeat-55fp7" + "name": "metricbeat-bvr2v" } }, "MetricSetFields": { @@ -695,7 +620,7 @@ "cores": 0.1 } }, - "id": "containerd://d66f649ad0f6c1822039f1c4ea27b6f792f6a86029bf862e77afa2966042a1ce", + "id": "containerd://90560da422742a41de53c281969942c25f24d7b6bf73af6e4f226ee62338f640", "memory": { "limit": { "bytes": 209715200 @@ -725,31 +650,30 @@ { "RootFields": { "container": { - "id": "ae513b826459c9382984bea986eb3546aa45fd0e650051cb9591ab7a8efed6ea", + "id": "a84953a247df489898d85ecfd0f893c2655ed1915ac902b309ee6e3658c7e258", "image": { - "name": "k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.1.0" + "name": "docker.io/library/busybox:latest" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "kind-worker" }, "pod": { - "name": "kube-state-metrics-f655d484d-hj69w" + "name": "hello-zf6gh" } }, "MetricSetFields": { - "id": "containerd://ae513b826459c9382984bea986eb3546aa45fd0e650051cb9591ab7a8efed6ea", - "name": "kube-state-metrics", + "id": "containerd://a84953a247df489898d85ecfd0f893c2655ed1915ac902b309ee6e3658c7e258", + "name": "hello", "status": { - "phase": "running", - "ready": true, - "restarts": 2 + "phase": "terminated", + "ready": false, + "reason": "Completed", + "restarts": 0 } }, "Index": "", @@ -766,43 +690,25 @@ { "RootFields": { "container": { - "id": "09603a8146bd6aacb32d55a1e52e929143f003ea30c84052f765efca129fd90a", + "id": "a55ee307ef431d293c02a7eb96417963d7b81b298a8ebfac2f77fe4ca58e1461", "image": { - "name": "docker.io/kindest/kindnetd:v20210326-1e038dc5" + "name": "k8s.gcr.io/kube-proxy:v1.16.15" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" }, "pod": { - "name": "kindnet-kch2v" + "name": "kube-proxy-cm525" } }, "MetricSetFields": { - "cpu": { - "limit": { - "cores": 0.1 - }, - "request": { - "cores": 0.1 - } - }, - "id": "containerd://09603a8146bd6aacb32d55a1e52e929143f003ea30c84052f765efca129fd90a", - "memory": { - "limit": { - "bytes": 52428800 - }, - "request": { - "bytes": 52428800 - } - }, - "name": "kindnet-cni", + "id": "containerd://a55ee307ef431d293c02a7eb96417963d7b81b298a8ebfac2f77fe4ca58e1461", + "name": "kube-proxy", "status": { "phase": "running", "ready": true, @@ -823,31 +729,29 @@ { "RootFields": { "container": { - "id": "02b0705f60dc6131a6b5d4e9a48e2510463f89a0f77e7e1bafa6b5f45cc595e8", + "id": "3f9250f160ca15f681b8c7da78fdf34cd8be8a86fde3910b682ad413b940a8c5", "image": { - "name": "docker.io/odise/busybox-python:latest" + "name": "k8s.gcr.io/etcd:3.3.15-0" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker" + "name": "kind-control-plane" }, "pod": { - "name": "hello-python-566b5479f5-ndwdl" + "name": "etcd-kind-control-plane" } }, "MetricSetFields": { - "id": "containerd://02b0705f60dc6131a6b5d4e9a48e2510463f89a0f77e7e1bafa6b5f45cc595e8", - "name": "hello-python", + "id": "containerd://3f9250f160ca15f681b8c7da78fdf34cd8be8a86fde3910b682ad413b940a8c5", + "name": "etcd", "status": { "phase": "running", "ready": true, - "restarts": 18 + "restarts": 0 } }, "Index": "", @@ -864,31 +768,89 @@ { "RootFields": { "container": { - "id": "1a223dbb8b51a7404836789fd049701a9e4df7bb69878fb893ab10419ff4eb29", + "id": "3037e577635e9cbcefe1f273e5b06784d36807af76158e4add887e840c42e1ef", "image": { - "name": "docker.io/rancher/local-path-provisioner:v0.0.14" + "name": "docker.io/kindest/kindnetd:v20210326-1e038dc5" }, "runtime": "containerd" } }, "ModuleFields": { - "namespace": { - "name": "local-path-storage" + "namespace": "kube-system", + "node": { + "name": "kind-worker2" + }, + "pod": { + "name": "kindnet-tg7tl" + } + }, + "MetricSetFields": { + "cpu": { + "limit": { + "cores": 0.1 + }, + "request": { + "cores": 0.1 + } }, + "id": "containerd://3037e577635e9cbcefe1f273e5b06784d36807af76158e4add887e840c42e1ef", + "memory": { + "limit": { + "bytes": 52428800 + }, + "request": { + "bytes": 52428800 + } + }, + "name": "kindnet-cni", + "status": { + "phase": "running", + "ready": true, + "restarts": 4 + } + }, + "Index": "", + "ID": "", + "Namespace": "kubernetes.container", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "1c1919c3b07bf3369b5e1a4bf187762f2724b3bc7eb113239af3919f12202337", + "image": { + "name": "k8s.gcr.io/kube-controller-manager:v1.16.15" + }, + "runtime": "containerd" + } + }, + "ModuleFields": { + "namespace": "kube-system", "node": { "name": "kind-control-plane" }, "pod": { - "name": "local-path-provisioner-5bf465b47d-h8hjn" + "name": "kube-controller-manager-kind-control-plane" } }, "MetricSetFields": { - "id": "containerd://1a223dbb8b51a7404836789fd049701a9e4df7bb69878fb893ab10419ff4eb29", - "name": "local-path-provisioner", + "cpu": { + "request": { + "cores": 0.2 + } + }, + "id": "containerd://1c1919c3b07bf3369b5e1a4bf187762f2724b3bc7eb113239af3919f12202337", + "name": "kube-controller-manager", "status": { "phase": "running", "ready": true, - "restarts": 8 + "restarts": 4 } }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_container/_meta/testdata/ksm-v1_3_0.plain-expected.json b/metricbeat/module/kubernetes/state_container/_meta/testdata/ksm-v1_3_0.plain-expected.json index a38d8487d344..91d3176317dc 100644 --- a/metricbeat/module/kubernetes/state_container/_meta/testdata/ksm-v1_3_0.plain-expected.json +++ b/metricbeat/module/kubernetes/state_container/_meta/testdata/ksm-v1_3_0.plain-expected.json @@ -1,9 +1,9 @@ [ { "container": { - "id": "52fa55e051dc5b68e44c027588685b7edd85aaa03b07f7216d399249ff4fc821", + "id": "469f5d2b7854eb52e5d13dc0cd3e664c1b682b157aabaf596ffe4984f1516902", "image": { - "name": "gcr.io/google_containers/exechealthz-amd64:1.2" + "name": "gcr.io/kubernetes-helm/tiller:v2.3.1" }, "runtime": "docker" }, @@ -14,35 +14,20 @@ }, "kubernetes": { "container": { - "cpu": { - "request": { - "cores": 0.01 - } - }, - "id": "docker://52fa55e051dc5b68e44c027588685b7edd85aaa03b07f7216d399249ff4fc821", - "memory": { - "limit": { - "bytes": 52428800 - }, - "request": { - "bytes": 52428800 - } - }, - "name": "healthz", + "id": "docker://469f5d2b7854eb52e5d13dc0cd3e664c1b682b157aabaf596ffe4984f1516902", + "name": "tiller", "status": { "phase": "running", "ready": true, - "restarts": 2 + "restarts": 1 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-dns-v20-5g5cb" + "name": "tiller-deploy-3067024529-9lpmb" } }, "metricset": { @@ -56,9 +41,9 @@ }, { "container": { - "id": "fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62", + "id": "3aaee8bdd311c015240e99fa2a5a5f2f26b11b51236a683b39d8c1902e423978", "image": { - "name": "gcr.io/google_containers/kubedns-amd64:1.9" + "name": "gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.1" }, "runtime": "docker" }, @@ -69,35 +54,20 @@ }, "kubernetes": { "container": { - "cpu": { - "request": { - "cores": 0.1 - } - }, - "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62", - "memory": { - "limit": { - "bytes": 178257920 - }, - "request": { - "bytes": 73400320 - } - }, - "name": "kubedns", + "id": "docker://3aaee8bdd311c015240e99fa2a5a5f2f26b11b51236a683b39d8c1902e423978", + "name": "kubernetes-dashboard", "status": { "phase": "running", "ready": true, "restarts": 2 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-dns-v20-5g5cb" + "name": "kubernetes-dashboard-vw0l6" } }, "metricset": { @@ -110,13 +80,6 @@ } }, { - "container": { - "id": "91fdd43f6b1b4c3dd133cfca53e0b1210bc557c2ae56006026b5ccdb5f52826f", - "image": { - "name": "gcr.io/google-containers/kube-addon-manager:v6.3" - }, - "runtime": "docker" - }, "event": { "dataset": "kubernetes.container", "duration": 115000, @@ -125,31 +88,26 @@ "kubernetes": { "container": { "cpu": { + "limit": { + "cores": 0.2 + }, "request": { - "cores": 0.005 + "cores": 0.1 } }, - "id": "docker://91fdd43f6b1b4c3dd133cfca53e0b1210bc557c2ae56006026b5ccdb5f52826f", "memory": { - "request": { + "limit": { "bytes": 52428800 + }, + "request": { + "bytes": 31457280 } }, - "name": "kube-addon-manager", - "status": { - "phase": "running", - "ready": true, - "restarts": 2 - } - }, - "namespace": { - "name": "kube-system" - }, - "node": { - "name": "minikube" + "name": "kube-state-metrics" }, + "namespace": "kube-system", "pod": { - "name": "kube-addon-manager-minikube" + "name": "kube-state-metrics-1303537707-mnzbp" } }, "metricset": { @@ -163,9 +121,9 @@ }, { "container": { - "id": "3aaee8bdd311c015240e99fa2a5a5f2f26b11b51236a683b39d8c1902e423978", + "id": "973cbe45982c5126a5caf8c58d964c0ab1d5bb2c165ccc59715fcc1ebd58ab3d", "image": { - "name": "gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.1" + "name": "gcr.io/google_containers/kube-state-metrics:v0.4.1" }, "runtime": "docker" }, @@ -176,22 +134,36 @@ }, "kubernetes": { "container": { - "id": "docker://3aaee8bdd311c015240e99fa2a5a5f2f26b11b51236a683b39d8c1902e423978", - "name": "kubernetes-dashboard", + "cpu": { + "limit": { + "cores": 0.2 + }, + "request": { + "cores": 0.1 + } + }, + "id": "docker://973cbe45982c5126a5caf8c58d964c0ab1d5bb2c165ccc59715fcc1ebd58ab3d", + "memory": { + "limit": { + "bytes": 52428800 + }, + "request": { + "bytes": 31457280 + } + }, + "name": "kube-state-metrics", "status": { "phase": "running", "ready": true, - "restarts": 2 + "restarts": 1 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kubernetes-dashboard-vw0l6" + "name": "kube-state-metrics-1303537707-7ncd1" } }, "metricset": { @@ -205,9 +177,9 @@ }, { "container": { - "id": "fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test", + "id": "e2ee1c2c7b8d4e5fd8c834b83cba8377d6b0e39da18157688ccc1a06b7c53117", "image": { - "name": "gcr.io/google_containers/kubedns-amd64:1.9-test" + "name": "jenkinsci/jenkins:2.46.1" }, "runtime": "docker" }, @@ -223,30 +195,25 @@ "cores": 0.2 } }, - "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test", + "id": "docker://e2ee1c2c7b8d4e5fd8c834b83cba8377d6b0e39da18157688ccc1a06b7c53117", "memory": { - "limit": { - "bytes": 278257920 - }, "request": { - "bytes": 83400320 + "bytes": 268435456 } }, - "name": "kubedns", + "name": "wise-lynx-jenkins", "status": { - "phase": "terminated", - "ready": false, - "restarts": 3 + "phase": "running", + "ready": true, + "restarts": 1 } }, - "namespace": { - "name": "test" - }, + "namespace": "jenkins", "node": { - "name": "minikube-test" + "name": "minikube" }, "pod": { - "name": "kube-dns-v20-5g5cb-test" + "name": "wise-lynx-jenkins-1616735317-svn6k" } }, "metricset": { @@ -260,9 +227,9 @@ }, { "container": { - "id": "e2ee1c2c7b8d4e5fd8c834b83cba8377d6b0e39da18157688ccc1a06b7c53117", + "id": "fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62", "image": { - "name": "jenkinsci/jenkins:2.46.1" + "name": "gcr.io/google_containers/kubedns-amd64:1.9" }, "runtime": "docker" }, @@ -275,30 +242,31 @@ "container": { "cpu": { "request": { - "cores": 0.2 + "cores": 0.1 } }, - "id": "docker://e2ee1c2c7b8d4e5fd8c834b83cba8377d6b0e39da18157688ccc1a06b7c53117", + "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62", "memory": { + "limit": { + "bytes": 178257920 + }, "request": { - "bytes": 268435456 + "bytes": 73400320 } }, - "name": "wise-lynx-jenkins", + "name": "kubedns", "status": { "phase": "running", "ready": true, - "restarts": 1 + "restarts": 2 } }, - "namespace": { - "name": "jenkins" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "wise-lynx-jenkins-1616735317-svn6k" + "name": "kube-dns-v20-5g5cb" } }, "metricset": { @@ -311,6 +279,13 @@ } }, { + "container": { + "id": "4fa227874ee68536bf902394fb662f07b99099798ca9cd5c1506b79075acc065", + "image": { + "name": "bitnami/redis:3.2.8-r2" + }, + "runtime": "docker" + }, "event": { "dataset": "kubernetes.container", "duration": 115000, @@ -319,28 +294,29 @@ "kubernetes": { "container": { "cpu": { - "limit": { - "cores": 0.2 - }, "request": { "cores": 0.1 } }, + "id": "docker://4fa227874ee68536bf902394fb662f07b99099798ca9cd5c1506b79075acc065", "memory": { - "limit": { - "bytes": 52428800 - }, "request": { - "bytes": 31457280 + "bytes": 268435456 } }, - "name": "kube-state-metrics" + "name": "jumpy-owl-redis", + "status": { + "phase": "waiting", + "ready": false, + "restarts": 270 + } }, - "namespace": { - "name": "kube-system" + "namespace": "default", + "node": { + "name": "minikube" }, "pod": { - "name": "kube-state-metrics-1303537707-mnzbp" + "name": "jumpy-owl-redis-3481028193-s78x9" } }, "metricset": { @@ -354,9 +330,9 @@ }, { "container": { - "id": "9a4c9462cd078d7be4f0a9b94bcfeb69d5fdd76bff67142df3f58367ac7e8d61", + "id": "fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test", "image": { - "name": "gcr.io/google_containers/kube-dnsmasq-amd64:1.4" + "name": "gcr.io/google_containers/kubedns-amd64:1.9-test" }, "runtime": "docker" }, @@ -367,22 +343,33 @@ }, "kubernetes": { "container": { - "id": "docker://9a4c9462cd078d7be4f0a9b94bcfeb69d5fdd76bff67142df3f58367ac7e8d61", - "name": "dnsmasq", + "cpu": { + "request": { + "cores": 0.2 + } + }, + "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test", + "memory": { + "limit": { + "bytes": 278257920 + }, + "request": { + "bytes": 83400320 + } + }, + "name": "kubedns", "status": { - "phase": "running", - "ready": true, - "restarts": 2 + "phase": "terminated", + "ready": false, + "restarts": 3 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "test", "node": { - "name": "minikube" + "name": "minikube-test" }, "pod": { - "name": "kube-dns-v20-5g5cb" + "name": "kube-dns-v20-5g5cb-test" } }, "metricset": { @@ -396,9 +383,9 @@ }, { "container": { - "id": "973cbe45982c5126a5caf8c58d964c0ab1d5bb2c165ccc59715fcc1ebd58ab3d", + "id": "91fdd43f6b1b4c3dd133cfca53e0b1210bc557c2ae56006026b5ccdb5f52826f", "image": { - "name": "gcr.io/google_containers/kube-state-metrics:v0.4.1" + "name": "gcr.io/google-containers/kube-addon-manager:v6.3" }, "runtime": "docker" }, @@ -410,37 +397,29 @@ "kubernetes": { "container": { "cpu": { - "limit": { - "cores": 0.2 - }, "request": { - "cores": 0.1 + "cores": 0.005 } }, - "id": "docker://973cbe45982c5126a5caf8c58d964c0ab1d5bb2c165ccc59715fcc1ebd58ab3d", + "id": "docker://91fdd43f6b1b4c3dd133cfca53e0b1210bc557c2ae56006026b5ccdb5f52826f", "memory": { - "limit": { - "bytes": 52428800 - }, "request": { - "bytes": 31457280 + "bytes": 52428800 } }, - "name": "kube-state-metrics", + "name": "kube-addon-manager", "status": { "phase": "running", "ready": true, - "restarts": 1 + "restarts": 2 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "kube-state-metrics-1303537707-7ncd1" + "name": "kube-addon-manager-minikube" } }, "metricset": { @@ -454,9 +433,9 @@ }, { "container": { - "id": "4fa227874ee68536bf902394fb662f07b99099798ca9cd5c1506b79075acc065", + "id": "52fa55e051dc5b68e44c027588685b7edd85aaa03b07f7216d399249ff4fc821", "image": { - "name": "bitnami/redis:3.2.8-r2" + "name": "gcr.io/google_containers/exechealthz-amd64:1.2" }, "runtime": "docker" }, @@ -469,30 +448,31 @@ "container": { "cpu": { "request": { - "cores": 0.1 + "cores": 0.01 } }, - "id": "docker://4fa227874ee68536bf902394fb662f07b99099798ca9cd5c1506b79075acc065", + "id": "docker://52fa55e051dc5b68e44c027588685b7edd85aaa03b07f7216d399249ff4fc821", "memory": { + "limit": { + "bytes": 52428800 + }, "request": { - "bytes": 268435456 + "bytes": 52428800 } }, - "name": "jumpy-owl-redis", + "name": "healthz", "status": { - "phase": "waiting", - "ready": false, - "restarts": 270 + "phase": "running", + "ready": true, + "restarts": 2 } }, - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "jumpy-owl-redis-3481028193-s78x9" + "name": "kube-dns-v20-5g5cb" } }, "metricset": { @@ -506,9 +486,9 @@ }, { "container": { - "id": "469f5d2b7854eb52e5d13dc0cd3e664c1b682b157aabaf596ffe4984f1516902", + "id": "9a4c9462cd078d7be4f0a9b94bcfeb69d5fdd76bff67142df3f58367ac7e8d61", "image": { - "name": "gcr.io/kubernetes-helm/tiller:v2.3.1" + "name": "gcr.io/google_containers/kube-dnsmasq-amd64:1.4" }, "runtime": "docker" }, @@ -519,22 +499,20 @@ }, "kubernetes": { "container": { - "id": "docker://469f5d2b7854eb52e5d13dc0cd3e664c1b682b157aabaf596ffe4984f1516902", - "name": "tiller", + "id": "docker://9a4c9462cd078d7be4f0a9b94bcfeb69d5fdd76bff67142df3f58367ac7e8d61", + "name": "dnsmasq", "status": { "phase": "running", "ready": true, - "restarts": 1 + "restarts": 2 } }, - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { - "name": "tiller-deploy-3067024529-9lpmb" + "name": "kube-dns-v20-5g5cb" } }, "metricset": { diff --git a/metricbeat/module/kubernetes/state_container/state_container.go b/metricbeat/module/kubernetes/state_container/state_container.go index 56ab2d8adac8..23c34bf040fa 100644 --- a/metricbeat/module/kubernetes/state_container/state_container.go +++ b/metricbeat/module/kubernetes/state_container/state_container.go @@ -78,7 +78,7 @@ var ( Labels: map[string]p.LabelMap{ "pod": p.KeyLabel(mb.ModuleDataKey + ".pod.name"), "container": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "node": p.Label(mb.ModuleDataKey + ".node.name"), "container_id": p.Label("id"), diff --git a/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v1.8.0.expected index 35dea56dcff7..926f896d1126 100644 --- a/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v1.8.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "active": { diff --git a/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v2.0.0.expected index aedf4d80e847..0702ef4cfe2a 100644 --- a/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_cronjob/_meta/test/ksm.v2.0.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "active": { diff --git a/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go b/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go index ffed1e92b677..272dc58aca6a 100644 --- a/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go +++ b/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go @@ -74,7 +74,7 @@ func NewCronJobMetricSet(base mb.BaseMetricSet) (mb.MetricSet, error) { }, Labels: map[string]p.LabelMap{ "cronjob": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "schedule": p.KeyLabel("schedule"), "concurrency_policy": p.KeyLabel("concurrency"), }, diff --git a/metricbeat/module/kubernetes/state_daemonset/_meta/data.json b/metricbeat/module/kubernetes/state_daemonset/_meta/data.json index 158d2a34eeb1..5856069d5686 100644 --- a/metricbeat/module/kubernetes/state_daemonset/_meta/data.json +++ b/metricbeat/module/kubernetes/state_daemonset/_meta/data.json @@ -7,7 +7,7 @@ }, "kubernetes": { "daemonset": { - "name": "kindnet", + "name": "kube-proxy", "replicas": { "available": 1, "desired": 1, @@ -15,9 +15,7 @@ "unavailable": 0 } }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "metricset": { "name": "state_daemonset", diff --git a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.3.0.expected index 73dfd269be2c..93e2d068788d 100644 --- a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.3.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "name": "kube-proxy", diff --git a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.8.0.expected index 73dfd269be2c..93e2d068788d 100644 --- a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v1.8.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "name": "kube-proxy", diff --git a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v2.0.0.expected index ff94aebc50a2..fbb6670ecd74 100644 --- a/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_daemonset/_meta/test/ksm.v2.0.0.expected @@ -2,12 +2,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kindnet", + "name": "kube-proxy", "replicas": { "available": 3, "desired": 3, @@ -29,16 +27,14 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-proxy", + "name": "metricbeat", "replicas": { - "available": 3, - "desired": 3, - "ready": 3, + "available": 2, + "desired": 2, + "ready": 2, "unavailable": 0 } }, @@ -56,16 +52,14 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "metricbeat", + "name": "kindnet", "replicas": { - "available": 2, - "desired": 2, - "ready": 2, + "available": 3, + "desired": 3, + "ready": 3, "unavailable": 0 } }, diff --git a/metricbeat/module/kubernetes/state_daemonset/_meta/testdata/docs.plain-expected.json b/metricbeat/module/kubernetes/state_daemonset/_meta/testdata/docs.plain-expected.json index a95bd894fb0c..9768d8d39281 100644 --- a/metricbeat/module/kubernetes/state_daemonset/_meta/testdata/docs.plain-expected.json +++ b/metricbeat/module/kubernetes/state_daemonset/_meta/testdata/docs.plain-expected.json @@ -7,7 +7,7 @@ }, "kubernetes": { "daemonset": { - "name": "kindnet", + "name": "kube-proxy", "replicas": { "available": 1, "desired": 1, @@ -15,9 +15,7 @@ "unavailable": 0 } }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "metricset": { "name": "state_daemonset", @@ -36,7 +34,7 @@ }, "kubernetes": { "daemonset": { - "name": "kube-proxy", + "name": "kindnet", "replicas": { "available": 1, "desired": 1, @@ -44,9 +42,7 @@ "unavailable": 0 } }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "metricset": { "name": "state_daemonset", diff --git a/metricbeat/module/kubernetes/state_daemonset/state_daemonset.go b/metricbeat/module/kubernetes/state_daemonset/state_daemonset.go index 95e580744b12..1066afa21959 100644 --- a/metricbeat/module/kubernetes/state_daemonset/state_daemonset.go +++ b/metricbeat/module/kubernetes/state_daemonset/state_daemonset.go @@ -50,7 +50,7 @@ var ( Labels: map[string]p.LabelMap{ "daemonset": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), }, } ) diff --git a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.3.0.expected index fa3dbf2df802..b2dce0071463 100644 --- a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.3.0.expected @@ -2,12 +2,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-dns", + "name": "kube-state-metrics", "paused": false, "replicas": { "available": 1, @@ -30,9 +28,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "name": "kubernetes-dashboard", @@ -58,12 +54,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-state-metrics", + "name": "kube-dns", "paused": false, "replicas": { "available": 1, diff --git a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.8.0.expected index b83cb15d7fd0..3f1255e36c6b 100644 --- a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v1.8.0.expected @@ -2,18 +2,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "coredns", + "name": "kube-state-metrics", "paused": false, "replicas": { - "available": 2, - "desired": 2, + "available": 1, + "desired": 1, "unavailable": 0, - "updated": 2 + "updated": 1 } }, "Index": "", @@ -30,18 +28,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-state-metrics", + "name": "coredns", "paused": false, "replicas": { - "available": 1, - "desired": 1, + "available": 2, + "desired": 2, "unavailable": 0, - "updated": 1 + "updated": 2 } }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v2.0.0.expected index 5f0b8c206891..de439f143865 100644 --- a/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_deployment/_meta/test/ksm.v2.0.0.expected @@ -2,18 +2,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "coredns", + "name": "kube-state-metrics", "paused": false, "replicas": { - "available": 2, - "desired": 2, + "available": 1, + "desired": 1, "unavailable": 0, - "updated": 2 + "updated": 1 } }, "Index": "", @@ -30,9 +28,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "local-path-storage" - } + "namespace": "local-path-storage" }, "MetricSetFields": { "name": "local-path-provisioner", @@ -58,12 +54,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "default" }, "MetricSetFields": { - "name": "kube-state-metrics", + "name": "hello-python", "paused": false, "replicas": { "available": 1, @@ -86,18 +80,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "hello-python", + "name": "coredns", "paused": false, "replicas": { - "available": 1, - "desired": 1, + "available": 2, + "desired": 2, "unavailable": 0, - "updated": 1 + "updated": 2 } }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.3.0.plain-expected.json b/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.3.0.plain-expected.json index fabdb0fabb03..19faf98a4ce3 100644 --- a/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.3.0.plain-expected.json +++ b/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.3.0.plain-expected.json @@ -7,18 +7,16 @@ }, "kubernetes": { "deployment": { - "name": "jumpy-owl-redis", - "paused": true, + "name": "tiller-deploy", + "paused": false, "replicas": { - "available": 6, - "desired": 2, - "unavailable": 7, - "updated": 8 + "available": 1, + "desired": 1, + "unavailable": 0, + "updated": 1 } }, - "namespace": { - "name": "test" - } + "namespace": "kube-system" }, "metricset": { "name": "state_deployment", @@ -37,18 +35,16 @@ }, "kubernetes": { "deployment": { - "name": "kube-state-metrics", + "name": "wise-lynx-jenkins", "paused": false, "replicas": { "available": 1, - "desired": 2, - "unavailable": 1, - "updated": 2 + "desired": 1, + "unavailable": 0, + "updated": 1 } }, - "namespace": { - "name": "kube-system" - } + "namespace": "jenkins" }, "metricset": { "name": "state_deployment", @@ -68,17 +64,15 @@ "kubernetes": { "deployment": { "name": "jumpy-owl-redis", - "paused": false, + "paused": true, "replicas": { - "available": 0, - "desired": 1, - "unavailable": 1, - "updated": 1 + "available": 6, + "desired": 2, + "unavailable": 7, + "updated": 8 } }, - "namespace": { - "name": "default" - } + "namespace": "test" }, "metricset": { "name": "state_deployment", @@ -97,18 +91,16 @@ }, "kubernetes": { "deployment": { - "name": "tiller-deploy", + "name": "jumpy-owl-redis", "paused": false, "replicas": { - "available": 1, + "available": 0, "desired": 1, - "unavailable": 0, + "unavailable": 1, "updated": 1 } }, - "namespace": { - "name": "kube-system" - } + "namespace": "default" }, "metricset": { "name": "state_deployment", @@ -127,18 +119,16 @@ }, "kubernetes": { "deployment": { - "name": "wise-lynx-jenkins", + "name": "kube-state-metrics", "paused": false, "replicas": { "available": 1, - "desired": 1, - "unavailable": 0, - "updated": 1 + "desired": 2, + "unavailable": 1, + "updated": 2 } }, - "namespace": { - "name": "jenkins" - } + "namespace": "kube-system" }, "metricset": { "name": "state_deployment", diff --git a/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.8.0.plain-expected.json b/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.8.0.plain-expected.json index bfc922814ee2..b766e4068f47 100644 --- a/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.8.0.plain-expected.json +++ b/metricbeat/module/kubernetes/state_deployment/_meta/testdata/ksm-v1.8.0.plain-expected.json @@ -7,7 +7,7 @@ }, "kubernetes": { "deployment": { - "name": "springboot-cr-applier", + "name": "metricbeat", "paused": false, "replicas": { "available": 1, @@ -16,9 +16,7 @@ "updated": 1 } }, - "namespace": { - "name": "telenet-cluster-ops" - } + "namespace": "openshift-logging" }, "metricset": { "name": "state_deployment", @@ -37,7 +35,7 @@ }, "kubernetes": { "deployment": { - "name": "namespace-operator", + "name": "springboot-operator", "paused": false, "replicas": { "available": 1, @@ -46,9 +44,7 @@ "updated": 1 } }, - "namespace": { - "name": "telenet-operators" - } + "namespace": "bi" }, "metricset": { "name": "state_deployment", @@ -67,7 +63,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "tiller", "paused": false, "replicas": { "available": 1, @@ -76,9 +72,7 @@ "updated": 1 } }, - "namespace": { - "name": "devops-playground" - } + "namespace": "tiller" }, "metricset": { "name": "state_deployment", @@ -97,18 +91,16 @@ }, "kubernetes": { "deployment": { - "name": "kube-state-metrics", + "name": "jenkins-operator", "paused": false, "replicas": { - "available": 1, - "desired": 1, + "available": 0, + "desired": 0, "unavailable": 0, - "updated": 1 + "updated": 0 } }, - "namespace": { - "name": "openshift-monitoring" - } + "namespace": "adc-vault" }, "metricset": { "name": "state_deployment", @@ -127,18 +119,16 @@ }, "kubernetes": { "deployment": { - "name": "webconsole", + "name": "jenkins-operator", "paused": false, "replicas": { - "available": 3, - "desired": 3, + "available": 1, + "desired": 1, "unavailable": 0, - "updated": 3 + "updated": 1 } }, - "namespace": { - "name": "openshift-web-console" - } + "namespace": "paas-demo" }, "metricset": { "name": "state_deployment", @@ -157,7 +147,7 @@ }, "kubernetes": { "deployment": { - "name": "springboot-operator", + "name": "springboot-cr-applier", "paused": false, "replicas": { "available": 1, @@ -166,9 +156,7 @@ "updated": 1 } }, - "namespace": { - "name": "gdpr" - } + "namespace": "telenet-cluster-ops" }, "metricset": { "name": "state_deployment", @@ -196,9 +184,7 @@ "updated": 1 } }, - "namespace": { - "name": "edev-communication" - } + "namespace": "paas-demo" }, "metricset": { "name": "state_deployment", @@ -217,7 +203,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "springboot-operator", "paused": false, "replicas": { "available": 1, @@ -226,9 +212,7 @@ "updated": 1 } }, - "namespace": { - "name": "telenet-baseimages" - } + "namespace": "edev-communication" }, "metricset": { "name": "state_deployment", @@ -247,7 +231,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "kube-state-metrics", "paused": false, "replicas": { "available": 1, @@ -256,9 +240,7 @@ "updated": 1 } }, - "namespace": { - "name": "bi" - } + "namespace": "openshift-logging" }, "metricset": { "name": "state_deployment", @@ -277,7 +259,7 @@ }, "kubernetes": { "deployment": { - "name": "dynatrace-oneagent-operator", + "name": "jenkins-operator", "paused": false, "replicas": { "available": 1, @@ -286,9 +268,7 @@ "updated": 1 } }, - "namespace": { - "name": "dynatrace" - } + "namespace": "devops-playground" }, "metricset": { "name": "state_deployment", @@ -316,9 +296,7 @@ "updated": 1 } }, - "namespace": { - "name": "darwin-integrations" - } + "namespace": "edev-tools" }, "metricset": { "name": "state_deployment", @@ -346,9 +324,7 @@ "updated": 1 } }, - "namespace": { - "name": "paas-demo" - } + "namespace": "devops-playground" }, "metricset": { "name": "state_deployment", @@ -376,9 +352,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-monitoring" - } + "namespace": "openshift-monitoring" }, "metricset": { "name": "state_deployment", @@ -397,18 +371,16 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-cr-applier", + "name": "tiller-deploy", "paused": false, "replicas": { - "available": 1, + "available": 0, "desired": 1, - "unavailable": 0, + "unavailable": 1, "updated": 1 } }, - "namespace": { - "name": "telenet-cluster-ops" - } + "namespace": "tiller" }, "metricset": { "name": "state_deployment", @@ -427,18 +399,16 @@ }, "kubernetes": { "deployment": { - "name": "tiller-deploy", + "name": "jenkins-operator", "paused": false, "replicas": { - "available": 0, + "available": 1, "desired": 1, - "unavailable": 1, + "unavailable": 0, "updated": 1 } }, - "namespace": { - "name": "tiller" - } + "namespace": "darwin-integrations" }, "metricset": { "name": "state_deployment", @@ -457,18 +427,16 @@ }, "kubernetes": { "deployment": { - "name": "elasticsearch", + "name": "jenkins-operator", "paused": false, "replicas": { - "available": 0, + "available": 1, "desired": 1, - "unavailable": 1, + "unavailable": 0, "updated": 1 } }, - "namespace": { - "name": "test-config" - } + "namespace": "edev-communication" }, "metricset": { "name": "state_deployment", @@ -487,18 +455,16 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "webconsole", "paused": false, "replicas": { - "available": 0, - "desired": 0, + "available": 3, + "desired": 3, "unavailable": 0, - "updated": 0 + "updated": 3 } }, - "namespace": { - "name": "adc-vault" - } + "namespace": "openshift-web-console" }, "metricset": { "name": "state_deployment", @@ -517,7 +483,7 @@ }, "kubernetes": { "deployment": { - "name": "springboot-operator", + "name": "console", "paused": false, "replicas": { "available": 1, @@ -526,9 +492,7 @@ "updated": 1 } }, - "namespace": { - "name": "edev-tools" - } + "namespace": "openshift-console" }, "metricset": { "name": "state_deployment", @@ -547,7 +511,7 @@ }, "kubernetes": { "deployment": { - "name": "springboot-operator", + "name": "jenkins-operator", "paused": false, "replicas": { "available": 1, @@ -556,9 +520,7 @@ "updated": 1 } }, - "namespace": { - "name": "devops-playground" - } + "namespace": "gdpr" }, "metricset": { "name": "state_deployment", @@ -577,7 +539,7 @@ }, "kubernetes": { "deployment": { - "name": "cluster-monitoring-operator", + "name": "jenkins-cr-applier", "paused": false, "replicas": { "available": 1, @@ -586,9 +548,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-monitoring" - } + "namespace": "telenet-cluster-ops" }, "metricset": { "name": "state_deployment", @@ -607,7 +567,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "namespace-operator", "paused": false, "replicas": { "available": 1, @@ -616,9 +576,7 @@ "updated": 1 } }, - "namespace": { - "name": "paas-demo" - } + "namespace": "telenet-operators" }, "metricset": { "name": "state_deployment", @@ -637,7 +595,7 @@ }, "kubernetes": { "deployment": { - "name": "springboot-operator", + "name": "jenkins-operator", "paused": false, "replicas": { "available": 1, @@ -646,9 +604,7 @@ "updated": 1 } }, - "namespace": { - "name": "bi" - } + "namespace": "telenet-baseimages" }, "metricset": { "name": "state_deployment", @@ -667,7 +623,7 @@ }, "kubernetes": { "deployment": { - "name": "console", + "name": "cluster-monitoring-operator", "paused": false, "replicas": { "available": 1, @@ -676,9 +632,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-console" - } + "namespace": "openshift-monitoring" }, "metricset": { "name": "state_deployment", @@ -697,18 +651,16 @@ }, "kubernetes": { "deployment": { - "name": "kibana-kibana", + "name": "springboot-operator", "paused": false, "replicas": { - "available": 0, - "desired": 0, + "available": 1, + "desired": 1, "unavailable": 0, - "updated": 0 + "updated": 1 } }, - "namespace": { - "name": "kibana-tst" - } + "namespace": "darwin-integrations" }, "metricset": { "name": "state_deployment", @@ -727,7 +679,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "kibana", "paused": false, "replicas": { "available": 1, @@ -736,9 +688,7 @@ "updated": 1 } }, - "namespace": { - "name": "edev-tools" - } + "namespace": "test-config" }, "metricset": { "name": "state_deployment", @@ -757,7 +707,7 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "dynatrace-oneagent-operator", "paused": false, "replicas": { "available": 1, @@ -766,9 +716,7 @@ "updated": 1 } }, - "namespace": { - "name": "edev-communication" - } + "namespace": "dynatrace" }, "metricset": { "name": "state_deployment", @@ -787,7 +735,7 @@ }, "kubernetes": { "deployment": { - "name": "kube-state-metrics", + "name": "springboot-operator", "paused": false, "replicas": { "available": 1, @@ -796,9 +744,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-logging" - } + "namespace": "edev-tools" }, "metricset": { "name": "state_deployment", @@ -817,7 +763,7 @@ }, "kubernetes": { "deployment": { - "name": "grafana", + "name": "sonarqube-operator", "paused": false, "replicas": { "available": 1, @@ -826,9 +772,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-monitoring" - } + "namespace": "devops-playground" }, "metricset": { "name": "state_deployment", @@ -847,7 +791,7 @@ }, "kubernetes": { "deployment": { - "name": "weblogic-operator", + "name": "grafana", "paused": false, "replicas": { "available": 1, @@ -856,9 +800,7 @@ "updated": 1 } }, - "namespace": { - "name": "weblogic-poc" - } + "namespace": "openshift-monitoring" }, "metricset": { "name": "state_deployment", @@ -877,18 +819,16 @@ }, "kubernetes": { "deployment": { - "name": "jenkins-operator", + "name": "kibana-kibana", "paused": false, "replicas": { - "available": 1, - "desired": 1, + "available": 0, + "desired": 0, "unavailable": 0, - "updated": 1 + "updated": 0 } }, - "namespace": { - "name": "gdpr" - } + "namespace": "kibana-tst" }, "metricset": { "name": "state_deployment", @@ -907,7 +847,7 @@ }, "kubernetes": { "deployment": { - "name": "sonarqube-operator", + "name": "kube-state-metrics", "paused": false, "replicas": { "available": 1, @@ -916,9 +856,7 @@ "updated": 1 } }, - "namespace": { - "name": "devops-playground" - } + "namespace": "openshift-monitoring" }, "metricset": { "name": "state_deployment", @@ -937,18 +875,16 @@ }, "kubernetes": { "deployment": { - "name": "kibana", + "name": "elasticsearch", "paused": false, "replicas": { - "available": 1, + "available": 0, "desired": 1, - "unavailable": 0, + "unavailable": 1, "updated": 1 } }, - "namespace": { - "name": "test-config" - } + "namespace": "test-config" }, "metricset": { "name": "state_deployment", @@ -976,9 +912,7 @@ "updated": 1 } }, - "namespace": { - "name": "darwin-integrations" - } + "namespace": "gdpr" }, "metricset": { "name": "state_deployment", @@ -997,7 +931,7 @@ }, "kubernetes": { "deployment": { - "name": "tiller", + "name": "jenkins-operator", "paused": false, "replicas": { "available": 1, @@ -1006,9 +940,7 @@ "updated": 1 } }, - "namespace": { - "name": "tiller" - } + "namespace": "bi" }, "metricset": { "name": "state_deployment", @@ -1027,7 +959,7 @@ }, "kubernetes": { "deployment": { - "name": "metricbeat", + "name": "weblogic-operator", "paused": false, "replicas": { "available": 1, @@ -1036,9 +968,7 @@ "updated": 1 } }, - "namespace": { - "name": "openshift-logging" - } + "namespace": "weblogic-poc" }, "metricset": { "name": "state_deployment", diff --git a/metricbeat/module/kubernetes/state_deployment/state_deployment.go b/metricbeat/module/kubernetes/state_deployment/state_deployment.go index 6b440baa2b97..02448afdc9a9 100644 --- a/metricbeat/module/kubernetes/state_deployment/state_deployment.go +++ b/metricbeat/module/kubernetes/state_deployment/state_deployment.go @@ -51,7 +51,7 @@ var ( Labels: map[string]p.LabelMap{ "deployment": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), }, } ) diff --git a/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v1.8.0.expected index 5b40b8ece051..8822378f36dc 100644 --- a/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v1.8.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "completions": { diff --git a/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v2.0.0.expected index 484d805c3a02..c9110a37ed01 100644 --- a/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_job/_meta/test/ksm.v2.0.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "completions": { diff --git a/metricbeat/module/kubernetes/state_job/_meta/testdata/kube-state-metrics-v1.8.0.plain-expected.json b/metricbeat/module/kubernetes/state_job/_meta/testdata/kube-state-metrics-v1.8.0.plain-expected.json index 926fc60faaab..afa859bc4182 100644 --- a/metricbeat/module/kubernetes/state_job/_meta/testdata/kube-state-metrics-v1.8.0.plain-expected.json +++ b/metricbeat/module/kubernetes/state_job/_meta/testdata/kube-state-metrics-v1.8.0.plain-expected.json @@ -10,7 +10,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075628", + "name": "sleep-30-ok-cron-27075645", "owner": { "is_controller": "true", "kind": "CronJob", @@ -25,12 +25,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:28:00.000Z" + "created": "2021-06-24T12:45:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -50,33 +48,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075625", + "name": "sleep-5-parallel-cron-27075617", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 0, + "active": 5, "failed": 0, - "succeeded": 1 - }, - "status": { - "complete": "true" + "succeeded": 0 }, "time": { - "completed": "2021-06-24T12:37:03.000Z", - "created": "2021-06-24T12:25:00.000Z" + "created": "2021-06-24T12:17:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -96,29 +88,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075641", + "name": "sleep-30-fail-cron-27075644", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:41:00.000Z" + "created": "2021-06-24T12:44:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -140,7 +130,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075644", + "name": "sleep-30-fail-cron-27075549", "owner": { "is_controller": "true", "kind": "CronJob", @@ -155,12 +145,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:44:00.000Z" + "created": "2021-06-24T11:09:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -182,11 +170,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075618", + "name": "sleep-30-ok-cron-27075638", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -197,12 +185,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:18:00.000Z" + "created": "2021-06-24T12:38:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -222,29 +208,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075618", + "name": "sleep-5-parallel-cron-27075639", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:18:00.000Z" + "created": "2021-06-24T12:39:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -266,7 +250,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075622", + "name": "sleep-30-fail-cron-27075535", "owner": { "is_controller": "true", "kind": "CronJob", @@ -281,12 +265,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:22:00.000Z" + "created": "2021-06-24T10:55:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -306,29 +288,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075617", + "name": "sleep-5-parallel-cron-27075551", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:17:00.000Z" + "created": "2021-06-24T11:11:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -350,7 +330,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075639", + "name": "sleep-5-parallel-cron-27075623", "owner": { "is_controller": "true", "kind": "CronJob", @@ -360,17 +340,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:39:00.000Z" + "created": "2021-06-24T12:23:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -392,7 +370,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075590", + "name": "sleep-30-ok-cron-27075592", "owner": { "is_controller": "true", "kind": "CronJob", @@ -407,12 +385,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:50:00.000Z" + "created": "2021-06-24T11:52:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -432,29 +408,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075622", + "name": "sleep-30-fail-cron-27075584", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 2 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:22:00.000Z" + "created": "2021-06-24T11:44:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -476,7 +450,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075627", + "name": "sleep-30-ok-cron-27075642", "owner": { "is_controller": "true", "kind": "CronJob", @@ -486,21 +460,15 @@ "desired": 1 }, "pods": { - "active": 0, + "active": 1, "failed": 0, - "succeeded": 1 - }, - "status": { - "complete": "true" + "succeeded": 0 }, "time": { - "completed": "2021-06-24T12:32:20.000Z", - "created": "2021-06-24T12:27:00.000Z" + "created": "2021-06-24T12:42:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -520,19 +488,19 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075643", + "name": "sleep-5-parallel-cron-27075643", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, @@ -540,9 +508,7 @@ "created": "2021-06-24T12:43:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -564,7 +530,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075625", + "name": "sleep-30-fail-cron-27075536", "owner": { "is_controller": "true", "kind": "CronJob", @@ -579,12 +545,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:25:00.000Z" + "created": "2021-06-24T10:56:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -606,7 +570,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075644", + "name": "sleep-5-parallel-cron-27075630", "owner": { "is_controller": "true", "kind": "CronJob", @@ -621,12 +585,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:44:00.000Z" + "created": "2021-06-24T12:30:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -646,29 +608,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075610", + "name": "sleep-5-parallel-cron-27075626", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 2 }, "time": { - "created": "2021-06-24T12:10:00.000Z" + "created": "2021-06-24T12:26:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -688,29 +648,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075628", + "name": "sleep-30-fail-cron-27075610", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:28:00.000Z" + "created": "2021-06-24T12:10:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -732,11 +690,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075632", + "name": "sleep-30-ok-cron-27075618", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -747,12 +705,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:32:00.000Z" + "created": "2021-06-24T12:18:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -772,29 +728,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075612", + "name": "sleep-5-parallel-cron-27075608", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:12:00.000Z" + "created": "2021-06-24T12:08:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -814,29 +768,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075633", + "name": "sleep-5-parallel-cron-27075622", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 2 }, "time": { - "created": "2021-06-24T12:33:00.000Z" + "created": "2021-06-24T12:22:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -858,7 +810,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075615", + "name": "sleep-30-fail-cron-27075591", "owner": { "is_controller": "true", "kind": "CronJob", @@ -873,12 +825,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:15:00.000Z" + "created": "2021-06-24T11:51:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -900,11 +850,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075621", + "name": "sleep-30-fail-cron-27075598", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -915,12 +865,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:21:00.000Z" + "created": "2021-06-24T11:58:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -940,29 +888,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075591", + "name": "sleep-5-parallel-cron-27075636", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 4 }, "time": { - "created": "2021-06-24T11:51:00.000Z" + "created": "2021-06-24T12:36:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -984,11 +930,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075639", + "name": "sleep-30-fail-cron-27075645", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -999,12 +945,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:39:00.000Z" + "created": "2021-06-24T12:45:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1026,27 +970,29 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075638", + "name": "sleep-30-ok-cron-27075629", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 }, "pods": { - "active": 1, + "active": 0, "failed": 0, - "succeeded": 0 + "succeeded": 1 + }, + "status": { + "complete": "true" }, "time": { - "created": "2021-06-24T12:38:00.000Z" + "completed": "2021-06-24T12:42:50.000Z", + "created": "2021-06-24T12:29:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1066,29 +1012,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075641", + "name": "sleep-5-parallel-cron-27075604", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:41:00.000Z" + "created": "2021-06-24T12:04:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1108,29 +1052,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075636", + "name": "sleep-5-parallel-cron-27075591", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:36:00.000Z" + "created": "2021-06-24T11:51:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1150,29 +1092,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075605", + "name": "sleep-5-parallel-cron-27075645", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:05:00.000Z" + "created": "2021-06-24T12:45:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1194,11 +1134,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075634", + "name": "sleep-30-fail-cron-27075625", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -1209,12 +1149,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:34:00.000Z" + "created": "2021-06-24T12:25:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1236,7 +1174,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075547", + "name": "sleep-30-fail-cron-27075639", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1251,12 +1189,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:07:00.000Z" + "created": "2021-06-24T12:39:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1278,11 +1214,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075592", + "name": "sleep-30-fail-cron-27075636", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -1293,12 +1229,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:52:00.000Z" + "created": "2021-06-24T12:36:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1318,29 +1252,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075601", + "name": "sleep-30-fail-cron-27075615", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 3, + "active": 1, "failed": 0, - "succeeded": 17 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:01:00.000Z" + "created": "2021-06-24T12:15:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1362,7 +1294,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075603", + "name": "sleep-5-parallel-cron-27075641", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1372,17 +1304,15 @@ "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:03:00.000Z" + "created": "2021-06-24T12:41:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1402,33 +1332,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075613", + "name": "sleep-30-ok-cron-27075621", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 0, + "active": 1, "failed": 0, - "succeeded": 20 - }, - "status": { - "complete": "true" + "succeeded": 0 }, "time": { - "completed": "2021-06-24T12:28:39.000Z", - "created": "2021-06-24T12:13:00.000Z" + "created": "2021-06-24T12:21:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1448,29 +1372,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075626", + "name": "sleep-30-ok-cron-27075623", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 2 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:26:00.000Z" + "created": "2021-06-24T12:23:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1490,29 +1412,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075576", + "name": "sleep-5-parallel-cron-27075563", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T11:36:00.000Z" + "created": "2021-06-24T11:23:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1534,11 +1454,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075547", + "name": "sleep-30-fail-cron-27075612", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -1549,12 +1469,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:07:00.000Z" + "created": "2021-06-24T12:12:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1576,7 +1494,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075615", + "name": "sleep-5-parallel-cron-27075634", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1586,21 +1504,15 @@ "desired": 5 }, "pods": { - "active": 0, + "active": 5, "failed": 0, - "succeeded": 20 - }, - "status": { - "complete": "true" + "succeeded": 1 }, "time": { - "completed": "2021-06-24T12:33:19.000Z", - "created": "2021-06-24T12:15:00.000Z" + "created": "2021-06-24T12:34:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1620,29 +1532,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075628", + "name": "sleep-5-parallel-cron-27075590", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:28:00.000Z" + "created": "2021-06-24T11:50:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1664,11 +1574,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075640", + "name": "sleep-30-fail-cron-27075621", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -1679,12 +1589,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:40:00.000Z" + "created": "2021-06-24T12:21:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1706,7 +1614,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075642", + "name": "sleep-30-ok-cron-27075639", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1721,12 +1629,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:42:00.000Z" + "created": "2021-06-24T12:39:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1746,29 +1652,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075630", + "name": "sleep-30-fail-cron-27075594", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:30:00.000Z" + "created": "2021-06-24T11:54:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1790,7 +1694,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075635", + "name": "sleep-5-parallel-cron-27075631", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1802,15 +1706,13 @@ "pods": { "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 3 }, "time": { - "created": "2021-06-24T12:35:00.000Z" + "created": "2021-06-24T12:31:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1830,29 +1732,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075621", + "name": "sleep-30-ok-cron-27075535", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 1 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:21:00.000Z" + "created": "2021-06-24T10:55:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1874,11 +1774,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075646", + "name": "sleep-30-fail-cron-27075631", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -1889,12 +1789,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:46:00.000Z" + "created": "2021-06-24T12:31:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -1916,7 +1814,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075584", + "name": "sleep-5-parallel-cron-27075629", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1926,17 +1824,15 @@ "desired": 5 }, "pods": { - "active": 2, + "active": 5, "failed": 0, - "succeeded": 18 + "succeeded": 6 }, "time": { - "created": "2021-06-24T11:44:00.000Z" + "created": "2021-06-24T12:29:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -1958,7 +1854,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075604", + "name": "sleep-5-parallel-cron-27075633", "owner": { "is_controller": "true", "kind": "CronJob", @@ -1968,17 +1864,15 @@ "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:04:00.000Z" + "created": "2021-06-24T12:33:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2000,7 +1894,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075585", + "name": "sleep-5-parallel-cron-27075616", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2010,17 +1904,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 10 + "succeeded": 19 }, "time": { - "created": "2021-06-24T11:45:00.000Z" + "created": "2021-06-24T12:16:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2042,11 +1934,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075603", + "name": "sleep-30-ok-cron-27075637", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -2057,12 +1949,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:03:00.000Z" + "created": "2021-06-24T12:37:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2084,7 +1974,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075619", + "name": "sleep-30-fail-cron-27075616", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2099,12 +1989,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:19:00.000Z" + "created": "2021-06-24T12:16:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2126,7 +2014,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075620", + "name": "sleep-5-parallel-cron-27075615", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2144,13 +2032,11 @@ "complete": "true" }, "time": { - "completed": "2021-06-24T12:37:24.000Z", - "created": "2021-06-24T12:20:00.000Z" + "completed": "2021-06-24T12:33:19.000Z", + "created": "2021-06-24T12:15:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2172,7 +2058,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075630", + "name": "sleep-30-ok-cron-27075627", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2182,17 +2068,19 @@ "desired": 1 }, "pods": { - "active": 1, + "active": 0, "failed": 0, - "succeeded": 0 + "succeeded": 1 + }, + "status": { + "complete": "true" }, "time": { - "created": "2021-06-24T12:30:00.000Z" + "completed": "2021-06-24T12:32:20.000Z", + "created": "2021-06-24T12:27:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2214,7 +2102,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075634", + "name": "sleep-30-fail-cron-27075611", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2229,12 +2117,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:34:00.000Z" + "created": "2021-06-24T12:11:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2256,31 +2142,25 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075629", + "name": "sleep-30-fail-cron-27075593", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 }, "pods": { - "active": 0, + "active": 1, "failed": 0, - "succeeded": 1 - }, - "status": { - "complete": "true" + "succeeded": 0 }, "time": { - "completed": "2021-06-24T12:42:50.000Z", - "created": "2021-06-24T12:29:00.000Z" + "created": "2021-06-24T11:53:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2302,11 +2182,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075594", + "name": "sleep-30-fail-cron-27075641", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -2317,12 +2197,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:54:00.000Z" + "created": "2021-06-24T12:41:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2342,29 +2220,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075532", + "name": "sleep-30-fail-cron-27075628", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { - "created": "2021-06-24T10:52:00.000Z" + "created": "2021-06-24T12:28:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2384,29 +2260,31 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075612", + "name": "sleep-30-ok-cron-27075625", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 0, "failed": 0, "succeeded": 1 }, + "status": { + "complete": "true" + }, "time": { - "created": "2021-06-24T12:12:00.000Z" + "completed": "2021-06-24T12:37:03.000Z", + "created": "2021-06-24T12:25:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2428,7 +2306,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075610", + "name": "sleep-5-parallel-cron-27075585", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2438,17 +2316,15 @@ "desired": 5 }, "pods": { - "active": 3, + "active": 5, "failed": 0, - "succeeded": 17 + "succeeded": 10 }, "time": { - "created": "2021-06-24T12:10:00.000Z" + "created": "2021-06-24T11:45:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2470,11 +2346,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075536", + "name": "sleep-30-fail-cron-27075601", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -2485,12 +2361,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T10:56:00.000Z" + "created": "2021-06-24T12:01:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2512,7 +2386,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075636", + "name": "sleep-30-fail-cron-27075614", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2527,12 +2401,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:36:00.000Z" + "created": "2021-06-24T12:14:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2552,29 +2424,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075549", + "name": "sleep-5-parallel-cron-27075644", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T11:09:00.000Z" + "created": "2021-06-24T12:44:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2596,7 +2466,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075640", + "name": "sleep-30-fail-cron-27075617", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2611,12 +2481,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:40:00.000Z" + "created": "2021-06-24T12:17:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2636,29 +2504,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075592", + "name": "sleep-30-ok-cron-27075601", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:52:00.000Z" + "created": "2021-06-24T12:01:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2678,29 +2544,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075598", + "name": "sleep-5-parallel-cron-27075628", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T11:58:00.000Z" + "created": "2021-06-24T12:28:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2722,11 +2586,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075631", + "name": "sleep-30-fail-cron-27075605", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -2737,12 +2601,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:31:00.000Z" + "created": "2021-06-24T12:05:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2764,11 +2626,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075609", + "name": "sleep-30-ok-cron-27075646", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -2779,12 +2641,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:09:00.000Z" + "created": "2021-06-24T12:46:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2804,29 +2664,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075646", + "name": "sleep-30-fail-cron-27075607", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:46:00.000Z" + "created": "2021-06-24T12:07:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2846,29 +2704,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075630", + "name": "sleep-5-parallel-cron-27075627", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 15 }, "time": { - "created": "2021-06-24T12:30:00.000Z" + "created": "2021-06-24T12:27:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2890,7 +2746,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075634", + "name": "sleep-5-parallel-cron-27075620", "owner": { "is_controller": "true", "kind": "CronJob", @@ -2900,17 +2756,19 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 0, "failed": 0, - "succeeded": 1 + "succeeded": 20 + }, + "status": { + "complete": "true" }, "time": { - "created": "2021-06-24T12:34:00.000Z" + "completed": "2021-06-24T12:37:24.000Z", + "created": "2021-06-24T12:20:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -2930,29 +2788,30 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075632", + "name": "sleep-30-fail-cron-27075600", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, - "failed": 0, - "succeeded": 1 + "active": 0, + "failed": 1, + "succeeded": 0 + }, + "status": { + "failed": "true" }, "time": { - "created": "2021-06-24T12:32:00.000Z" + "created": "2021-06-24T12:00:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -2972,29 +2831,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075563", + "name": "sleep-5-parallel-cron-27075607", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 3, "failed": 0, - "succeeded": 0 + "succeeded": 17 }, "time": { - "created": "2021-06-24T11:23:00.000Z" + "created": "2021-06-24T12:07:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3014,29 +2871,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075535", + "name": "sleep-30-fail-cron-27075590", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T10:55:00.000Z" + "created": "2021-06-24T11:50:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3056,29 +2911,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075643", + "name": "sleep-30-ok-cron-27075617", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:43:00.000Z" + "created": "2021-06-24T12:17:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3098,29 +2951,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075641", + "name": "sleep-5-parallel-cron-27075610", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 3, "failed": 0, - "succeeded": 0 + "succeeded": 17 }, "time": { - "created": "2021-06-24T12:41:00.000Z" + "created": "2021-06-24T12:10:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3140,29 +2991,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075633", + "name": "sleep-5-parallel-cron-27075572", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:33:00.000Z" + "created": "2021-06-24T11:32:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3184,11 +3033,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075614", + "name": "sleep-30-ok-cron-27075641", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -3199,12 +3048,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:14:00.000Z" + "created": "2021-06-24T12:41:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3226,7 +3073,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075604", + "name": "sleep-30-fail-cron-27075547", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3241,12 +3088,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:04:00.000Z" + "created": "2021-06-24T11:07:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3268,11 +3113,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075643", + "name": "sleep-30-ok-cron-27075630", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -3283,12 +3128,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:43:00.000Z" + "created": "2021-06-24T12:30:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3310,7 +3153,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075642", + "name": "sleep-5-parallel-cron-27075621", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3322,15 +3165,13 @@ "pods": { "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 1 }, "time": { - "created": "2021-06-24T12:42:00.000Z" + "created": "2021-06-24T12:21:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3350,29 +3191,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075551", + "name": "sleep-30-fail-cron-27075624", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:11:00.000Z" + "created": "2021-06-24T12:24:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3392,29 +3231,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075614", + "name": "sleep-30-fail-cron-27075619", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 15 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:14:00.000Z" + "created": "2021-06-24T12:19:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3434,29 +3271,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075607", + "name": "sleep-5-parallel-cron-27075601", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 3, "failed": 0, - "succeeded": 0 + "succeeded": 17 }, "time": { - "created": "2021-06-24T12:07:00.000Z" + "created": "2021-06-24T12:01:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3478,7 +3313,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075588", + "name": "sleep-30-fail-cron-27075643", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3493,12 +3328,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:48:00.000Z" + "created": "2021-06-24T12:43:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3520,11 +3353,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075590", + "name": "sleep-30-ok-cron-27075635", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -3535,12 +3368,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:50:00.000Z" + "created": "2021-06-24T12:35:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3562,7 +3393,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075612", + "name": "sleep-30-ok-cron-27075547", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3577,12 +3408,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:12:00.000Z" + "created": "2021-06-24T11:07:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3604,11 +3433,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075535", + "name": "sleep-30-fail-cron-27075588", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -3619,12 +3448,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T10:55:00.000Z" + "created": "2021-06-24T11:48:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3646,7 +3473,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075637", + "name": "sleep-30-ok-cron-27075612", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3661,12 +3488,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:37:00.000Z" + "created": "2021-06-24T12:12:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3686,29 +3511,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075620", + "name": "sleep-5-parallel-cron-27075646", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:20:00.000Z" + "created": "2021-06-24T12:46:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3730,11 +3553,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075638", + "name": "sleep-30-fail-cron-27075604", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -3745,12 +3568,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:38:00.000Z" + "created": "2021-06-24T12:04:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3772,7 +3593,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075592", + "name": "sleep-30-fail-cron-27075640", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3787,12 +3608,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:52:00.000Z" + "created": "2021-06-24T12:40:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3814,11 +3633,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075629", + "name": "sleep-30-ok-cron-27075631", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -3829,12 +3648,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:29:00.000Z" + "created": "2021-06-24T12:31:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3856,7 +3673,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075554", + "name": "sleep-30-fail-cron-27075635", "owner": { "is_controller": "true", "kind": "CronJob", @@ -3871,12 +3688,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:14:00.000Z" + "created": "2021-06-24T12:35:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3896,29 +3711,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075591", + "name": "sleep-30-ok-cron-27075634", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:51:00.000Z" + "created": "2021-06-24T12:34:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -3938,32 +3751,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075600", + "name": "sleep-5-parallel-cron-27075592", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 0, - "failed": 1, - "succeeded": 0 - }, - "status": { - "failed": "true" + "active": 1, + "failed": 0, + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:00:00.000Z" + "created": "2021-06-24T11:52:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -3983,29 +3791,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075618", + "name": "sleep-30-fail-cron-27075618", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { "created": "2021-06-24T12:18:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4027,7 +3833,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075645", + "name": "sleep-30-fail-cron-27075642", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4042,12 +3848,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:45:00.000Z" + "created": "2021-06-24T12:42:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4069,7 +3873,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075636", + "name": "sleep-5-parallel-cron-27075535", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4079,17 +3883,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 4 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:36:00.000Z" + "created": "2021-06-24T10:55:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4111,7 +3913,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075548", + "name": "sleep-5-parallel-cron-27075566", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4126,12 +3928,10 @@ "succeeded": 19 }, "time": { - "created": "2021-06-24T11:08:00.000Z" + "created": "2021-06-24T11:26:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4151,29 +3951,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075607", + "name": "sleep-30-fail-cron-27075634", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 3, + "active": 1, "failed": 0, - "succeeded": 17 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:07:00.000Z" + "created": "2021-06-24T12:34:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4195,7 +3993,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075606", + "name": "sleep-30-fail-cron-27075602", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4210,12 +4008,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:06:00.000Z" + "created": "2021-06-24T12:02:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4235,29 +4031,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075536", + "name": "sleep-5-parallel-cron-27075640", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 1 }, "time": { - "created": "2021-06-24T10:56:00.000Z" + "created": "2021-06-24T12:40:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4277,29 +4071,31 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075642", + "name": "sleep-5-parallel-cron-27075613", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 0, "failed": 0, - "succeeded": 0 + "succeeded": 20 + }, + "status": { + "complete": "true" }, "time": { - "created": "2021-06-24T12:42:00.000Z" + "completed": "2021-06-24T12:28:39.000Z", + "created": "2021-06-24T12:13:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4321,7 +4117,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075645", + "name": "sleep-5-parallel-cron-27075624", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4333,15 +4129,13 @@ "pods": { "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 7 }, "time": { - "created": "2021-06-24T12:45:00.000Z" + "created": "2021-06-24T12:24:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4361,29 +4155,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075637", + "name": "sleep-30-fail-cron-27075637", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 2 + "succeeded": 0 }, "time": { "created": "2021-06-24T12:37:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4405,7 +4197,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075646", + "name": "sleep-30-fail-cron-27075606", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4420,12 +4212,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:46:00.000Z" + "created": "2021-06-24T12:06:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4445,29 +4235,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075594", + "name": "sleep-30-ok-cron-27075632", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 9 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:54:00.000Z" + "created": "2021-06-24T12:32:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4487,29 +4275,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075631", + "name": "sleep-30-fail-cron-27075627", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 3 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:31:00.000Z" + "created": "2021-06-24T12:27:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4531,7 +4317,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075572", + "name": "sleep-5-parallel-cron-27075571", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4546,12 +4332,10 @@ "succeeded": 18 }, "time": { - "created": "2021-06-24T11:32:00.000Z" + "created": "2021-06-24T11:31:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4571,29 +4355,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075610", + "name": "sleep-5-parallel-cron-27075564", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:10:00.000Z" + "created": "2021-06-24T11:24:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4613,29 +4395,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075566", + "name": "sleep-30-fail-cron-27075622", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:26:00.000Z" + "created": "2021-06-24T12:22:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4655,29 +4435,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075623", + "name": "sleep-30-ok-cron-27075536", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:23:00.000Z" + "created": "2021-06-24T10:56:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4697,29 +4475,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075608", + "name": "sleep-5-parallel-cron-27075612", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 1 }, "time": { - "created": "2021-06-24T12:08:00.000Z" + "created": "2021-06-24T12:12:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4741,7 +4517,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075625", + "name": "sleep-5-parallel-cron-27075619", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4751,17 +4527,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 4, "failed": 0, - "succeeded": 11 + "succeeded": 16 }, "time": { - "created": "2021-06-24T12:25:00.000Z" + "created": "2021-06-24T12:19:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4781,29 +4555,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075645", + "name": "sleep-5-parallel-cron-27075638", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:45:00.000Z" + "created": "2021-06-24T12:38:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4825,11 +4597,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075602", + "name": "sleep-30-ok-cron-27075590", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -4840,12 +4612,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:02:00.000Z" + "created": "2021-06-24T11:50:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4867,11 +4637,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075593", + "name": "sleep-30-ok-cron-27075626", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -4882,12 +4652,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T11:53:00.000Z" + "created": "2021-06-24T12:26:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -4907,29 +4675,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075586", + "name": "sleep-5-parallel-cron-27075625", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 11 }, "time": { - "created": "2021-06-24T11:46:00.000Z" + "created": "2021-06-24T12:25:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4951,7 +4717,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075616", + "name": "sleep-5-parallel-cron-27075603", "owner": { "is_controller": "true", "kind": "CronJob", @@ -4966,12 +4732,10 @@ "succeeded": 19 }, "time": { - "created": "2021-06-24T12:16:00.000Z" + "created": "2021-06-24T12:03:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -4993,11 +4757,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075613", + "name": "sleep-30-ok-cron-27075643", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -5008,12 +4772,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:13:00.000Z" + "created": "2021-06-24T12:43:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5033,29 +4795,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075594", + "name": "sleep-5-parallel-cron-27075548", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T11:54:00.000Z" + "created": "2021-06-24T11:08:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5075,29 +4835,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075584", + "name": "sleep-5-parallel-cron-27075632", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 1 }, "time": { - "created": "2021-06-24T11:44:00.000Z" + "created": "2021-06-24T12:32:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5119,7 +4877,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075627", + "name": "sleep-5-parallel-cron-27075637", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5131,15 +4889,13 @@ "pods": { "active": 5, "failed": 0, - "succeeded": 15 + "succeeded": 2 }, "time": { - "created": "2021-06-24T12:27:00.000Z" + "created": "2021-06-24T12:37:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5161,7 +4917,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075626", + "name": "sleep-30-ok-cron-27075628", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5176,12 +4932,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:26:00.000Z" + "created": "2021-06-24T12:28:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5203,11 +4957,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075632", + "name": "sleep-30-fail-cron-27075620", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -5218,12 +4972,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:32:00.000Z" + "created": "2021-06-24T12:20:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5243,29 +4995,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075589", + "name": "sleep-30-fail-cron-27075633", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:49:00.000Z" + "created": "2021-06-24T12:33:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5287,11 +5037,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075611", + "name": "sleep-30-ok-cron-27075640", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -5302,12 +5052,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:11:00.000Z" + "created": "2021-06-24T12:40:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5329,7 +5077,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075608", + "name": "sleep-5-parallel-cron-27075593", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5344,12 +5092,10 @@ "succeeded": 19 }, "time": { - "created": "2021-06-24T12:08:00.000Z" + "created": "2021-06-24T11:53:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5371,7 +5117,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075640", + "name": "sleep-5-parallel-cron-27075635", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5383,15 +5129,13 @@ "pods": { "active": 5, "failed": 0, - "succeeded": 1 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:40:00.000Z" + "created": "2021-06-24T12:35:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5411,29 +5155,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075624", + "name": "sleep-30-fail-cron-27075554", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 7 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:24:00.000Z" + "created": "2021-06-24T11:14:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5455,11 +5197,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075623", + "name": "sleep-30-fail-cron-27075609", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -5470,12 +5212,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:23:00.000Z" + "created": "2021-06-24T12:09:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5497,11 +5237,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075535", + "name": "sleep-30-ok-cron-27075633", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -5512,12 +5252,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T10:55:00.000Z" + "created": "2021-06-24T12:33:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5539,7 +5277,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075593", + "name": "sleep-5-parallel-cron-27075557", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5554,12 +5292,10 @@ "succeeded": 19 }, "time": { - "created": "2021-06-24T11:53:00.000Z" + "created": "2021-06-24T11:17:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5581,7 +5317,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075616", + "name": "sleep-30-fail-cron-27075608", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5596,12 +5332,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:16:00.000Z" + "created": "2021-06-24T12:08:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5621,29 +5355,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075557", + "name": "sleep-30-ok-cron-27075636", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:17:00.000Z" + "created": "2021-06-24T12:36:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5663,29 +5395,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075571", + "name": "sleep-30-ok-cron-27075610", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:31:00.000Z" + "created": "2021-06-24T12:10:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5707,7 +5437,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075631", + "name": "sleep-30-fail-cron-27075632", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5722,12 +5452,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:31:00.000Z" + "created": "2021-06-24T12:32:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5747,29 +5475,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075635", + "name": "sleep-5-parallel-cron-27075594", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 9 }, "time": { - "created": "2021-06-24T12:35:00.000Z" + "created": "2021-06-24T11:54:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5789,29 +5515,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075601", + "name": "sleep-5-parallel-cron-27075584", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:01:00.000Z" + "created": "2021-06-24T11:44:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5831,29 +5555,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075627", + "name": "sleep-5-parallel-cron-27075614", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 15 }, "time": { - "created": "2021-06-24T12:27:00.000Z" + "created": "2021-06-24T12:14:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -5873,29 +5595,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075617", + "name": "sleep-30-fail-cron-27075638", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:17:00.000Z" + "created": "2021-06-24T12:38:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5915,29 +5635,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075599", + "name": "sleep-30-fail-cron-27075576", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, - "succeeded": 2 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:59:00.000Z" + "created": "2021-06-24T11:36:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -5959,7 +5677,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075624", + "name": "sleep-30-fail-cron-27075626", "owner": { "is_controller": "true", "kind": "CronJob", @@ -5974,12 +5692,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:24:00.000Z" + "created": "2021-06-24T12:26:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6001,11 +5717,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075635", + "name": "sleep-30-fail-cron-27075563", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -6016,12 +5732,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:35:00.000Z" + "created": "2021-06-24T11:23:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6043,11 +5757,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-ok-cron-27075601", + "name": "sleep-30-fail-cron-27075646", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { "desired": 1 @@ -6058,12 +5772,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:01:00.000Z" + "created": "2021-06-24T12:46:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6085,7 +5797,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075629", + "name": "sleep-5-parallel-cron-27075532", "owner": { "is_controller": "true", "kind": "CronJob", @@ -6095,17 +5807,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 2, "failed": 0, - "succeeded": 6 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:29:00.000Z" + "created": "2021-06-24T10:52:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -6125,29 +5835,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075563", + "name": "sleep-30-fail-cron-27075613", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:23:00.000Z" + "created": "2021-06-24T12:13:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6167,29 +5875,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075626", + "name": "sleep-5-parallel-cron-27075599", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, - "succeeded": 0 + "succeeded": 2 }, "time": { - "created": "2021-06-24T12:26:00.000Z" + "created": "2021-06-24T11:59:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -6209,29 +5915,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-ok-cron-27075644", + "name": "sleep-5-parallel-cron-27075589", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-ok-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { "active": 1, "failed": 0, - "succeeded": 0 + "succeeded": 19 }, "time": { - "created": "2021-06-24T12:44:00.000Z" + "created": "2021-06-24T11:49:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -6251,29 +5955,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075590", + "name": "sleep-30-ok-cron-27075644", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { "active": 1, "failed": 0, - "succeeded": 19 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:50:00.000Z" + "created": "2021-06-24T12:44:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6295,11 +5997,11 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075621", + "name": "sleep-30-ok-cron-27075594", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-30-ok-cron" }, "parallelism": { "desired": 1 @@ -6310,12 +6012,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:21:00.000Z" + "created": "2021-06-24T11:54:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6335,29 +6035,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075619", + "name": "sleep-30-fail-cron-27075629", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 4, + "active": 1, "failed": 0, - "succeeded": 16 + "succeeded": 0 }, "time": { - "created": "2021-06-24T12:19:00.000Z" + "created": "2021-06-24T12:29:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6377,29 +6075,27 @@ "kubernetes": { "job": { "completions": { - "desired": 1 + "desired": 20 }, - "name": "sleep-30-fail-cron-27075617", + "name": "sleep-5-parallel-cron-27075642", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-30-fail-cron" + "name": "sleep-5-parallel-cron" }, "parallelism": { - "desired": 1 + "desired": 5 }, "pods": { - "active": 1, + "active": 5, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:17:00.000Z" + "created": "2021-06-24T12:42:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -6421,7 +6117,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075639", + "name": "sleep-30-fail-cron-27075603", "owner": { "is_controller": "true", "kind": "CronJob", @@ -6436,12 +6132,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:39:00.000Z" + "created": "2021-06-24T12:03:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6463,7 +6157,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075637", + "name": "sleep-30-fail-cron-27075623", "owner": { "is_controller": "true", "kind": "CronJob", @@ -6478,12 +6172,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:37:00.000Z" + "created": "2021-06-24T12:23:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6505,7 +6197,7 @@ "completions": { "desired": 1 }, - "name": "sleep-30-fail-cron-27075623", + "name": "sleep-30-fail-cron-27075586", "owner": { "is_controller": "true", "kind": "CronJob", @@ -6520,12 +6212,10 @@ "succeeded": 0 }, "time": { - "created": "2021-06-24T12:23:00.000Z" + "created": "2021-06-24T11:46:00.000Z" } }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6545,29 +6235,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075638", + "name": "sleep-30-fail-cron-27075630", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 5, + "active": 1, "failed": 0, "succeeded": 0 }, "time": { - "created": "2021-06-24T12:38:00.000Z" + "created": "2021-06-24T12:30:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", @@ -6589,7 +6277,7 @@ "completions": { "desired": 20 }, - "name": "sleep-5-parallel-cron-27075633", + "name": "sleep-5-parallel-cron-27075618", "owner": { "is_controller": "true", "kind": "CronJob", @@ -6599,17 +6287,15 @@ "desired": 5 }, "pods": { - "active": 5, + "active": 2, "failed": 0, - "succeeded": 0 + "succeeded": 18 }, "time": { - "created": "2021-06-24T12:33:00.000Z" + "created": "2021-06-24T12:18:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "parallel-ns" }, "metricset": { "name": "state_job", @@ -6629,29 +6315,27 @@ "kubernetes": { "job": { "completions": { - "desired": 20 + "desired": 1 }, - "name": "sleep-5-parallel-cron-27075564", + "name": "sleep-30-fail-cron-27075592", "owner": { "is_controller": "true", "kind": "CronJob", - "name": "sleep-5-parallel-cron" + "name": "sleep-30-fail-cron" }, "parallelism": { - "desired": 5 + "desired": 1 }, "pods": { - "active": 2, + "active": 1, "failed": 0, - "succeeded": 18 + "succeeded": 0 }, "time": { - "created": "2021-06-24T11:24:00.000Z" + "created": "2021-06-24T11:52:00.000Z" } }, - "namespace": { - "name": "parallel-ns" - } + "namespace": "default" }, "metricset": { "name": "state_job", diff --git a/metricbeat/module/kubernetes/state_job/state_job.go b/metricbeat/module/kubernetes/state_job/state_job.go index bfad2bcba8b8..1b072eae742b 100644 --- a/metricbeat/module/kubernetes/state_job/state_job.go +++ b/metricbeat/module/kubernetes/state_job/state_job.go @@ -65,7 +65,7 @@ var ( Labels: map[string]p.LabelMap{ // Jobs are uniquely identified by the combination of name and namespace. "job_name": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), // Add owner information provided by the "kube_job_owner" InfoMetric. "owner_kind": p.Label("owner.kind"), "owner_name": p.Label("owner.name"), diff --git a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.unit.v1.8.0.expected b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.unit.v1.8.0.expected index fbc1e75a94ec..1bafc31a84c6 100644 --- a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.unit.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.unit.v1.8.0.expected @@ -5,9 +5,7 @@ "labels": { "app": "mysql-server" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "access_mode": "ReadWriteOnce", @@ -32,12 +30,15 @@ }, { "RootFields": {}, - "ModuleFields": null, + "ModuleFields": { + "namespace": "default" + }, "MetricSetFields": { "access_mode": "ReadWriteOnce", - "name": "mongo-data", - "phase": "Lost", - "storage_class": "\u003cnone\u003e" + "name": "prometheus-data", + "phase": "Pending", + "storage_class": "rbd", + "volume_name": "pvc-prometheus-data" }, "Index": "", "ID": "", @@ -52,17 +53,12 @@ }, { "RootFields": {}, - "ModuleFields": { - "namespace": { - "name": "default" - } - }, + "ModuleFields": null, "MetricSetFields": { "access_mode": "ReadWriteOnce", - "name": "prometheus-data", - "phase": "Pending", - "storage_class": "rbd", - "volume_name": "pvc-prometheus-data" + "name": "mongo-data", + "phase": "Lost", + "storage_class": "\u003cnone\u003e" }, "Index": "", "ID": "", diff --git a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v1.8.0.expected index 925b651362ed..e5c4c21bd2f1 100644 --- a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v1.8.0.expected @@ -5,19 +5,17 @@ "labels": { "app": "nginx" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "access_mode": "ReadWriteOnce", - "name": "www-web-1", + "name": "www-web-0", "phase": "Bound", "request_storage": { "bytes": 1073741824 }, "storage_class": "standard", - "volume_name": "pvc-539a19cf-ea44-43a4-84c5-4acca3f9b583" + "volume_name": "pvc-c87e31f9-f853-4b20-b5db-fc41466c8b56" }, "Index": "", "ID": "", @@ -36,19 +34,17 @@ "labels": { "app": "nginx" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "access_mode": "ReadWriteOnce", - "name": "www-web-0", + "name": "www-web-1", "phase": "Bound", "request_storage": { "bytes": 1073741824 }, "storage_class": "standard", - "volume_name": "pvc-c87e31f9-f853-4b20-b5db-fc41466c8b56" + "volume_name": "pvc-539a19cf-ea44-43a4-84c5-4acca3f9b583" }, "Index": "", "ID": "", diff --git a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v2.0.0.expected index dc1ada939b51..09a2c61e7890 100644 --- a/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_persistentvolumeclaim/_meta/test/ksm.v2.0.0.expected @@ -2,9 +2,7 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "access_mode": "ReadWriteOnce", diff --git a/metricbeat/module/kubernetes/state_persistentvolumeclaim/state_persistentvolumeclaim.go b/metricbeat/module/kubernetes/state_persistentvolumeclaim/state_persistentvolumeclaim.go index 15072c5710c7..3cf414c498a4 100644 --- a/metricbeat/module/kubernetes/state_persistentvolumeclaim/state_persistentvolumeclaim.go +++ b/metricbeat/module/kubernetes/state_persistentvolumeclaim/state_persistentvolumeclaim.go @@ -69,7 +69,7 @@ func NewpersistentvolumeclaimMetricSet(base mb.BaseMetricSet) (mb.MetricSet, err "kube_persistentvolumeclaim_status_phase": p.LabelMetric("phase", "phase"), }, Labels: map[string]p.LabelMap{ - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "persistentvolumeclaim": p.KeyLabel("name"), "storageclass": p.Label("storage_class"), "volumename": p.Label("volume_name"), diff --git a/metricbeat/module/kubernetes/state_pod/_meta/data.json b/metricbeat/module/kubernetes/state_pod/_meta/data.json index 2a002a1470ea..474341cacd37 100644 --- a/metricbeat/module/kubernetes/state_pod/_meta/data.json +++ b/metricbeat/module/kubernetes/state_pod/_meta/data.json @@ -6,16 +6,14 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "jenkins" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { "host_ip": "192.168.99.100", - "ip": "172.17.0.7", - "name": "wise-lynx-jenkins-1616735317-svn6k", + "ip": "172.17.0.2", + "name": "tiller-deploy-3067024529-9lpmb", "status": { "phase": "running", "ready": "true", diff --git a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.3.0.expected index b8ffd59a24ba..b47439bb83e9 100644 --- a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.3.0.expected @@ -2,17 +2,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "172.17.0.5", - "name": "kube-state-metrics-6479d88c5c-5b6cl", + "ip": "10.0.2.15", + "name": "kube-scheduler-minikube", "status": { "phase": "running", "ready": "true", @@ -33,9 +31,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -43,7 +39,7 @@ "MetricSetFields": { "host_ip": "10.0.2.15", "ip": "10.0.2.15", - "name": "kube-proxy-znhg6", + "name": "kube-apiserver-minikube", "status": { "phase": "running", "ready": "true", @@ -64,9 +60,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -74,7 +68,7 @@ "MetricSetFields": { "host_ip": "10.0.2.15", "ip": "10.0.2.15", - "name": "kube-controller-manager-minikube", + "name": "kube-addon-manager-minikube", "status": { "phase": "running", "ready": "true", @@ -95,17 +89,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "10.0.2.15", - "name": "storage-provisioner", + "ip": "172.17.0.3", + "name": "kubernetes-dashboard-77d8b98585-vqtzm", "status": { "phase": "running", "ready": "true", @@ -126,17 +118,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "10.0.2.15", - "name": "etcd-minikube", + "ip": "172.17.0.2", + "name": "kube-dns-6f4fd4bdf-wlmht", "status": { "phase": "running", "ready": "true", @@ -157,17 +147,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "172.17.0.2", - "name": "kube-dns-6f4fd4bdf-wlmht", + "ip": "10.0.2.15", + "name": "kube-controller-manager-minikube", "status": { "phase": "running", "ready": "true", @@ -188,17 +176,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "172.17.0.3", - "name": "kubernetes-dashboard-77d8b98585-vqtzm", + "ip": "10.0.2.15", + "name": "storage-provisioner", "status": { "phase": "running", "ready": "true", @@ -219,9 +205,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -229,7 +213,7 @@ "MetricSetFields": { "host_ip": "10.0.2.15", "ip": "10.0.2.15", - "name": "kube-scheduler-minikube", + "name": "etcd-minikube", "status": { "phase": "running", "ready": "true", @@ -250,17 +234,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "10.0.2.15", - "ip": "10.0.2.15", - "name": "kube-addon-manager-minikube", + "ip": "172.17.0.5", + "name": "kube-state-metrics-6479d88c5c-5b6cl", "status": { "phase": "running", "ready": "true", @@ -281,9 +263,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -291,7 +271,7 @@ "MetricSetFields": { "host_ip": "10.0.2.15", "ip": "10.0.2.15", - "name": "kube-apiserver-minikube", + "name": "kube-proxy-znhg6", "status": { "phase": "running", "ready": "true", diff --git a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.8.0.expected index 8e4e7e974171..3048bed3e487 100644 --- a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v1.8.0.expected @@ -2,20 +2,18 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "192.168.64.6", - "name": "kube-scheduler-minikube", + "ip": "172.17.0.7", + "name": "hello-1578512100-vr7wj", "status": { - "phase": "running", - "ready": "true", + "phase": "succeeded", + "ready": "false", "scheduled": "true" } }, @@ -33,17 +31,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.6", - "name": "web-1", + "ip": "192.168.64.6", + "name": "etcd-minikube", "status": { "phase": "running", "ready": "true", @@ -64,17 +60,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "192.168.64.6", - "name": "kube-addon-manager-minikube", + "ip": "172.17.0.6", + "name": "web-1", "status": { "phase": "running", "ready": "true", @@ -95,17 +89,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.3", - "name": "coredns-5644d7b6d9-k6wsp", + "ip": "172.17.0.2", + "name": "coredns-5644d7b6d9-fhwjd", "status": { "phase": "running", "ready": "true", @@ -126,17 +118,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "192.168.64.6", - "name": "storage-provisioner", + "ip": "172.17.0.5", + "name": "web-0", "status": { "phase": "running", "ready": "true", @@ -157,9 +147,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -167,7 +155,7 @@ "MetricSetFields": { "host_ip": "192.168.64.6", "ip": "192.168.64.6", - "name": "kube-controller-manager-minikube", + "name": "kube-proxy-dwg6l", "status": { "phase": "running", "ready": "true", @@ -188,9 +176,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -198,7 +184,7 @@ "MetricSetFields": { "host_ip": "192.168.64.6", "ip": "192.168.64.6", - "name": "kube-apiserver-minikube", + "name": "kube-scheduler-minikube", "status": { "phase": "running", "ready": "true", @@ -219,17 +205,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.4", - "name": "kube-state-metrics-898d4db8d-dqmtg", + "ip": "192.168.64.6", + "name": "kube-addon-manager-minikube", "status": { "phase": "running", "ready": "true", @@ -250,17 +234,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.5", - "name": "web-0", + "ip": "172.17.0.3", + "name": "coredns-5644d7b6d9-k6wsp", "status": { "phase": "running", "ready": "true", @@ -281,9 +263,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } @@ -291,7 +271,7 @@ "MetricSetFields": { "host_ip": "192.168.64.6", "ip": "192.168.64.6", - "name": "kube-proxy-dwg6l", + "name": "storage-provisioner", "status": { "phase": "running", "ready": "true", @@ -312,20 +292,18 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.7", - "name": "hello-1578512100-vr7wj", + "ip": "192.168.64.6", + "name": "kube-controller-manager-minikube", "status": { - "phase": "succeeded", - "ready": "false", + "phase": "running", + "ready": "true", "scheduled": "true" } }, @@ -343,17 +321,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "172.17.0.2", - "name": "coredns-5644d7b6d9-fhwjd", + "ip": "192.168.64.6", + "name": "kube-apiserver-minikube", "status": { "phase": "running", "ready": "true", @@ -374,17 +350,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" } }, "MetricSetFields": { "host_ip": "192.168.64.6", - "ip": "192.168.64.6", - "name": "etcd-minikube", + "ip": "172.17.0.4", + "name": "kube-state-metrics-898d4db8d-dqmtg", "status": { "phase": "running", "ready": "true", diff --git a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v2.0.0.expected index 865ffcf64496..9ee91db17f40 100644 --- a/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_pod/_meta/test/ksm.v2.0.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-worker" } @@ -12,7 +10,7 @@ "MetricSetFields": { "host_ip": "172.20.0.4", "ip": "172.20.0.4", - "name": "metricbeat-bvr2v", + "name": "kube-proxy-22znl", "status": { "phase": "running", "ready": "true", @@ -33,17 +31,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "default", "node": { - "name": "kind-worker" + "name": "kind-worker2" } }, "MetricSetFields": { - "host_ip": "172.20.0.4", - "ip": "10.244.2.3", - "name": "hello-python-566b5479f5-ndwdl", + "host_ip": "172.20.0.3", + "ip": "10.244.1.2", + "name": "redis", "status": { "phase": "running", "ready": "true", @@ -64,17 +60,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" } }, "MetricSetFields": { "host_ip": "172.20.0.2", - "ip": "172.20.0.2", - "name": "kube-proxy-cm525", + "ip": "10.244.0.3", + "name": "coredns-5644d7b6d9-zgdsx", "status": { "phase": "running", "ready": "true", @@ -95,17 +89,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" } }, "MetricSetFields": { "host_ip": "172.20.0.2", - "ip": "172.20.0.2", - "name": "kube-scheduler-kind-control-plane", + "ip": "10.244.0.2", + "name": "coredns-5644d7b6d9-nnwmb", "status": { "phase": "running", "ready": "true", @@ -126,17 +118,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-worker" } }, "MetricSetFields": { - "host_ip": "172.20.0.3", - "ip": "172.20.0.3", - "name": "metricbeat-55fp7", + "host_ip": "172.20.0.4", + "ip": "172.20.0.4", + "name": "kindnet-9fgst", "status": { "phase": "running", "ready": "true", @@ -157,17 +147,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { "name": "kind-worker2" } }, "MetricSetFields": { "host_ip": "172.20.0.3", - "ip": "10.244.1.2", - "name": "redis", + "ip": "172.20.0.3", + "name": "kube-proxy-lf6md", "status": { "phase": "running", "ready": "true", @@ -188,17 +176,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker" + "name": "kind-control-plane" } }, "MetricSetFields": { - "host_ip": "172.20.0.4", - "ip": "10.244.2.2", - "name": "kube-state-metrics-f655d484d-hj69w", + "host_ip": "172.20.0.2", + "ip": "172.20.0.2", + "name": "kube-controller-manager-kind-control-plane", "status": { "phase": "running", "ready": "true", @@ -219,9 +205,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" } @@ -229,7 +213,7 @@ "MetricSetFields": { "host_ip": "172.20.0.2", "ip": "172.20.0.2", - "name": "kindnet-kch2v", + "name": "kube-apiserver-kind-control-plane", "status": { "phase": "running", "ready": "true", @@ -250,17 +234,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-control-plane" } }, "MetricSetFields": { - "host_ip": "172.20.0.3", - "ip": "172.20.0.3", - "name": "kindnet-tg7tl", + "host_ip": "172.20.0.2", + "ip": "172.20.0.2", + "name": "etcd-kind-control-plane", "status": { "phase": "running", "ready": "true", @@ -281,17 +263,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "kind-worker" } }, "MetricSetFields": { "host_ip": "172.20.0.4", - "ip": "172.20.0.4", - "name": "kindnet-9fgst", + "ip": "10.244.2.3", + "name": "hello-python-566b5479f5-ndwdl", "status": { "phase": "running", "ready": "true", @@ -312,9 +292,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "kind-control-plane" } @@ -322,7 +300,7 @@ "MetricSetFields": { "host_ip": "172.20.0.2", "ip": "172.20.0.2", - "name": "kube-controller-manager-kind-control-plane", + "name": "kube-proxy-cm525", "status": { "phase": "running", "ready": "true", @@ -343,17 +321,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "local-path-storage", "node": { "name": "kind-control-plane" } }, "MetricSetFields": { "host_ip": "172.20.0.2", - "ip": "172.20.0.2", - "name": "kube-apiserver-kind-control-plane", + "ip": "10.244.0.4", + "name": "local-path-provisioner-5bf465b47d-h8hjn", "status": { "phase": "running", "ready": "true", @@ -374,17 +350,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker" } }, "MetricSetFields": { - "host_ip": "172.20.0.2", - "ip": "172.20.0.2", - "name": "etcd-kind-control-plane", + "host_ip": "172.20.0.4", + "ip": "10.244.2.2", + "name": "kube-state-metrics-f655d484d-hj69w", "status": { "phase": "running", "ready": "true", @@ -405,20 +379,18 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker" + "name": "kind-control-plane" } }, "MetricSetFields": { - "host_ip": "172.20.0.3", - "ip": "10.244.2.2", - "name": "hello-zf6gh", + "host_ip": "172.20.0.2", + "ip": "172.20.0.2", + "name": "kube-scheduler-kind-control-plane", "status": { - "phase": "succeeded", - "ready": "false", + "phase": "running", + "ready": "true", "scheduled": "true" } }, @@ -436,20 +408,18 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "default", "node": { "name": "kind-worker" } }, "MetricSetFields": { - "host_ip": "172.20.0.4", - "ip": "172.20.0.4", - "name": "kube-proxy-22znl", + "host_ip": "172.20.0.3", + "ip": "10.244.2.2", + "name": "hello-zf6gh", "status": { - "phase": "running", - "ready": "true", + "phase": "succeeded", + "ready": "false", "scheduled": "true" } }, @@ -467,17 +437,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-worker2" + "name": "kind-control-plane" } }, "MetricSetFields": { - "host_ip": "172.20.0.3", - "ip": "172.20.0.3", - "name": "kube-proxy-lf6md", + "host_ip": "172.20.0.2", + "ip": "172.20.0.2", + "name": "kindnet-kch2v", "status": { "phase": "running", "ready": "true", @@ -498,17 +466,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "local-path-storage" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker2" } }, "MetricSetFields": { - "host_ip": "172.20.0.2", - "ip": "10.244.0.4", - "name": "local-path-provisioner-5bf465b47d-h8hjn", + "host_ip": "172.20.0.3", + "ip": "172.20.0.3", + "name": "metricbeat-55fp7", "status": { "phase": "running", "ready": "true", @@ -529,17 +495,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker" } }, "MetricSetFields": { - "host_ip": "172.20.0.2", - "ip": "10.244.0.3", - "name": "coredns-5644d7b6d9-zgdsx", + "host_ip": "172.20.0.4", + "ip": "172.20.0.4", + "name": "metricbeat-bvr2v", "status": { "phase": "running", "ready": "true", @@ -560,17 +524,15 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { - "name": "kind-control-plane" + "name": "kind-worker2" } }, "MetricSetFields": { - "host_ip": "172.20.0.2", - "ip": "10.244.0.2", - "name": "coredns-5644d7b6d9-nnwmb", + "host_ip": "172.20.0.3", + "ip": "172.20.0.3", + "name": "kindnet-tg7tl", "status": { "phase": "running", "ready": "true", diff --git a/metricbeat/module/kubernetes/state_pod/_meta/testdata/docs.plain-expected.json b/metricbeat/module/kubernetes/state_pod/_meta/testdata/docs.plain-expected.json index 7816dfea70f8..09de4a43609d 100644 --- a/metricbeat/module/kubernetes/state_pod/_meta/testdata/docs.plain-expected.json +++ b/metricbeat/module/kubernetes/state_pod/_meta/testdata/docs.plain-expected.json @@ -6,16 +6,14 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "jenkins" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { "host_ip": "192.168.99.100", - "ip": "172.17.0.7", - "name": "wise-lynx-jenkins-1616735317-svn6k", + "ip": "172.17.0.2", + "name": "tiller-deploy-3067024529-9lpmb", "status": { "phase": "running", "ready": "true", @@ -39,16 +37,14 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { "host_ip": "192.168.99.100", - "ip": "172.17.0.6", - "name": "kube-dns-v20-5g5cb", + "ip": "172.17.0.3", + "name": "kube-state-metrics-1303537707-7ncd1", "status": { "phase": "running", "ready": "true", @@ -72,9 +68,7 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "default" - }, + "namespace": "default", "node": { "name": "minikube" }, @@ -105,20 +99,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "test", "node": { - "name": "minikube" + "name": "minikube-test" }, "pod": { - "host_ip": "192.168.99.100", - "ip": "172.17.0.3", - "name": "kube-state-metrics-1303537707-7ncd1", + "host_ip": "192.168.99.200", + "ip": "172.17.0.5", + "name": "jumpy-owl-redis-3481028193-s78x9", "status": { "phase": "running", "ready": "true", - "scheduled": "true" + "scheduled": "false" } } }, @@ -138,14 +130,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" + "namespace": "jenkins", + "node": { + "name": "minikube" }, "pod": { - "name": "kube-state-metrics-1303537707-mnzbp", + "host_ip": "192.168.99.100", + "ip": "172.17.0.7", + "name": "wise-lynx-jenkins-1616735317-svn6k", "status": { - "phase": "pending", - "scheduled": "false" + "phase": "running", + "ready": "true", + "scheduled": "true" } } }, @@ -165,20 +161,12 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, - "node": { - "name": "minikube" - }, + "namespace": "kube-system", "pod": { - "host_ip": "192.168.99.100", - "ip": "172.17.0.5", - "name": "kubernetes-dashboard-vw0l6", + "name": "kube-state-metrics-1303537707-mnzbp", "status": { - "phase": "running", - "ready": "true", - "scheduled": "true" + "phase": "pending", + "scheduled": "false" } } }, @@ -198,20 +186,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "test" - }, + "namespace": "kube-system", "node": { - "name": "minikube-test" + "name": "minikube" }, "pod": { - "host_ip": "192.168.99.200", - "ip": "172.17.0.5", - "name": "jumpy-owl-redis-3481028193-s78x9", + "host_ip": "192.168.99.100", + "ip": "172.17.0.6", + "name": "kube-dns-v20-5g5cb", "status": { "phase": "running", "ready": "true", - "scheduled": "false" + "scheduled": "true" } } }, @@ -231,16 +217,14 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, "pod": { "host_ip": "192.168.99.100", - "ip": "172.17.0.2", - "name": "tiller-deploy-3067024529-9lpmb", + "ip": "172.17.0.5", + "name": "kubernetes-dashboard-vw0l6", "status": { "phase": "running", "ready": "true", @@ -264,9 +248,7 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "node": { "name": "minikube" }, diff --git a/metricbeat/module/kubernetes/state_pod/state_pod.go b/metricbeat/module/kubernetes/state_pod/state_pod.go index e4bd290850b4..ea742ab26bd1 100644 --- a/metricbeat/module/kubernetes/state_pod/state_pod.go +++ b/metricbeat/module/kubernetes/state_pod/state_pod.go @@ -49,7 +49,7 @@ var ( Labels: map[string]p.LabelMap{ "pod": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "node": p.Label(mb.ModuleDataKey + ".node.name"), "pod_ip": p.Label("ip"), diff --git a/metricbeat/module/kubernetes/state_replicaset/_meta/data.json b/metricbeat/module/kubernetes/state_replicaset/_meta/data.json index 0c1091c8ad5c..f4441104d6bf 100644 --- a/metricbeat/module/kubernetes/state_replicaset/_meta/data.json +++ b/metricbeat/module/kubernetes/state_replicaset/_meta/data.json @@ -6,17 +6,15 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "jenkins" - }, + "namespace": "default", "replicaset": { - "name": "wise-lynx-jenkins-1616735317", + "name": "jumpy-owl-redis-3481028193", "replicas": { "available": 1, "desired": 1, "labeled": 1, "observed": 1, - "ready": 1 + "ready": 0 } } }, diff --git a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.3.0.expected index c8a26911c7b8..1705a5a87dc3 100644 --- a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.3.0.expected @@ -2,12 +2,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-state-metrics-6479d88c5c", + "name": "kubernetes-dashboard-77d8b98585", "replicas": { "available": 1, "desired": 1, @@ -30,18 +28,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-state-metrics-86dd856df7", + "name": "kube-state-metrics-6479d88c5c", "replicas": { - "available": 0, - "desired": 0, - "labeled": 0, - "observed": 2, - "ready": 0 + "available": 1, + "desired": 1, + "labeled": 1, + "observed": 1, + "ready": 1 } }, "Index": "", @@ -58,9 +54,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "name": "kube-dns-6f4fd4bdf", @@ -86,18 +80,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kubernetes-dashboard-77d8b98585", + "name": "kube-state-metrics-86dd856df7", "replicas": { - "available": 1, - "desired": 1, - "labeled": 1, - "observed": 1, - "ready": 1 + "available": 0, + "desired": 0, + "labeled": 0, + "observed": 2, + "ready": 0 } }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.8.0.expected index 9cc72c20d214..d292785f4589 100644 --- a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v1.8.0.expected @@ -2,18 +2,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "kube-state-metrics-898d4db8d", + "name": "coredns-5644d7b6d9", "replicas": { - "available": 1, - "desired": 1, - "labeled": 1, + "available": 2, + "desired": 2, + "labeled": 2, "observed": 1, - "ready": 1 + "ready": 2 } }, "Index": "", @@ -30,18 +28,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "coredns-5644d7b6d9", + "name": "kube-state-metrics-898d4db8d", "replicas": { - "available": 2, - "desired": 2, - "labeled": 2, + "available": 1, + "desired": 1, + "labeled": 1, "observed": 1, - "ready": 2 + "ready": 1 } }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v2.0.0.expected index 229e8e3f5dbb..fb06db2106b0 100644 --- a/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_replicaset/_meta/test/ksm.v2.0.0.expected @@ -2,12 +2,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "hello-python-566b5479f5", + "name": "kube-state-metrics-f655d484d", "replicas": { "available": 1, "desired": 1, @@ -30,18 +28,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "default" }, "MetricSetFields": { - "name": "coredns-5644d7b6d9", + "name": "hello-python-566b5479f5", "replicas": { - "available": 2, - "desired": 2, - "labeled": 2, + "available": 1, + "desired": 1, + "labeled": 1, "observed": 1, - "ready": 2 + "ready": 1 } }, "Index": "", @@ -58,18 +54,16 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "local-path-storage" - } + "namespace": "kube-system" }, "MetricSetFields": { - "name": "local-path-provisioner-5bf465b47d", + "name": "coredns-5644d7b6d9", "replicas": { - "available": 1, - "desired": 1, - "labeled": 1, + "available": 2, + "desired": 2, + "labeled": 2, "observed": 1, - "ready": 1 + "ready": 2 } }, "Index": "", @@ -86,12 +80,10 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "local-path-storage" }, "MetricSetFields": { - "name": "kube-state-metrics-f655d484d", + "name": "local-path-provisioner-5bf465b47d", "replicas": { "available": 1, "desired": 1, diff --git a/metricbeat/module/kubernetes/state_replicaset/_meta/testdata/docs.plain-expected.json b/metricbeat/module/kubernetes/state_replicaset/_meta/testdata/docs.plain-expected.json index 72df48f77e8c..cfdafbd4cc39 100644 --- a/metricbeat/module/kubernetes/state_replicaset/_meta/testdata/docs.plain-expected.json +++ b/metricbeat/module/kubernetes/state_replicaset/_meta/testdata/docs.plain-expected.json @@ -6,17 +6,15 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "jenkins" - }, + "namespace": "default", "replicaset": { - "name": "wise-lynx-jenkins-1616735317", + "name": "jumpy-owl-redis-3481028193", "replicas": { "available": 1, "desired": 1, "labeled": 1, "observed": 1, - "ready": 1 + "ready": 0 } } }, @@ -36,17 +34,15 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "test", "replicaset": { - "name": "tiller-deploy-3067024529", + "name": "kube-state-metrics-1303537707", "replicas": { - "available": 1, - "desired": 1, - "labeled": 1, - "observed": 1, - "ready": 1 + "available": 7, + "desired": 3, + "labeled": 4, + "observed": 5, + "ready": 6 } } }, @@ -66,17 +62,15 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "test" - }, + "namespace": "kube-system", "replicaset": { "name": "kube-state-metrics-1303537707", "replicas": { - "available": 7, - "desired": 3, - "labeled": 4, - "observed": 5, - "ready": 6 + "available": 2, + "desired": 2, + "labeled": 2, + "observed": 1, + "ready": 1 } } }, @@ -96,17 +90,15 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "default" - }, + "namespace": "jenkins", "replicaset": { - "name": "jumpy-owl-redis-3481028193", + "name": "wise-lynx-jenkins-1616735317", "replicas": { "available": 1, "desired": 1, "labeled": 1, "observed": 1, - "ready": 0 + "ready": 1 } } }, @@ -126,15 +118,13 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "kube-system" - }, + "namespace": "kube-system", "replicaset": { - "name": "kube-state-metrics-1303537707", + "name": "tiller-deploy-3067024529", "replicas": { - "available": 2, - "desired": 2, - "labeled": 2, + "available": 1, + "desired": 1, + "labeled": 1, "observed": 1, "ready": 1 } diff --git a/metricbeat/module/kubernetes/state_replicaset/state_replicaset.go b/metricbeat/module/kubernetes/state_replicaset/state_replicaset.go index 5a28a237a771..7ee8e62864ae 100644 --- a/metricbeat/module/kubernetes/state_replicaset/state_replicaset.go +++ b/metricbeat/module/kubernetes/state_replicaset/state_replicaset.go @@ -51,7 +51,7 @@ var ( Labels: map[string]p.LabelMap{ "replicaset": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), }, } ) diff --git a/metricbeat/module/kubernetes/state_resourcequota/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_resourcequota/_meta/test/ksm.v1.8.0.expected index 5946cf6c8cb8..071423392dc7 100644 --- a/metricbeat/module/kubernetes/state_resourcequota/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_resourcequota/_meta/test/ksm.v1.8.0.expected @@ -2,14 +2,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 20, - "resource": "replicationcontrollers", + "quota": 10, + "resource": "services", "type": "hard" }, "Index": "", @@ -26,15 +24,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 4, - "resource": "pods", - "type": "hard" + "quota": 0, + "resource": "replicationcontrollers", + "type": "used" }, "Index": "", "ID": "", @@ -50,15 +46,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", - "quota": 10, - "resource": "configmaps", - "type": "hard" + "name": "compute-resources", + "quota": 0, + "resource": "requests.memory", + "type": "used" }, "Index": "", "ID": "", @@ -74,15 +68,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", - "quota": 4, - "resource": "persistentvolumeclaims", - "type": "hard" + "created": { + "sec": 1578507202 + }, + "name": "compute-resources" }, "Index": "", "ID": "", @@ -98,14 +90,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "compute-resources", - "quota": 1073741824, - "resource": "requests.memory", + "quota": 2147483648, + "resource": "limits.memory", "type": "hard" }, "Index": "", @@ -122,15 +112,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 0, + "quota": 4, "resource": "persistentvolumeclaims", - "type": "used" + "type": "hard" }, "Index": "", "ID": "", @@ -146,15 +134,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "compute-resources", - "quota": 0, - "resource": "limits.memory", - "type": "used" + "quota": 1073741824, + "resource": "requests.memory", + "type": "hard" }, "Index": "", "ID": "", @@ -170,15 +156,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 10, - "resource": "services", - "type": "hard" + "quota": 0, + "resource": "persistentvolumeclaims", + "type": "used" }, "Index": "", "ID": "", @@ -194,15 +178,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 0, - "resource": "requests.memory", - "type": "used" + "name": "object-counts", + "quota": 4, + "resource": "pods", + "type": "hard" }, "Index": "", "ID": "", @@ -218,15 +200,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 0, + "quota": 20, "resource": "replicationcontrollers", - "type": "used" + "type": "hard" }, "Index": "", "ID": "", @@ -242,14 +222,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 2147483648, - "resource": "limits.memory", + "name": "object-counts", + "quota": 10, + "resource": "configmaps", "type": "hard" }, "Index": "", @@ -266,15 +244,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "created": { - "sec": 1578507202 - }, - "name": "compute-resources" + "name": "compute-resources", + "quota": 0, + "resource": "limits.memory", + "type": "used" }, "Index": "", "ID": "", @@ -290,15 +266,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "created": { - "sec": 1578507217 - }, - "name": "object-counts" + "name": "object-counts", + "quota": 10, + "resource": "secrets", + "type": "hard" }, "Index": "", "ID": "", @@ -314,14 +288,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", + "name": "object-counts", "quota": 0, - "resource": "requests.nvidia.com/gpu", + "resource": "services", "type": "used" }, "Index": "", @@ -338,15 +310,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 1, - "resource": "secrets", - "type": "used" + "quota": 2, + "resource": "services.loadbalancers", + "type": "hard" }, "Index": "", "ID": "", @@ -362,14 +332,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", + "name": "compute-resources", "quota": 0, - "resource": "pods", + "resource": "limits.cpu", "type": "used" }, "Index": "", @@ -386,15 +354,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 1, - "resource": "requests.cpu", - "type": "hard" + "name": "object-counts", + "quota": 0, + "resource": "configmaps", + "type": "used" }, "Index": "", "ID": "", @@ -410,15 +376,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 4, - "resource": "requests.nvidia.com/gpu", - "type": "hard" + "name": "object-counts", + "quota": 1, + "resource": "secrets", + "type": "used" }, "Index": "", "ID": "", @@ -434,15 +398,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 2, - "resource": "limits.cpu", - "type": "hard" + "name": "object-counts", + "quota": 0, + "resource": "pods", + "type": "used" }, "Index": "", "ID": "", @@ -458,14 +420,12 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", + "name": "compute-resources", "quota": 0, - "resource": "services.loadbalancers", + "resource": "requests.nvidia.com/gpu", "type": "used" }, "Index": "", @@ -482,15 +442,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "compute-resources", - "quota": 0, - "resource": "requests.cpu", - "type": "used" + "created": { + "sec": 1578507217 + }, + "name": "object-counts" }, "Index": "", "ID": "", @@ -506,15 +464,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "object-counts", - "quota": 10, - "resource": "secrets", - "type": "hard" + "quota": 0, + "resource": "services.loadbalancers", + "type": "used" }, "Index": "", "ID": "", @@ -530,15 +486,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", - "quota": 0, - "resource": "services", - "type": "used" + "name": "compute-resources", + "quota": 2, + "resource": "limits.cpu", + "type": "hard" }, "Index": "", "ID": "", @@ -554,15 +508,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", - "quota": 2, - "resource": "services.loadbalancers", - "type": "hard" + "name": "compute-resources", + "quota": 0, + "resource": "requests.cpu", + "type": "used" }, "Index": "", "ID": "", @@ -578,15 +530,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { - "name": "object-counts", - "quota": 0, - "resource": "configmaps", - "type": "used" + "name": "compute-resources", + "quota": 1, + "resource": "requests.cpu", + "type": "hard" }, "Index": "", "ID": "", @@ -602,15 +552,13 @@ { "RootFields": {}, "ModuleFields": { - "namespace": { - "name": "myspace" - } + "namespace": "myspace" }, "MetricSetFields": { "name": "compute-resources", - "quota": 0, - "resource": "limits.cpu", - "type": "used" + "quota": 4, + "resource": "requests.nvidia.com/gpu", + "type": "hard" }, "Index": "", "ID": "", diff --git a/metricbeat/module/kubernetes/state_resourcequota/state_resourcequota.go b/metricbeat/module/kubernetes/state_resourcequota/state_resourcequota.go index 5fb72e5b5773..eb8bc6ddf352 100644 --- a/metricbeat/module/kubernetes/state_resourcequota/state_resourcequota.go +++ b/metricbeat/module/kubernetes/state_resourcequota/state_resourcequota.go @@ -63,7 +63,7 @@ func NewResourceQuotaMetricSet(base mb.BaseMetricSet) (mb.MetricSet, error) { "kube_resourcequota": p.Metric("quota"), }, Labels: map[string]p.LabelMap{ - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "resourcequota": p.KeyLabel("name"), "resource": p.KeyLabel("resource"), diff --git a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.unit.v1.8.0.expected b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.unit.v1.8.0.expected index 8f34da5871bd..d0c0c46a4ad7 100644 --- a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.unit.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.unit.v1.8.0.expected @@ -3,17 +3,15 @@ "RootFields": null, "ModuleFields": { "labels": { - "app": "example4" + "app": "example2" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { + "cluster_ip": "1.2.3.5", "created": "2017-07-14T02:40:00.000Z", - "external_name": "www.example.com", - "name": "test-service4", - "type": "ExternalName" + "name": "test-service2", + "type": "NodePort" }, "Index": "", "ID": "", @@ -30,17 +28,16 @@ "RootFields": null, "ModuleFields": { "labels": { - "app": "example2" + "app": "example3" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { - "cluster_ip": "1.2.3.5", + "cluster_ip": "1.2.3.6", "created": "2017-07-14T02:40:00.000Z", - "name": "test-service2", - "type": "NodePort" + "load_balancer_ip": "1.2.3.7", + "name": "test-service3", + "type": "LoadBalancer" }, "Index": "", "ID": "", @@ -57,17 +54,15 @@ "RootFields": null, "ModuleFields": { "labels": { - "app": "example3" + "app": "example5" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { - "cluster_ip": "1.2.3.6", "created": "2017-07-14T02:40:00.000Z", - "load_balancer_ip": "1.2.3.7", - "name": "test-service3", + "ingress_hostname": "www.example.com", + "ingress_ip": "1.2.3.8", + "name": "test-service5", "type": "LoadBalancer" }, "Index": "", @@ -85,18 +80,15 @@ "RootFields": null, "ModuleFields": { "labels": { - "app": "example5" + "app": "example4" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "created": "2017-07-14T02:40:00.000Z", - "ingress_hostname": "www.example.com", - "ingress_ip": "1.2.3.8", - "name": "test-service5", - "type": "LoadBalancer" + "external_name": "www.example.com", + "name": "test-service4", + "type": "ExternalName" }, "Index": "", "ID": "", @@ -115,9 +107,7 @@ "labels": { "app": "example6" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "created": "2017-07-14T02:40:00.000Z", @@ -142,9 +132,7 @@ "labels": { "app": "example1" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "cluster_ip": "1.2.3.4", diff --git a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.3.0.expected b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.3.0.expected index 8921833ee55d..5717193d8a25 100644 --- a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.3.0.expected +++ b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.3.0.expected @@ -3,19 +3,18 @@ "RootFields": null, "ModuleFields": { "labels": { - "k8s_app": "kube-dns", - "kubernetes_io_cluster_service": "true", - "kubernetes_io_name": "KubeDNS" + "addonmanager_kubernetes_io_mode": "Reconcile", + "app": "kubernetes-dashboard", + "kubernetes_io_minikube_addons": "dashboard", + "kubernetes_io_minikube_addons_endpoint": "dashboard" }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "cluster_ip": "10.96.0.10", - "created": "2018-05-30T16:24:36.000Z", - "name": "kube-dns", - "type": "ClusterIP" + "cluster_ip": "10.109.175.127", + "created": "2018-05-30T16:24:44.000Z", + "name": "kubernetes-dashboard", + "type": "NodePort" }, "Index": "", "ID": "", @@ -32,17 +31,16 @@ "RootFields": null, "ModuleFields": { "labels": { - "component": "apiserver", - "provider": "kubernetes" + "k8s_app": "kube-dns", + "kubernetes_io_cluster_service": "true", + "kubernetes_io_name": "KubeDNS" }, - "namespace": { - "name": "default" - } + "namespace": "kube-system" }, "MetricSetFields": { - "cluster_ip": "10.96.0.1", - "created": "2018-05-30T16:24:29.000Z", - "name": "kubernetes", + "cluster_ip": "10.96.0.10", + "created": "2018-05-30T16:24:36.000Z", + "name": "kube-dns", "type": "ClusterIP" }, "Index": "", @@ -60,20 +58,16 @@ "RootFields": null, "ModuleFields": { "labels": { - "addonmanager_kubernetes_io_mode": "Reconcile", - "app": "kubernetes-dashboard", - "kubernetes_io_minikube_addons": "dashboard", - "kubernetes_io_minikube_addons_endpoint": "dashboard" + "component": "apiserver", + "provider": "kubernetes" }, - "namespace": { - "name": "kube-system" - } + "namespace": "default" }, "MetricSetFields": { - "cluster_ip": "10.109.175.127", - "created": "2018-05-30T16:24:44.000Z", - "name": "kubernetes-dashboard", - "type": "NodePort" + "cluster_ip": "10.96.0.1", + "created": "2018-05-30T16:24:29.000Z", + "name": "kubernetes", + "type": "ClusterIP" }, "Index": "", "ID": "", @@ -92,9 +86,7 @@ "labels": { "k8s_app": "kube-state-metrics" }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "cluster_ip": "10.108.182.194", diff --git a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.8.0.expected index d56cabf40b5e..9e7b4c7cd3b1 100644 --- a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v1.8.0.expected @@ -5,9 +5,7 @@ "labels": { "k8s_app": "kube-state-metrics" }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "cluster_ip": "10.101.63.187", @@ -34,9 +32,7 @@ "kubernetes_io_cluster_service": "true", "kubernetes_io_name": "KubeDNS" }, - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { "cluster_ip": "10.96.0.10", @@ -59,17 +55,14 @@ "RootFields": null, "ModuleFields": { "labels": { - "component": "apiserver", - "provider": "kubernetes" + "app": "nginx" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { - "cluster_ip": "10.96.0.1", - "created": "2020-01-07T16:11:02.000Z", - "name": "kubernetes", + "cluster_ip": "None", + "created": "2020-01-08T18:15:25.000Z", + "name": "nginx", "type": "ClusterIP" }, "Index": "", @@ -87,16 +80,15 @@ "RootFields": null, "ModuleFields": { "labels": { - "app": "nginx" + "component": "apiserver", + "provider": "kubernetes" }, - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { - "cluster_ip": "None", - "created": "2020-01-08T18:15:25.000Z", - "name": "nginx", + "cluster_ip": "10.96.0.1", + "created": "2020-01-07T16:11:02.000Z", + "name": "kubernetes", "type": "ClusterIP" }, "Index": "", diff --git a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v2.0.0.expected b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v2.0.0.expected index 58c5637cf15d..096ec78662dd 100644 --- a/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_service/_meta/test/ksm.v2.0.0.expected @@ -2,14 +2,12 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "cluster_ip": "None", - "created": "2021-08-23T13:04:03.000Z", - "name": "kube-state-metrics", + "cluster_ip": "10.96.0.10", + "created": "2021-08-12T14:24:46.000Z", + "name": "kube-dns", "type": "ClusterIP" }, "Index": "", @@ -26,14 +24,12 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "kube-system" - } + "namespace": "kube-system" }, "MetricSetFields": { - "cluster_ip": "10.96.0.10", - "created": "2021-08-12T14:24:46.000Z", - "name": "kube-dns", + "cluster_ip": "None", + "created": "2021-08-23T13:04:03.000Z", + "name": "kube-state-metrics", "type": "ClusterIP" }, "Index": "", @@ -50,9 +46,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "cluster_ip": "10.96.0.1", diff --git a/metricbeat/module/kubernetes/state_service/state_service.go b/metricbeat/module/kubernetes/state_service/state_service.go index e46ab08623af..6794c36c44f7 100644 --- a/metricbeat/module/kubernetes/state_service/state_service.go +++ b/metricbeat/module/kubernetes/state_service/state_service.go @@ -75,7 +75,7 @@ func NewServiceMetricSet(base mb.BaseMetricSet) (mb.MetricSet, error) { "kube_service_status_load_balancer_ingress": p.InfoMetric(), }, Labels: map[string]p.LabelMap{ - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), "service": p.KeyLabel("name"), "cluster_ip": p.Label("cluster_ip"), "external_name": p.Label("external_name"), diff --git a/metricbeat/module/kubernetes/state_statefulset/_meta/data.json b/metricbeat/module/kubernetes/state_statefulset/_meta/data.json index 96a170777923..776b4a48d937 100644 --- a/metricbeat/module/kubernetes/state_statefulset/_meta/data.json +++ b/metricbeat/module/kubernetes/state_statefulset/_meta/data.json @@ -6,20 +6,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "default" - }, + "namespace": "default", "statefulset": { - "created": 1511973651, + "created": 1511989697, "generation": { - "desired": 3, - "observed": 1 + "desired": 4, + "observed": 2 }, - "name": "elasticsearch", + "name": "mysql", "replicas": { - "desired": 4, - "observed": 1, - "ready": 1 + "desired": 5, + "observed": 2, + "ready": 2 } } }, diff --git a/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.unit.v2.0.0.expected b/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.unit.v2.0.0.expected index d2fe830a9f1d..d55d49a0b855 100644 --- a/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.unit.v2.0.0.expected +++ b/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.unit.v2.0.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "created": 1629966737, diff --git a/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.v1.8.0.expected b/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.v1.8.0.expected index ae8659926a3e..a5c1c584229d 100644 --- a/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.v1.8.0.expected +++ b/metricbeat/module/kubernetes/state_statefulset/_meta/test/ksm.v1.8.0.expected @@ -2,9 +2,7 @@ { "RootFields": null, "ModuleFields": { - "namespace": { - "name": "default" - } + "namespace": "default" }, "MetricSetFields": { "created": 1578507325, diff --git a/metricbeat/module/kubernetes/state_statefulset/_meta/testdata/docs.plain-expected.json b/metricbeat/module/kubernetes/state_statefulset/_meta/testdata/docs.plain-expected.json index ef3ba87ef222..8ab015da0617 100644 --- a/metricbeat/module/kubernetes/state_statefulset/_meta/testdata/docs.plain-expected.json +++ b/metricbeat/module/kubernetes/state_statefulset/_meta/testdata/docs.plain-expected.json @@ -6,20 +6,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "default" - }, + "namespace": "default", "statefulset": { - "created": 1511973651, + "created": 1511989697, "generation": { - "desired": 3, - "observed": 1 + "desired": 4, + "observed": 2 }, - "name": "elasticsearch", + "name": "mysql", "replicas": { - "desired": 4, - "observed": 1, - "ready": 1 + "desired": 5, + "observed": 2, + "ready": 2 } } }, @@ -39,9 +37,7 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "custom" - }, + "namespace": "custom", "statefulset": { "created": 1511999697, "generation": { @@ -72,20 +68,18 @@ "module": "kubernetes" }, "kubernetes": { - "namespace": { - "name": "default" - }, + "namespace": "default", "statefulset": { - "created": 1511989697, + "created": 1511973651, "generation": { - "desired": 4, - "observed": 2 + "desired": 3, + "observed": 1 }, - "name": "mysql", + "name": "elasticsearch", "replicas": { - "desired": 5, - "observed": 2, - "ready": 2 + "desired": 4, + "observed": 1, + "ready": 1 } } }, diff --git a/metricbeat/module/kubernetes/state_statefulset/state_statefulset.go b/metricbeat/module/kubernetes/state_statefulset/state_statefulset.go index 59de9bfeff16..c2c021952065 100644 --- a/metricbeat/module/kubernetes/state_statefulset/state_statefulset.go +++ b/metricbeat/module/kubernetes/state_statefulset/state_statefulset.go @@ -51,7 +51,7 @@ var ( Labels: map[string]p.LabelMap{ "statefulset": p.KeyLabel("name"), - "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace.name"), + "namespace": p.KeyLabel(mb.ModuleDataKey + ".namespace"), }, } ) diff --git a/metricbeat/module/kubernetes/util/kubernetes.go b/metricbeat/module/kubernetes/util/kubernetes.go index 41e0a2bac163..6f4b7c44d281 100644 --- a/metricbeat/module/kubernetes/util/kubernetes.go +++ b/metricbeat/module/kubernetes/util/kubernetes.go @@ -196,7 +196,7 @@ func NewResourceMetadataEnricher( }, // index func(e common.MapStr) string { - return join(getString(e, mb.ModuleDataKey+".namespace.name"), getString(e, "name")) + return join(getString(e, mb.ModuleDataKey+".namespace"), getString(e, "name")) }, ) diff --git a/metricbeat/module/kubernetes/volume/data.go b/metricbeat/module/kubernetes/volume/data.go index 03508a371557..6170bbadbccc 100644 --- a/metricbeat/module/kubernetes/volume/data.go +++ b/metricbeat/module/kubernetes/volume/data.go @@ -40,9 +40,7 @@ func eventMapping(content []byte) ([]common.MapStr, error) { for _, volume := range pod.Volume { volumeEvent := common.MapStr{ mb.ModuleDataKey: common.MapStr{ - "namespace": common.MapStr{ - "name": pod.PodRef.Namespace, - }, + "namespace": pod.PodRef.Namespace, "node": common.MapStr{ "name": node.NodeName, }, diff --git a/metricbeat/module/openmetrics/collector/_meta/data.json b/metricbeat/module/openmetrics/collector/_meta/data.json index 668e6a887512..d60063a9157e 100644 --- a/metricbeat/module/openmetrics/collector/_meta/data.json +++ b/metricbeat/module/openmetrics/collector/_meta/data.json @@ -11,7 +11,7 @@ }, "openmetrics": { "labels": { - "device": "br-33d819d5f834", + "device": "br-3a285aa5e58c", "job": "openmetrics" }, "metrics": { diff --git a/metricbeat/module/prometheus/collector/_meta/data.json b/metricbeat/module/prometheus/collector/_meta/data.json index a46b63c74feb..dba9f7771c45 100644 --- a/metricbeat/module/prometheus/collector/_meta/data.json +++ b/metricbeat/module/prometheus/collector/_meta/data.json @@ -11,10 +11,12 @@ }, "prometheus": { "labels": { - "job": "prometheus" + "job": "prometheus", + "listener_name": "http" }, "metrics": { - "up": 1 + "net_conntrack_listener_conn_accepted_total": 3, + "net_conntrack_listener_conn_closed_total": 0 } }, "service": { diff --git a/packetbeat/docs/fields.asciidoc b/packetbeat/docs/fields.asciidoc index ac1d316d2386..c46253bd0527 100644 --- a/packetbeat/docs/fields.asciidoc +++ b/packetbeat/docs/fields.asciidoc @@ -17610,47 +17610,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/packetbeat/include/fields.go b/packetbeat/include/fields.go index 870da081b5a0..bbd0afc526cd 100644 --- a/packetbeat/include/fields.go +++ b/packetbeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/winlogbeat/docs/fields.asciidoc b/winlogbeat/docs/fields.asciidoc index 27f561dba396..87762a519c6d 100644 --- a/winlogbeat/docs/fields.asciidoc +++ b/winlogbeat/docs/fields.asciidoc @@ -15633,47 +15633,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/winlogbeat/include/fields.go b/winlogbeat/include/fields.go index a89de8466eeb..29bc38bff458 100644 --- a/winlogbeat/include/fields.go +++ b/winlogbeat/include/fields.go @@ -32,5 +32,5 @@ func init() { // AssetBuildFieldsFieldsCommonYml returns asset data. // This is the base64 encoded zlib format compressed contents of build/fields/fields.common.yml. func AssetBuildFieldsFieldsCommonYml() string { - return "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" + return "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" } diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go index 5a7a8c4a392f..735e123b7c0a 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go @@ -247,14 +247,13 @@ func generatePodData( return providerData{} } - ckMeta := kubemetaMap.(common.MapStr).Clone() - if len(namespaceAnnotations) != 0 { - ckMeta.Put("namespace.annotations", namespaceAnnotations) - } // k8sMapping includes only the metadata that fall under kubernetes.* // and these are available as dynamic vars through the provider - k8sMapping := map[string]interface{}(ckMeta) + k8sMapping := map[string]interface{}(kubemetaMap.(common.MapStr).Clone()) + if len(namespaceAnnotations) != 0 { + k8sMapping["namespace_annotations"] = namespaceAnnotations + } // Pass annotations to all events so that it can be used in templating and by annotation builders. annotations := common.MapStr{} for k, v := range pod.GetObjectMeta().GetAnnotations() { @@ -314,14 +313,13 @@ func generateContainerData( continue } - ckMeta := kubemetaMap.(common.MapStr).Clone() - if len(namespaceAnnotations) != 0 { - ckMeta.Put("namespace.annotations", namespaceAnnotations) - } // k8sMapping includes only the metadata that fall under kubernetes.* // and these are available as dynamic vars through the provider - k8sMapping := map[string]interface{}(ckMeta) + k8sMapping := map[string]interface{}(kubemetaMap.(common.MapStr).Clone()) + if len(namespaceAnnotations) != 0 { + k8sMapping["namespace_annotations"] = namespaceAnnotations + } // add annotations to be discoverable by templates k8sMapping["annotations"] = annotations diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go index 5c26d50ea8f8..62d4a199892e 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go @@ -50,17 +50,15 @@ func TestGeneratePodData(t *testing.T) { data := generatePodData(pod, &Config{}, &podMeta{}, namespaceAnnotations) mapping := map[string]interface{}{ - "namespace": common.MapStr{ - "name": pod.GetNamespace(), - "annotations": common.MapStr{ - "nsa": "nsb", - }, - }, + "namespace": pod.GetNamespace(), "pod": common.MapStr{ "uid": string(pod.GetUID()), "name": pod.GetName(), "ip": pod.Status.PodIP, }, + "namespace_annotations": common.MapStr{ + "nsa": "nsb", + }, "labels": common.MapStr{ "foo": "bar", }, @@ -75,9 +73,7 @@ func TestGeneratePodData(t *testing.T) { "name": "devcluster", "url": "8.8.8.8:9090"}, }, "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "labels": common.MapStr{ "foo": "bar", }, @@ -161,12 +157,7 @@ func TestGenerateContainerPodData(t *testing.T) { }) mapping := map[string]interface{}{ - "namespace": common.MapStr{ - "name": pod.GetNamespace(), - "annotations": common.MapStr{ - "nsa": "nsb", - }, - }, + "namespace": pod.GetNamespace(), "pod": common.MapStr{ "uid": string(pod.GetUID()), "name": pod.GetName(), @@ -180,6 +171,9 @@ func TestGenerateContainerPodData(t *testing.T) { "port": "80", "port_name": "http", }, + "namespace_annotations": common.MapStr{ + "nsa": "nsb", + }, "annotations": common.MapStr{ "app": "production", }, @@ -198,9 +192,7 @@ func TestGenerateContainerPodData(t *testing.T) { "name": "devcluster", "url": "8.8.8.8:9090"}, }, "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "annotations": common.MapStr{"app": "production"}, "labels": common.MapStr{"foo": "bar"}, "pod": common.MapStr{ @@ -280,12 +272,7 @@ func TestEphemeralContainers(t *testing.T) { }) mapping := map[string]interface{}{ - "namespace": common.MapStr{ - "name": pod.GetNamespace(), - "annotations": common.MapStr{ - "nsa": "nsb", - }, - }, + "namespace": pod.GetNamespace(), "pod": common.MapStr{ "uid": string(pod.GetUID()), "name": pod.GetName(), @@ -300,6 +287,9 @@ func TestEphemeralContainers(t *testing.T) { "image": "nginx:1.120", "runtime": "crio", }, + "namespace_annotations": common.MapStr{ + "nsa": "nsb", + }, "annotations": common.MapStr{ "app": "production", }, @@ -315,9 +305,7 @@ func TestEphemeralContainers(t *testing.T) { "name": "devcluster", "url": "8.8.8.8:9090"}, }, "kubernetes": common.MapStr{ - "namespace": common.MapStr{ - "name": "testns", - }, + "namespace": "testns", "labels": common.MapStr{"foo": "bar"}, "annotations": common.MapStr{"app": "production"}, "pod": common.MapStr{ @@ -393,9 +381,7 @@ func (p *podMeta) GenerateECS(obj kubernetes.Resource) common.MapStr { func (p *podMeta) GenerateK8s(obj kubernetes.Resource, opts ...metadata.FieldOptions) common.MapStr { k8sPod := obj.(*kubernetes.Pod) return common.MapStr{ - "namespace": common.MapStr{ - "name": k8sPod.GetNamespace(), - }, + "namespace": k8sPod.GetNamespace(), "pod": common.MapStr{ "uid": string(k8sPod.GetUID()), "name": k8sPod.GetName(), diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go index 2bdf73380bed..40e12bb53ffb 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go @@ -186,14 +186,13 @@ func generateServiceData( return &serviceData{} } - ckMeta := kubemetaMap.(common.MapStr).Clone() - if len(namespaceAnnotations) != 0 { - ckMeta.Put("namespace.annotations", namespaceAnnotations) - } // k8sMapping includes only the metadata that fall under kubernetes.* // and these are available as dynamic vars through the provider - k8sMapping := map[string]interface{}(ckMeta) + k8sMapping := map[string]interface{}(kubemetaMap.(common.MapStr).Clone()) + if len(namespaceAnnotations) != 0 { + k8sMapping["namespace_annotations"] = namespaceAnnotations + } // Pass annotations to all events so that it can be used in templating and by annotation builders. annotations := common.MapStr{} for k, v := range service.GetObjectMeta().GetAnnotations() { diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service_test.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service_test.go index c85abed7f077..c183541e6a73 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service_test.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service_test.go @@ -61,10 +61,8 @@ func TestGenerateServiceData(t *testing.T) { "name": service.GetName(), "ip": service.Spec.ClusterIP, }, - "namespace": common.MapStr{ - "annotations": common.MapStr{ - "nsa": "nsb", - }, + "namespace_annotations": common.MapStr{ + "nsa": "nsb", }, "annotations": common.MapStr{ "baz": "ban", diff --git a/x-pack/filebeat/module/coredns/log/test/coredns-json.log b/x-pack/filebeat/module/coredns/log/test/coredns-json.log index 52f20388d107..9a2f9b6dea45 100644 --- a/x-pack/filebeat/module/coredns/log/test/coredns-json.log +++ b/x-pack/filebeat/module/coredns/log/test/coredns-json.log @@ -1,3 +1,3 @@ -{"message":"2019-02-12T00:27:28.903Z [INFO] 172.17.0.4:36413 - 21583 \"A IN httpbin.org.cluster.local. udp 43 false 512\" NXDOMAIN qr,rd,ra 136 0.000102078s", "stream": "stdout", "time": "2019-02-12T00:27:28.903433597Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": { "name": "kube-system" }, "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } -{"message":"2019-03-19T02:57:23.213Z [INFO] 172.17.0.9:37723 - 6966 \"A IN httpbin.org. udp 29 false 512\" NOERROR qr,rd,ra 83 0.000082083s\n","stream":"stdout","time":"2019-03-19T02:57:23.214583742Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": { "name": "kube-system" }, "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } -{"message":"2019-03-11T07:16:34.013Z [INFO] [::1]:37915 - 62762 \"AAAA IN czbaoyu.com. udp 29 false 512\" NOERROR qr,rd,ra 100 0.00006286s\n","stream":"stdout","time":"2019-03-11T07:16:34.013970788Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": { "name": "kube-system" }, "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } +{"message":"2019-02-12T00:27:28.903Z [INFO] 172.17.0.4:36413 - 21583 \"A IN httpbin.org.cluster.local. udp 43 false 512\" NXDOMAIN qr,rd,ra 136 0.000102078s", "stream": "stdout", "time": "2019-02-12T00:27:28.903433597Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": "kube-system", "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } +{"message":"2019-03-19T02:57:23.213Z [INFO] 172.17.0.9:37723 - 6966 \"A IN httpbin.org. udp 29 false 512\" NOERROR qr,rd,ra 83 0.000082083s\n","stream":"stdout","time":"2019-03-19T02:57:23.214583742Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": "kube-system", "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } +{"message":"2019-03-11T07:16:34.013Z [INFO] [::1]:37915 - 62762 \"AAAA IN czbaoyu.com. udp 29 false 512\" NOERROR qr,rd,ra 100 0.00006286s\n","stream":"stdout","time":"2019-03-11T07:16:34.013970788Z", "kubernetes": { "container": { "name": "coredns" }, "node": { "name": "minikube" }, "pod": { "uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "name": "coredns-86c58d9df4-jwhsg" }, "namespace": "kube-system", "replicaset": { "name": "coredns-86c58d9df4" }, "labels": { "pod-template-hash": "86c58d9df4", "k8s-app": "kube-dns" } } } diff --git a/x-pack/filebeat/module/coredns/log/test/coredns-json.log-expected.json b/x-pack/filebeat/module/coredns/log/test/coredns-json.log-expected.json index 12a927c1cc30..9a1c8520b766 100644 --- a/x-pack/filebeat/module/coredns/log/test/coredns-json.log-expected.json +++ b/x-pack/filebeat/module/coredns/log/test/coredns-json.log-expected.json @@ -20,7 +20,7 @@ "event.duration": 102078, "event.kind": "event", "event.module": "coredns", - "event.original": "{\"message\":\"2019-02-12T00:27:28.903Z [INFO] 172.17.0.4:36413 - 21583 \\\"A IN httpbin.org.cluster.local. udp 43 false 512\\\" NXDOMAIN qr,rd,ra 136 0.000102078s\", \"stream\": \"stdout\", \"time\": \"2019-02-12T00:27:28.903433597Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": { \"name\": \"kube-system\" }, \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", + "event.original": "{\"message\":\"2019-02-12T00:27:28.903Z [INFO] 172.17.0.4:36413 - 21583 \\\"A IN httpbin.org.cluster.local. udp 43 false 512\\\" NXDOMAIN qr,rd,ra 136 0.000102078s\", \"stream\": \"stdout\", \"time\": \"2019-02-12T00:27:28.903433597Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": \"kube-system\", \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", "event.outcome": "failure", "event.type": [ "protocol" @@ -30,7 +30,7 @@ "kubernetes.container.name": "coredns", "kubernetes.labels.k8s-app": "kube-dns", "kubernetes.labels.pod-template-hash": "86c58d9df4", - "kubernetes.namespace.name": "kube-system", + "kubernetes.namespace": "kube-system", "kubernetes.node.name": "minikube", "kubernetes.pod.name": "coredns-86c58d9df4-jwhsg", "kubernetes.pod.uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", @@ -72,7 +72,7 @@ "event.duration": 82083, "event.kind": "event", "event.module": "coredns", - "event.original": "{\"message\":\"2019-03-19T02:57:23.213Z [INFO] 172.17.0.9:37723 - 6966 \\\"A IN httpbin.org. udp 29 false 512\\\" NOERROR qr,rd,ra 83 0.000082083s\\n\",\"stream\":\"stdout\",\"time\":\"2019-03-19T02:57:23.214583742Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": { \"name\": \"kube-system\" }, \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", + "event.original": "{\"message\":\"2019-03-19T02:57:23.213Z [INFO] 172.17.0.9:37723 - 6966 \\\"A IN httpbin.org. udp 29 false 512\\\" NOERROR qr,rd,ra 83 0.000082083s\\n\",\"stream\":\"stdout\",\"time\":\"2019-03-19T02:57:23.214583742Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": \"kube-system\", \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", "event.outcome": "success", "event.type": [ "protocol" @@ -82,13 +82,13 @@ "kubernetes.container.name": "coredns", "kubernetes.labels.k8s-app": "kube-dns", "kubernetes.labels.pod-template-hash": "86c58d9df4", - "kubernetes.namespace.name": "kube-system", + "kubernetes.namespace": "kube-system", "kubernetes.node.name": "minikube", "kubernetes.pod.name": "coredns-86c58d9df4-jwhsg", "kubernetes.pod.uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "kubernetes.replicaset.name": "coredns-86c58d9df4", "log.level": "INFO", - "log.offset": 562, + "log.offset": 550, "message": "2019-03-19T02:57:23.213Z [INFO] 172.17.0.9:37723 - 6966 \"A IN httpbin.org. udp 29 false 512\" NOERROR qr,rd,ra 83 0.000082083s\n", "network.protocol": "dns", "network.transport": "udp", @@ -124,7 +124,7 @@ "event.duration": 62860, "event.kind": "event", "event.module": "coredns", - "event.original": "{\"message\":\"2019-03-11T07:16:34.013Z [INFO] [::1]:37915 - 62762 \\\"AAAA IN czbaoyu.com. udp 29 false 512\\\" NOERROR qr,rd,ra 100 0.00006286s\\n\",\"stream\":\"stdout\",\"time\":\"2019-03-11T07:16:34.013970788Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": { \"name\": \"kube-system\" }, \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", + "event.original": "{\"message\":\"2019-03-11T07:16:34.013Z [INFO] [::1]:37915 - 62762 \\\"AAAA IN czbaoyu.com. udp 29 false 512\\\" NOERROR qr,rd,ra 100 0.00006286s\\n\",\"stream\":\"stdout\",\"time\":\"2019-03-11T07:16:34.013970788Z\", \"kubernetes\": { \"container\": { \"name\": \"coredns\" }, \"node\": { \"name\": \"minikube\" }, \"pod\": { \"uid\": \"d57d545e-2a9d-11e9-995f-08002730e0dc\", \"name\": \"coredns-86c58d9df4-jwhsg\" }, \"namespace\": \"kube-system\", \"replicaset\": { \"name\": \"coredns-86c58d9df4\" }, \"labels\": { \"pod-template-hash\": \"86c58d9df4\", \"k8s-app\": \"kube-dns\" } } }", "event.outcome": "success", "event.type": [ "protocol" @@ -134,13 +134,13 @@ "kubernetes.container.name": "coredns", "kubernetes.labels.k8s-app": "kube-dns", "kubernetes.labels.pod-template-hash": "86c58d9df4", - "kubernetes.namespace.name": "kube-system", + "kubernetes.namespace": "kube-system", "kubernetes.node.name": "minikube", "kubernetes.pod.name": "coredns-86c58d9df4-jwhsg", "kubernetes.pod.uid": "d57d545e-2a9d-11e9-995f-08002730e0dc", "kubernetes.replicaset.name": "coredns-86c58d9df4", "log.level": "INFO", - "log.offset": 1105, + "log.offset": 1081, "message": "2019-03-11T07:16:34.013Z [INFO] [::1]:37915 - 62762 \"AAAA IN czbaoyu.com. udp 29 false 512\" NOERROR qr,rd,ra 100 0.00006286s\n", "network.protocol": "dns", "network.transport": "udp", diff --git a/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log b/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log index 65d689e46eb8..31cb674f4c7f 100644 --- a/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log +++ b/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log @@ -1,2 +1,2 @@ -{"message":"ACCESS [2019-04-10T03:49:34.451Z] \"GET /httpbin/status/501 HTTP/1.1\" 501 - 0 0 180 179 \"172.17.0.3\" \"curl/7.59.0\" \"413bf460-bd56-4515-ada4-2a69c5e78e54\" \"httpbin.org\" \"52.71.234.219:80\"","stream":"stdout","time":"2019-02-12T18:37:43.139620629Z", "kubernetes": { "container": { "name": "ambassador" }, "node": { "name": "minikube" }, "pod": { "uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", "name": "ambassador-76c58d9df4-jwhsg" }, "namespace": { "name": "default" }, "labels": { "service": "ambassador" }}} -{"message":"ACCESS [2019-04-06T06:20:05.972Z] \"- - -\" 0 UF,URX 0 0 0 - \"-\" \"-\" \"-\" \"-\" \"127.0.0.1:9200\"","stream":"stdout","time":"2019-02-12T18:37:43.139620629Z", "kubernetes": { "container": { "name": "ambassador" }, "node": { "name": "minikube" }, "pod": { "uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", "name": "ambassador-76c58d9df4-jwhsg" }, "namespace": { "name": "default" }, "labels": { "service": "ambassador" }}}} +{"message":"ACCESS [2019-04-10T03:49:34.451Z] \"GET /httpbin/status/501 HTTP/1.1\" 501 - 0 0 180 179 \"172.17.0.3\" \"curl/7.59.0\" \"413bf460-bd56-4515-ada4-2a69c5e78e54\" \"httpbin.org\" \"52.71.234.219:80\"","stream":"stdout","time":"2019-02-12T18:37:43.139620629Z", "kubernetes": { "container": { "name": "ambassador" }, "node": { "name": "minikube" }, "pod": { "uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", "name": "ambassador-76c58d9df4-jwhsg" }, "namespace": "default", "labels": { "service": "ambassador" }}} +{"message":"ACCESS [2019-04-06T06:20:05.972Z] \"- - -\" 0 UF,URX 0 0 0 - \"-\" \"-\" \"-\" \"-\" \"127.0.0.1:9200\"","stream":"stdout","time":"2019-02-12T18:37:43.139620629Z", "kubernetes": { "container": { "name": "ambassador" }, "node": { "name": "minikube" }, "pod": { "uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", "name": "ambassador-76c58d9df4-jwhsg" }, "namespace": "default", "labels": { "service": "ambassador" }}}} diff --git a/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log-expected.json b/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log-expected.json index f2e9cb25b379..9219be79328f 100644 --- a/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log-expected.json +++ b/x-pack/filebeat/module/envoyproxy/log/test/envoy-json.log-expected.json @@ -32,7 +32,7 @@ "input.type": "log", "kubernetes.container.name": "ambassador", "kubernetes.labels.service": "ambassador", - "kubernetes.namespace.name": "default", + "kubernetes.namespace": "default", "kubernetes.node.name": "minikube", "kubernetes.pod.name": "ambassador-76c58d9df4-jwhsg", "kubernetes.pod.uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", @@ -87,11 +87,11 @@ "input.type": "log", "kubernetes.container.name": "ambassador", "kubernetes.labels.service": "ambassador", - "kubernetes.namespace.name": "default", + "kubernetes.namespace": "default", "kubernetes.node.name": "minikube", "kubernetes.pod.name": "ambassador-76c58d9df4-jwhsg", "kubernetes.pod.uid": "e57d545e-2a9d-11e9-995f-08002730e0dc", - "log.offset": 530, + "log.offset": 518, "message": "ACCESS [2019-04-06T06:20:05.972Z] \"- - -\" 0 UF,URX 0 0 0 - \"-\" \"-\" \"-\" \"-\" \"127.0.0.1:9200\"", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/functionbeat/docs/fields.asciidoc b/x-pack/functionbeat/docs/fields.asciidoc index 6c968ea5a300..0251ede5401e 100644 --- a/x-pack/functionbeat/docs/fields.asciidoc +++ b/x-pack/functionbeat/docs/fields.asciidoc @@ -15456,47 +15456,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/x-pack/functionbeat/include/fields.go b/x-pack/functionbeat/include/fields.go index 080d4f2c5c41..84ea17cc41ae 100644 --- a/x-pack/functionbeat/include/fields.go +++ b/x-pack/functionbeat/include/fields.go @@ -19,5 +19,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/x-pack/heartbeat/include/fields.go b/x-pack/heartbeat/include/fields.go index 205ce7d00461..efcd48a2e5e6 100644 --- a/x-pack/heartbeat/include/fields.go +++ b/x-pack/heartbeat/include/fields.go @@ -19,5 +19,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } diff --git a/x-pack/metricbeat/module/prometheus/collector/_meta/data.json b/x-pack/metricbeat/module/prometheus/collector/_meta/data.json index b1fd95460ad7..d35cd24a9211 100644 --- a/x-pack/metricbeat/module/prometheus/collector/_meta/data.json +++ b/x-pack/metricbeat/module/prometheus/collector/_meta/data.json @@ -11,10 +11,11 @@ }, "prometheus": { "labels": { + "device": "br-33d819d5f834", "job": "prometheus" }, - "up": { - "value": 1 + "node_network_carrier": { + "value": 0 } }, "service": { diff --git a/x-pack/osquerybeat/docs/fields.asciidoc b/x-pack/osquerybeat/docs/fields.asciidoc index 0ad49632287c..96ab2d136850 100644 --- a/x-pack/osquerybeat/docs/fields.asciidoc +++ b/x-pack/osquerybeat/docs/fields.asciidoc @@ -15451,47 +15451,16 @@ type: ip -- - -*`kubernetes.namespace.name`*:: +*`kubernetes.namespace`*:: + -- -Kubernetes namespace name +Kubernetes namespace type: keyword -- -*`kubernetes.namespace.uuid`*:: -+ --- -Kubernetes namespace uuid - - -type: keyword - --- - -*`kubernetes.namespace.labels.*`*:: -+ --- -Kubernetes namespace labels map - - -type: object - --- - -*`kubernetes.namespace.annotations.*`*:: -+ --- -Kubernetes namespace annotations map - - -type: object - --- - *`kubernetes.node.name`*:: + -- diff --git a/x-pack/osquerybeat/include/fields.go b/x-pack/osquerybeat/include/fields.go index b8a323811b6d..9d6bce231f90 100644 --- a/x-pack/osquerybeat/include/fields.go +++ b/x-pack/osquerybeat/include/fields.go @@ -19,5 +19,5 @@ func init() { // AssetFieldsYml returns asset data. // This is the base64 encoded zlib format compressed contents of fields.yml. func AssetFieldsYml() string { - return "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" + return "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" } From 24f4410b60381ad27e848276ac00b6c3de8f1dbf Mon Sep 17 00:00:00 2001 From: Mario Castro Date: Tue, 23 Nov 2021 13:52:25 +0100 Subject: [PATCH 018/172] Add `beat` field back to beat.stats (#29094) --- metricbeat/docs/fields.asciidoc | 36 +++++++++++++++++++ metricbeat/module/beat/fields.go | 2 +- metricbeat/module/beat/stats/_meta/fields.yml | 13 +++++++ .../system => module/beat}/test_beat.py | 0 4 files changed, 50 insertions(+), 1 deletion(-) rename metricbeat/{tests/system => module/beat}/test_beat.py (100%) diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index c68ea577da3a..c1e7087125c8 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -8309,6 +8309,42 @@ type: keyword -- +*`beat.stats.beat.name`*:: ++ +-- +type: keyword + +-- + +*`beat.stats.beat.host`*:: ++ +-- +type: keyword + +-- + +*`beat.stats.beat.type`*:: ++ +-- +type: keyword + +-- + +*`beat.stats.beat.uuid`*:: ++ +-- +type: keyword + +-- + +*`beat.stats.beat.version`*:: ++ +-- +type: keyword + +-- + + *`beat.stats.system.cpu.cores`*:: + -- diff --git a/metricbeat/module/beat/fields.go b/metricbeat/module/beat/fields.go index b8ee153217ae..03105135aaad 100644 --- a/metricbeat/module/beat/fields.go +++ b/metricbeat/module/beat/fields.go @@ -32,5 +32,5 @@ func init() { // AssetBeat returns asset data. // This is the base64 encoded zlib format compressed contents of module/beat. func AssetBeat() string { - return "eJzsXU1v5LgRvftXED5nBOxhLz4kQZAE2EsCBAvkEAQGrWZ3E5ZIDUl54v31gaRutT5YrJJEqnt3x5cZjEfvPRbJYvGzvrB38fnC3gR3T4w56Qrxwp7/Irh7fmLsIGxuZOWkVi/sj0+MMdb8ipX6UBfiiTEjCsGteGEn/sSYFc5JdbIv7D/P1hbPf2DPZ+eq5/82vztr415zrY7y9MKOvLDN90cpioN9aZG/MMVL0Wmxr9ZxZ9t/Z8x9Vg2F0XV1+Zfhd8NveVV+scJ8CNP/yve5D2IIUxmdC2u1Gf0WQoLQhoi24ipzhit71KbkjUXt7D9fCXghue+3FXfnzj5Za56MV+VrV9ysl5yRqK66hDGzUoZLGirttMS+QuDFpBe1VZ/BTL0Wx/N3Z3gudlKE8F11HQ0vd5IUoLqqwZtnfFkUzqu+g8j1QapT9+k++iicM325rpXbVx5MeVX3wQt5aK28p/1orB6N+9kQJR31D543//NX6zEHZXgovznS9UjecyiM6kO7/76nMpT2Pj5+JvEhPf1Q5cP6e6/Ix/P6Q5kP7fsBoeERwOra5KLkPg+/3f+33MIXjccseF+GLMR3n5540/aw/dAj8fF64U3kQ/dBr8xwDyyFMzJP0v32HRq7gqwaFYPKIAtgVmDTRQGoeDQjLDYEzdFMnOWdJC7p8L/JyqL6s7tWV9CnjPrUbAxcv853EMeCO5EoPlBOKPelEOrkzkn808Uc2aUYGYGSUsOxRYVGiNMvMlV4tpv5mzI8lu0vikKGr1Wuy8oIa8Xh114Bw7I8VkVMlIUqxAg+d20szlKV/MXn4+IVs9OegTz7GfyiBAlLpbVSnb6MmwoYKKzf5rmqIhP2NTbdFWObxjkjvtbCugQlvPwRJhi4hLw2RiiXfePSZWXcTbXLHwSWm11spZVNFQCkauy90Tv11Ag3eXCr35PGjNNit4XKAqT9PnOei8p5x7nU6lDq/UJuv0C87RDWQGI0nv0N0BUsuHYyWG/QuuDmBI2jSRWi3JOJ7F1Eoty90+VOFLKUd6lsnPwq82st6rsYMkzcd5dC+yP35PoQ5n6/T5s3eTgIaE0lqUacfBaT5J/3cT44/W3Kxmt31kb+cp+KJ/FfxUrlhFG8uIdQlHu8nnQPiQjzYAH9rO9S2R7mWzhVBgN+WFNIRxh1zO2N2h9xejSUS5wk1cqKhCL88FgQFok8XHJokrJ9Kqa0K/VBHiXouLZNyEaF7OJqjDL9LNEjCg/2wdlUdC0AE3HOFl0OyIdOg7Y3TyR0jlhWSqxOHMHjqwoSUsLy+JJgtp37LzpXJYU08QUF6Igz5/iagoSDYPqDy4K/FfsJwzipU6f4ysKMpGg0vqgA3WBgP+pa7acpSHjznK2D/VoLA83qUnhPhJS6/hJfWpiRtKKRwJXCdAsm3EmcxJx0eNvqacq+5K7UWdsN0zWpjjqbQfSdkZf+ORkdewbRDyKf1VbsGURfzfVs2rEUewbRh3bC2Pm5oqXwU5Tx+Tq7qUXYT+tEGW0unVd1lmvjPXi/cBbZKctgxCtnofkh+yEaIQA3YvsxLtscbly2yHQevBGf0mbaIliUmc7zD8/xHOmwRI1ibxMYcv+YlNxXRwP2pOQ/ert2Id8mAwbb1LcrWYlCqkTb5YUUykU8yHspfXZVnYUYRtPLjOfvMUf8mRKMpV9z+BDI5DLGzivPnfxIsAo+K3ZbHJshfP1M1uiqSrHTAenCCPvpGZfFnroQvl6WLJwwuwrDGHvHUb8V0p731IZT3lb/HThNSyAsTHdbNHEp9s4gUX66flG4dlUNbwts8fod/w4uDnbobLs5OwPd/FuIbC+vO9VE8rlv3OVn8JZudFUY3W5DwVgWdSA41FUhc57kZBmg7MqI2yz1KDUWRhyjnNYlVwm97VgVRreTt52KgsiGR8Gzt0+4ljfEoBctCMVISexLkD4phOuOniWgeCJA8Cv7NyOdSFwpGMdYS+JqCZIMTk8dpe+K4/bIoHu1KjO1UtgtylXF7KQH8SdSrOMmxQT1oiQAPxOiq5Q6pujA6jPbtJjQLmyK6ixKYXjxGjj5QV7iwiFH5HXlZCmi3EJA8PrVd64ORWBpdEt/aTdYsjM3ERcuLnozBHsswepjxK2lsQQQu5+qVDF3Ta/kXtTbInw5fP5uTrmlVk/5qxL/i2jPq9oshDwomjafr7wotO8W/1YJHXwGw090hMK0CDoIgZmN6HZ7eh9qP8BCjSfCgmtVJ593g5eO2PqoujNJuy0UgO9LebRZJYzUh6xOMK8diKExDXV9rbXje8hCifrNQMCRjeWEWgYjtI4hY2exECcjm4Ehpuj+gcLYzznORjtXiAPpq7g6l3HPFYOPoqQVizyLklc1z3MHd90VnvSmJgQ9VdC6e9hK23UECcZDWwpzhJEH/JfYKvLcdqyCQjOUVFt+ij7dnksK0YTHyQi38rtNXCfz95hlbLokhjyTAE2DYoiAsUfLb9kHL2Ke7G00YMBjAQlqAgOeCkhQDzh0fw7KCpPCCAjuhD6BCUbIT2yyotG9Xn5tIPN+Db1eftezeCJr/5rkLN4FO8lZvAt2krN4F+xUZ/Eu8NBZvKZ9WcfLatYmptgd7vOf+y+eZ2DDFslWNS5/FUZsBWDrXbMYyE1+lk7krjbw6aLwalyjJwviDJV7LLOICMQIdMBFBEFwnWaxqSq4O/qP/uHama8JtUXRNgsih/tnBHYf8G0luKo3XmMVGQQyJlGe96gXk8xBJpsDG4sCokxoNhYGRBmfOdnowSCQ3s0K8yHzeBeJt29iiOyiyTdvi+BbPERBTwP3yZVsQ0BPJDW3vSerDRyTjYzWYb2Lz296tHHhRex+2nw5P/01m4/u44BlLXTz3RycNtpj2FOUcbaf60/wKsB+3WFuuvGnwSaOfYw1Wt/3I1cdzQLh+/SF9mw8Dy0AD/OhIkTdpvWEeWEV0zKs/hg4kkH72DOPoH+8pf3kRW2dMPNZCOXjqDF1rpXjUgno+hrNFolCzXdhlAjv5UHKGN7AloGQwl4KECWADVV/yRU/iVIolwnF3+YH6jqIN60Lwac0geGh+fnJslwoZ3gxoGEXmj+tCyilcuI0e6YSEfKPunwThunjBd8yX1nJ0WbInlgM6a9TTD8vRaO+A2e1FQf29tkOwV4R3V2PNBpabPYmpDr5hUD7eusjDLspwrjdfY3m5qDsf2HUEPLIcLRMgCw8pg8RoRx+uF5M81Q3vpELimXjtoOklVoIGMwEtRCLVjULQanZDdaB0h66JGHSX/ZfC7tR7KiawGRs7HvTX4FFSF62BvF7Z3r0zhTKa8WidqVwjiuCZPa9ISRsCGB6JRa1FSR1CyhazMNmaHUSC8EISzwLIeet5PdqGTDS92f/YVHifDgTEI6PcbDJogyaFYUtazKRvAmQiof9XsqPZMRhvxc7gIloWNwwHU5KQxDL4pd7YVYYBHm4p5LIZ2HPFi8oOykzywK8QGIVvOxY+Vm8umfTkXfXQTeYL4WofohHyHOyAjVygEMMqWPaOVIJ2OjAJpoOZAUqIX/HClRKwo0VsFiCjBWQaFKLFZiUPBRrpJLyRqwAJmZ5WIFMSMmwAhXNobACE017gGDeHGI4U8EimISpwqKO5JshoAwECyD2yTeGP+tPkMzSRBOEXGgkHHLuMtrGUziui1Ep5BxUpOKT08iQ0Gg5nfZuKsQsNLQlfGqaMhIa/kj6QkB6UigSHDE9DgkLeUp8IRrhCfCFiPS0abT2S8sfRm0m9MRUM8SbyY76yffFmlMBm06ebTrz9us8trb7K9DBgKvQPE0iIOz94YOuseQM6DPCFIztEMATzSzqWA6bi6SV0cy2HGsd1KBxRmvoyFVbygIhdk+WgBG+50oG2FAK7JYpASJ4TZT+/UIFSUYf0rNW6FiAPk8FFsb7aswmb57EG1NeTKFOe/FXTohIyLyVcg449IpKPOeMvwqyZN6w4LGRVbBrzw0M2iD8uAetQxHe5SAI6V6PSNIfIjS9Jc95EM6X0B/iAH0R8Dzaem8EP1xGrj3wyTE6AvRYGAHB/4oYYkb/04HrrQg8lEcJzkOPAZK/B17yQ6wAjYkgLXKQvj3W3oF6+UytWsKTNrp2UgEVsJz4dgviBs0ub5EyqeDrBEtzeiA6/t42E5brstSKOc14UbTk04I+fG4Q1JtRU3vgC6l7vVlPeiCetsRIfECdtohHe1mchkVNWkFCo+eZoC25kTJDENdlKS+MhyOgdG8tUx5Ztmdtwq+FEt5HpoBgbxv7MfpxbV2uCsRNNj//7C58QcE9xc7A2iAjhXgkkc3Pz5/V4IZaSldGFPS3huV6mBxii5vKA9lqJgpno5G6M1YjQOlvhTic4mX5SCG3ow5X8U0oNfNHMsOiCqKOZduawOIEIXe0q6WkKYk5tG8TGzmRSAqlTmvWkFO71oaxf5XSnxs+piaWDQcAwrvhwmKOAv8S/BBcGqOOAKHFCJa05lvmkLEWH3NMobLRF+K/SmwzfKSu9X83JL+Jam/M5QInFx6g5tsanQoI/eX/AQAA//95+27i" + return "eJzsXU1v5LgRvftXED5nBOxhLz4kQZAE2EsCBAvkEAQGrWZ3E5ZIDUl54v31gaRutT5YrJJEqnt3x5cZjEfvPRbJYvGzvrB38fnC3gR3T4w56Qrxwp7/Irh7fmLsIGxuZOWkVi/sj0+MMdb8ipX6UBfiiTEjCsGteGEn/sSYFc5JdbIv7D/P1hbPf2DPZ+eq5/82vztr415zrY7y9MKOvLDN90cpioN9aZG/MMVL0Wmxr9ZxZ9t/Z8x9Vg2F0XV1+Zfhd8NveVV+scJ8CNP/yve5D2IIUxmdC2u1Gf0WQoLQhoi24ipzhit71KbkjUXt7D9fCXghue+3FXfnzj5Za56MV+VrV9ysl5yRqK66hDGzUoZLGirttMS+QuDFpBe1VZ/BTL0Wx/N3Z3gudlKE8F11HQ0vd5IUoLqqwZtnfFkUzqu+g8j1QapT9+k++iicM325rpXbVx5MeVX3wQt5aK28p/1orB6N+9kQJR31D543//NX6zEHZXgovznS9UjecyiM6kO7/76nMpT2Pj5+JvEhPf1Q5cP6e6/Ix/P6Q5kP7fsBoeERwOra5KLkPg+/3f+33MIXjccseF+GLMR3n5540/aw/dAj8fF64U3kQ/dBr8xwDyyFMzJP0v32HRq7gqwaFYPKIAtgVmDTRQGoeDQjLDYEzdFMnOWdJC7p8L/JyqL6s7tWV9CnjPrUbAxcv853EMeCO5EoPlBOKPelEOrkzkn808Uc2aUYGYGSUsOxRYVGiNMvMlV4tpv5mzI8lu0vikKGr1Wuy8oIa8Xh114Bw7I8VkVMlIUqxAg+d20szlKV/MXn4+IVs9OegTz7GfyiBAlLpbVSnb6MmwoYKKzf5rmqIhP2NTbdFWObxjkjvtbCugQlvPwRJhi4hLw2RiiXfePSZWXcTbXLHwSWm11spZVNFQCkauy90Tv11Ag3eXCr35PGjNNit4XKAqT9PnOei8p5x7nU6lDq/UJuv0C87RDWQGI0nv0N0BUsuHYyWG/QuuDmBI2jSRWi3JOJ7F1Eoty90+VOFLKUd6lsnPwq82st6rsYMkzcd5dC+yP35PoQ5n6/T5s3eTgIaE0lqUacfBaT5J/3cT44/W3Kxmt31kb+cp+KJ/FfxUrlhFG8uIdQlHu8nnQPiQjzYAH9rO9S2R7mWzhVBgN+WFNIRxh1zO2N2h9xejSUS5wk1cqKhCL88FgQFok8XHJokrJ9Kqa0K/VBHiXouLZNyEaF7OJqjDL9LNEjCg/2wdlUdC0AE3HOFl0OyIdOg7Y3TyR0jlhWSqxOHMHjqwoSUsLy+JJgtp37LzpXJYU08QUF6Igz5/iagoSDYPqDy4K/FfsJwzipU6f4ysKMpGg0vqgA3WBgP+pa7acpSHjznK2D/VoLA83qUnhPhJS6/hJfWpiRtKKRwJXCdAsm3EmcxJx0eNvqacq+5K7UWdsN0zWpjjqbQfSdkZf+ORkdewbRDyKf1VbsGURfzfVs2rEUewbRh3bC2Pm5oqXwU5Tx+Tq7qUXYT+tEGW0unVd1lmvjPXi/cBbZKctgxCtnofkh+yEaIQA3YvsxLtscbly2yHQevBGf0mbaIliUmc7zD8/xHOmwRI1ibxMYcv+YlNxXRwP2pOQ/ert2Id8mAwbb1LcrWYlCqkTb5YUUykU8yHspfXZVnYUYRtPLjOfvMUf8mRKMpV9z+BDI5DLGzivPnfxIsAo+K3ZbHJshfP1M1uiqSrHTAenCCPvpGZfFnroQvl6WLJwwuwrDGHvHUb8V0p731IZT3lb/HThNSyAsTHdbNHEp9s4gUX66flG4dlUNbwts8fod/w4uDnbobLs5OwPd/FuIbC+vO9VE8rlv3OVn8JZudFUY3W5DwVgWdSA41FUhc57kZBmg7MqI2yz1KDUWRhyjnNYlVwm97VgVRreTt52KgsiGR8Gzt0+4ljfEoBctCMVISexLkD4phOuOniWgeCJA8Cv7NyOdSFwpGMdYS+JqCZIMTk8dpe+K4/bIoHu1KjO1UtgtylXF7KQH8SdSrOMmxQT1oiQAPxOiq5Q6pujA6jPbtJjQLmyK6ixKYXjxGjj5QV7iwiFH5HXlZCmi3EJA8PrVd64ORWBpdEt/aTdYsjM3ERcuLnozBHsswepjxK2lsQQQu5+qVDF3Ta/kXtTbInw5fP5uTrmlVk/5qxL/i2jPq9oshDwomjafr7wotO8W/1YJHXwGw090hMK0CDoIgZmN6HZ7eh9qP8BCjSfCgmtVJ593g5eO2PqoujNJuy0UgO9LebRZJYzUh6xOMK8diKExDXV9rbXje8hCifrNQMCRjeWEWgYjtI4hY2exECcjm4Ehpuj+gcLYzznORjtXiAPpq7g6l3HPFYOPoqQVizyLklc1z3MHd90VnvSmJgQ9VdC6e9hK23UECcZDWwpzhJEH/JfYKvLcdqyCQjOUVFt+ij7dnksK0YTHyQi38rtNXCfz95hlbLokhjyTAE2DYoiAsUfLb9kHL2Ke7G00YMBjAQlqAgOeCkhQDzh0fw7KCpPCCAjuhD6BCUbIT2yyotG9Xn5tIPN+Db1eftezeCJr/5rkLN4FO8lZvAt2krN4F+xUZ/Eu8NBZvKZ9WcfLatYmptgd7vOf+y+eZ2DDFslWNS5/FUZsBWDrXbMYyE1+lk7krjbw6aLwalyjJwviDJV7LLOICMQIdMBFBEFwnWaxqSq4O/qP/uHama8JtUXRNgsih/tnBHYf8G0luKo3XmMVGQQyJlGe96gXk8xBJpsDG4sCokxoNhYGRBmfOdnowSCQ3s0K8yHzeBeJt29iiOyiyTdvi+BbPERBTwP3yZVsQ0BPJDW3vSerDRyTjYzWYb2Lz296tHHhRex+2nw5P/01m4/u44BlLXTz3RycNtpj2FOUcbaf60/wKsB+3WFuuvGnwSaOfYw1Wt/3I1cdzQLh+/SF9mw8Dy0AD/OhIkTdpvWEeWEV0zKs/hg4kkH72DOPoH+8pf3kRW2dMPNZCOXjqDF1rpXjUgno+hrNFolCzXdhlAjv5UHKGN7AloGQwl4KECWADVV/yRU/iVIolwnF3+YH6jqIN60Lwac0geGh+fnJslwoZ3gxoGEXmj+tCyilcuI0e6YSEfKPunwThunjBd8yX1nJ0WbInlgM6a9TTD8vRaO+A2e1FQf29tkOwV4R3V2PNBpabPYmpDr5hUD7eusjDLspwrjdfY3m5qDsf2HUEPLIcLRMgCw8pg8RoRx+uF5M81Q3vpELimXjtoOklVoIGMwEtRCLVjULQanZDdaB0h66JGHSX/ZfC7tR7KiawGRs7HvTX4FFSF62BvF7Z3r0zhTKa8WidqVwjiuCZPa9ISRsCGB6JRa1FSR1CyhazMNmaHUSC8EISzwLIeet5PdqGTDS92f/YVHifDgTEI6PcbDJogyaFYUtazKRvAmQiof9XsqPZMRhvxc7gIloWNwwHU5KQxDL4pd7YVYYBHm4p5LIZ2HPFi8oOykzywK8QGIVvOxY+Vm8umfTkXfXQTeYL4WofohHyHOyAjVygEMMqWPaOVIJ2OjAJpoOZAUqIX/HClRKwo0VsFiCjBWQaFKLFZiUPBRrpJLyRqwAJmZ5WIFMSMmwAhXNobACE017gGDeHGI4U8EimISpwqKO5JshoAwECyD2yTeGP+tPkMzSRBOEXGgkHHLuMtrGUziui1Ep5BxUpOKT08iQ0Gg5nfZuKsQsNLQlfGqaMhIa/kj6QkB6UigSHDE9DgkLeUp8IRrhCfCFiPS0abT2S8sfRm0m9MRUM8SbyY76yffFmlMBm06ebTrz9us8thb1zOB349O+79eI9n6COxjtFpqnycKEPf580DWWGQN9w5mCsR0CeB+bRQ2kYHORtDKa2ZZjrYMaNM5oDR2550xZncUuKRMwwpeMyQAbSoFd8SVABO/o0r9fqCDJ0E96UwwdC9C3wcDCeJ/s2eTNk3hjynM11DUH/IkZIhKyaEA5hB16wiaec8afZFkyaVvw0ssq2LWHNgZtEH5ZhdahCI+iEIR0T3ck6Q8Rmt6St1QIh3vor6CAvgh4m269N4JfjSPXHvjeGx0BeqmNgOB/wg0xo//dxvVWBF4ppATnoZcYyd8DzygiVoDGRJAWucXQ3inoQL18plYt4UkbXTupgApYTny7gnKDZpeHYJlU8F2OpQlVEB1/b5sJy3VZasWcZrwoWvJpQR8+MQvqzah5VfBV7L0SBpBe56et7xJfr6etoNKedadhUTOGkNDoST5o652ktBzERXHK8+7hCCjdQ9eUF67tWZvwU62Ex6kpINjD0n6MflxblygEcZPNzz+723ZQcE+xM7A2yEghHklk8/PzZzW4HpjSlREF/a1huZ7kh9ji5lFB9vmJwtlopO6M1QhQ+lshDqd4KVZSyO2ow1U8WH0npl1JZlhUQdSxbFsTWJyd5Y52tZQcMTGH9m1iI2dxSaHUac0acmrX2jD2r1L6c8PH1MSy4QBAeDdcWMxR4F+CH4JLY9QRILQYwZLWfMscMtbiM6YpVDb6QvxXiW16ldS1/u+G5DdR7Y25XODYyAPUfFujUwGhv/w/AAD//1Cnw20=" } diff --git a/metricbeat/module/beat/stats/_meta/fields.yml b/metricbeat/module/beat/stats/_meta/fields.yml index 19c0f75d7156..56b598c7d054 100644 --- a/metricbeat/module/beat/stats/_meta/fields.yml +++ b/metricbeat/module/beat/stats/_meta/fields.yml @@ -232,6 +232,19 @@ type: keyword - name: version type: keyword + - name: beat + type: group + fields: + - name: name + type: keyword + - name: host + type: keyword + - name: type + type: keyword + - name: uuid + type: keyword + - name: version + type: keyword - name: system type: group fields: diff --git a/metricbeat/tests/system/test_beat.py b/metricbeat/module/beat/test_beat.py similarity index 100% rename from metricbeat/tests/system/test_beat.py rename to metricbeat/module/beat/test_beat.py From 260509fe607b8be017c0e1513b4ff1b6bb00ae47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 23 Nov 2021 17:37:18 +0100 Subject: [PATCH 019/172] Remove deprecated spool queue from Beats (#28869) --- CHANGELOG-developer.next.asciidoc | 1 + NOTICE.txt | 844 ------------------ auditbeat/auditbeat.reference.yml | 60 -- filebeat/filebeat.reference.yml | 60 -- go.mod | 3 - go.sum | 11 - heartbeat/heartbeat.reference.yml | 60 -- journalbeat/journalbeat.reference.yml | 60 -- .../_meta/config/general.reference.yml.tmpl | 60 -- libbeat/docs/queueconfig.asciidoc | 163 ---- libbeat/publisher/includes/includes.go | 1 - .../stress/configs/pipeline/small_spool.yml | 11 - .../publisher/pipeline/stress/stress_test.go | 1 - libbeat/publisher/queue/spool/codec.go | 203 ----- libbeat/publisher/queue/spool/codec_test.go | 76 -- libbeat/publisher/queue/spool/config.go | 129 --- libbeat/publisher/queue/spool/consume.go | 139 --- libbeat/publisher/queue/spool/inbroker.go | 550 ------------ libbeat/publisher/queue/spool/internal_api.go | 61 -- libbeat/publisher/queue/spool/log.go | 71 -- libbeat/publisher/queue/spool/module.go | 80 -- libbeat/publisher/queue/spool/outbroker.go | 536 ----------- libbeat/publisher/queue/spool/produce.go | 203 ----- libbeat/publisher/queue/spool/spool.go | 250 ------ libbeat/publisher/queue/spool/spool_test.go | 159 ---- libbeat/publisher/queue/spool/timer.go | 72 -- libbeat/scripts/cmd/stress_pipeline/main.go | 1 - metricbeat/metricbeat.reference.yml | 60 -- packetbeat/packetbeat.reference.yml | 60 -- winlogbeat/winlogbeat.reference.yml | 60 -- x-pack/auditbeat/auditbeat.reference.yml | 60 -- x-pack/dockerlogbeat/main.go | 1 - x-pack/filebeat/filebeat.reference.yml | 60 -- .../functionbeat/functionbeat.reference.yml | 60 -- x-pack/heartbeat/heartbeat.reference.yml | 60 -- x-pack/metricbeat/metricbeat.reference.yml | 60 -- x-pack/osquerybeat/osquerybeat.reference.yml | 60 -- x-pack/packetbeat/packetbeat.reference.yml | 60 -- x-pack/winlogbeat/winlogbeat.reference.yml | 60 -- 39 files changed, 1 insertion(+), 4525 deletions(-) delete mode 100644 libbeat/publisher/pipeline/stress/configs/pipeline/small_spool.yml delete mode 100644 libbeat/publisher/queue/spool/codec.go delete mode 100644 libbeat/publisher/queue/spool/codec_test.go delete mode 100644 libbeat/publisher/queue/spool/config.go delete mode 100644 libbeat/publisher/queue/spool/consume.go delete mode 100644 libbeat/publisher/queue/spool/inbroker.go delete mode 100644 libbeat/publisher/queue/spool/internal_api.go delete mode 100644 libbeat/publisher/queue/spool/log.go delete mode 100644 libbeat/publisher/queue/spool/module.go delete mode 100644 libbeat/publisher/queue/spool/outbroker.go delete mode 100644 libbeat/publisher/queue/spool/produce.go delete mode 100644 libbeat/publisher/queue/spool/spool.go delete mode 100644 libbeat/publisher/queue/spool/spool_test.go delete mode 100644 libbeat/publisher/queue/spool/timer.go diff --git a/CHANGELOG-developer.next.asciidoc b/CHANGELOG-developer.next.asciidoc index 485f4d4152fb..e640b5a0334d 100644 --- a/CHANGELOG-developer.next.asciidoc +++ b/CHANGELOG-developer.next.asciidoc @@ -58,6 +58,7 @@ The list below covers the major changes between 7.0.0-rc2 and master only. - Removed the `common.Float` type. {issue}28279[28279] {pull}28280[28280] {pull}28376[28376] - Removed Beat generators. {pull}28816[28816] - libbeat.logp package forces ECS compliant logs. Logs are JSON formatted. Options to enable ECS/JSON have been removed. {issue}15544[15544] {pull}28573[28573] +- Removed deprecated disk spool from Beats. Use disk queue instead. {pull}28869[28869] ==== Bugfixes diff --git a/NOTICE.txt b/NOTICE.txt index d5599add95ee..e4d0e19c26ca 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -7641,217 +7641,6 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.7 limitations under the License. --------------------------------------------------------------------------------- -Dependency : github.com/elastic/go-txfile -Version: v0.0.8 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-txfile@v0.0.8/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -------------------------------------------------------------------------------- Dependency : github.com/elastic/go-ucfg Version: v0.8.3 @@ -33854,639 +33643,6 @@ Contents of probable licence file $GOMODCACHE/github.com/urso/diag@v0.0.0-202002 limitations under the License. --------------------------------------------------------------------------------- -Dependency : github.com/urso/go-bin -Version: v0.0.0-20180220135811-781c575c9f0e -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/urso/go-bin@v0.0.0-20180220135811-781c575c9f0e/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - --------------------------------------------------------------------------------- -Dependency : github.com/urso/magetools -Version: v0.0.0-20200125210132-c2e338f92f3a -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/urso/magetools@v0.0.0-20200125210132-c2e338f92f3a/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - --------------------------------------------------------------------------------- -Dependency : github.com/urso/qcgen -Version: v0.0.0-20180131103024-0b059e7db4f4 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/urso/qcgen@v0.0.0-20180131103024-0b059e7db4f4/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -------------------------------------------------------------------------------- Dependency : github.com/xdg/stringprep Version: v1.0.3 diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 1068dbd80829..24bfac144149 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -197,66 +197,6 @@ auditbeat.modules: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 0ae039ad589a..45d679cc1944 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -1111,66 +1111,6 @@ filebeat.inputs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/go.mod b/go.mod index a06dd9e5d490..c47fcd15bc8b 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,6 @@ require ( github.com/elastic/go-seccomp-bpf v1.2.0 github.com/elastic/go-structform v0.0.9 github.com/elastic/go-sysinfo v1.7.1 - github.com/elastic/go-txfile v0.0.8 github.com/elastic/go-ucfg v0.8.3 github.com/elastic/go-windows v1.0.1 github.com/elastic/gosigar v0.14.2 @@ -151,7 +150,6 @@ require ( github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786 github.com/ugorji/go/codec v1.1.8 - github.com/urso/magetools v0.0.0-20200125210132-c2e338f92f3a // indirect github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71 github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 github.com/xdg/scram v1.0.3 @@ -268,7 +266,6 @@ require ( github.com/sirupsen/logrus v1.8.1 // indirect github.com/stretchr/objx v0.2.0 // indirect github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797 // indirect - github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e // indirect github.com/xdg/stringprep v1.0.3 // indirect go.elastic.co/fastjson v1.1.0 // indirect go.opencensus.io v0.23.0 // indirect diff --git a/go.sum b/go.sum index 4ae1569e4dac..3ba3d94b54e4 100644 --- a/go.sum +++ b/go.sum @@ -529,8 +529,6 @@ github.com/elastic/go-structform v0.0.9/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZN github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-sysinfo v1.7.1 h1:Wx4DSARcKLllpKT2TnFVdSUJOsybqMYCNQZq1/wO+s0= github.com/elastic/go-sysinfo v1.7.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-txfile v0.0.8 h1:hqFMmLM+UCDMJeSyuCWe8YwS+HtoX7F+cz5fhPYRTn4= -github.com/elastic/go-txfile v0.0.8/go.mod h1:H0nCoFae0a4ga57apgxFsgmRjevNCsEaT6g56JoeKAE= github.com/elastic/go-ucfg v0.7.0/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= github.com/elastic/go-ucfg v0.8.3 h1:leywnFjzr2QneZZWhE6uWd+QN/UpP0sdJRHYyuFvkeo= github.com/elastic/go-ucfg v0.8.3/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= @@ -745,7 +743,6 @@ github.com/godbus/dbus/v5 v5.0.5 h1:9Eg0XUhQxtkV8ykTMKtMMYY72g4NgxtRq4jgh4Ih5YM= github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godror/godror v0.10.4 h1:44FcfzDPp/PJZzen5Hm59SZQBhgrbR6E1KwCjg6gnJo= github.com/godror/godror v0.10.4/go.mod h1:9MVLtu25FBJBMHkPs0m3Ngf/VmwGcLpM2HS8PlNGw9U= -github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -1520,13 +1517,6 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797 h1:OHNw/6pXODJAB32NujjdQO/KIYQ3KAbHQfCzH81XdCs= github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797/go.mod h1:pNWFTeQ+V1OYT/TzWpnWb6eQBdoXpdx+H+lrH97/Oyo= -github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e h1:NiofbjIUI5gR+ybDsGSVH1fWyjSeDYiYVJHT1+kcsak= -github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e/go.mod h1:6GfHrdWBQYjFRIznu7XuQH4lYB2w8nO4bnImVKkzPOM= -github.com/urso/magetools v0.0.0-20190919040553-290c89e0c230/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= -github.com/urso/magetools v0.0.0-20200125210132-c2e338f92f3a h1:jWAaRFnay3H2e6S0GGCl5nKrkgQNlarCE/kvcutzBmw= -github.com/urso/magetools v0.0.0-20200125210132-c2e338f92f3a/go.mod h1:DbaJnRzkGaWrMWm5Hz6QVnUj//x9/zjrfx8bF3J+GJY= -github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4 h1:hhA8EBThzz9PztawVTycKvfETVuBqxAQ5keFlAVtbAw= -github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4/go.mod h1:RspW+E2Yb7Fs7HclB2tiDaiu6Rp41BiIG4Wo1YaoXGc= github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71 h1:CehQeKbysHV8J2V7AD0w8NL2x1h04kmmo/Ft5su4lU0= github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71/go.mod h1:Wp40HwmjM59FkDIVFfcCb9LzBbnc0XAMp8++hJuWvSU= github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= @@ -1867,7 +1857,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200102141924-c96a22e43c9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 6bac78d08c20..8f0f019626bd 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -343,66 +343,6 @@ heartbeat.jobs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/journalbeat/journalbeat.reference.yml b/journalbeat/journalbeat.reference.yml index 2170f2fcec4e..19692cfec94b 100644 --- a/journalbeat/journalbeat.reference.yml +++ b/journalbeat/journalbeat.reference.yml @@ -140,66 +140,6 @@ setup.template.settings: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/libbeat/_meta/config/general.reference.yml.tmpl b/libbeat/_meta/config/general.reference.yml.tmpl index 58a39af4b34f..27118c979c9e 100644 --- a/libbeat/_meta/config/general.reference.yml.tmpl +++ b/libbeat/_meta/config/general.reference.yml.tmpl @@ -77,66 +77,6 @@ # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/libbeat/docs/queueconfig.asciidoc b/libbeat/docs/queueconfig.asciidoc index 054379e1b20a..fb930831dac3 100644 --- a/libbeat/docs/queueconfig.asciidoc +++ b/libbeat/docs/queueconfig.asciidoc @@ -196,166 +196,3 @@ too many errors or overloading the host system if the target disk becomes unavailable for an extended time. The default value is `30s` (thirty seconds). - - -[float] -[[configuration-internal-queue-spool]] -=== Configure the file spool queue - -beta[] - -NOTE: The file spool queue is a deprecated feature offered as-is for backwards compatibility. The supported way to queue events in persistent storage is the disk queue. - -The file spool queue stores all events in an on disk ring buffer. The spool -has a write buffer, which new events are written to. Events written to the -spool are forwarded to the outputs, only after the write buffer has been -flushed successfully. - -The spool waits for the output to acknowledge or drop events. If the spool is -full, no new events can be inserted. The spool will block. Space is freed only -after a signal from the output has been received. - -On disk, the spool divides a file into pages. The `file.page_size` setting -configures the file's page size at file creation time. The optimal page size depends -on the effective block size, used by the underlying file system. - -This sample configuration enables the spool with all default settings (See -<> for defaults) and the -default file path: - -[source,yaml] ------------------------------------------------------------------------------- -queue.spool: ~ ------------------------------------------------------------------------------- - -This sample configuration creates a spool of 512MiB, with 16KiB pages. The -write buffer is flushed if 10MiB of contents, or 1024 events have been -written. If the oldest available event has been waiting for 5s in the write -buffer, the buffer will be flushed as well: - -[source,yaml] ------------------------------------------------------------------------------- -queue.spool: - file: - path: "${path.data}/spool.dat" - size: 512MiB - page_size: 16KiB - write: - buffer_size: 10MiB - flush.timeout: 5s - flush.events: 1024 ------------------------------------------------------------------------------- - -[float] -[[configuration-internal-queue-spool-reference]] -==== Configuration options - -You can specify the following options in the `queue.spool` section of the -+{beatname_lc}.yml+ config file: - -[float] -===== `file.path` - -The spool file path. The file is created on startup, if it does not exist. - -The default value is "${path.data}/spool.dat". - -[float] -===== `file.permissions` - -The file permissions. The permissions are applied when the file is -created. In case the file already exists, the file permissions are compared -with `file.permissions`. The spool file is not opened if the actual file -permissions are more permissive then configured. - -The default value is 0600. - - -[float] -===== `file.size` - -Spool file size. - -The default value is 100 MiB. - -NOTE: The size should be much larger then the expected event sizes -and write buffer size. Otherwise the queue will block, because it has not -enough space. - -NOTE: The file size cannot be changed once the file has been generated. This -limitation will be removed in the future. - -[float] -===== `file.page_size` - -The file's page size. - -The spool file is split into pages of `page_size`. All I/O -operations operate on complete pages. - -The default value is 4096 (4KiB). - -NOTE: This setting should match the file system's minimum block size. If the -`page_size` is not a multiple of the file system's block size, the file system -might create additional read operations on writes. - -NOTE: The page size is only set at file creation time. It cannot be changed -afterwards. - -[float] -===== `file.prealloc` - -If `prealloc` is set to `true`, truncate is used to reserve the space up to -`file.size`. This setting is only used when the file is created. - -The file will dynamically grow, if `prealloc` is set to false. The spool -blocks, if `prealloc` is `false` and the system is out of disk space. - -The default value is `true`. - -[float] -===== `write.buffer_size` - -The write buffer size. The write buffer is flushed, once the buffer size is exceeded. - -Very big events are allowed to be bigger then the configured buffer size. But -the write buffer will be flushed right after the event has been serialized. - -The default value is 1MiB. - -[float] -===== `write.codec` - -The event encoding used for serialized events. Valid values are `json` and `cbor`. - -The default value is `cbor`. - -[float] -===== `write.flush.timeout` - -Maximum wait time of the oldest event in the write buffer. If set to 0, the -write buffer will only be flushed once `write.flush.events` or `write.buffer_size` is fulfilled. - -The default value is 1s. - -[float] -===== `write.flush.events` - -Number of buffered events. The write buffer is flushed once the limit is reached. - -The default value is 16384. - -[float] -===== `read.flush.timeout` - -The spool reader tries to read up to the output's `bulk_max_size` events at once. - -If `read.flush.timeout` is set to 0s, all available events are forwarded -immediately to the output. - -If `read.flush.timeout` is set to a value bigger then 0s, the spool will wait -for more events to be flushed. Events are forwarded to the output if -`bulk_max_size` events have been read or the oldest read event has been waiting -for the configured duration. - -The default value is 0s. diff --git a/libbeat/publisher/includes/includes.go b/libbeat/publisher/includes/includes.go index a14dd16d3ba9..befc0e93d43e 100644 --- a/libbeat/publisher/includes/includes.go +++ b/libbeat/publisher/includes/includes.go @@ -29,5 +29,4 @@ import ( _ "github.com/elastic/beats/v7/libbeat/outputs/redis" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/diskqueue" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/memqueue" - _ "github.com/elastic/beats/v7/libbeat/publisher/queue/spool" ) diff --git a/libbeat/publisher/pipeline/stress/configs/pipeline/small_spool.yml b/libbeat/publisher/pipeline/stress/configs/pipeline/small_spool.yml deleted file mode 100644 index d5f999440e30..000000000000 --- a/libbeat/publisher/pipeline/stress/configs/pipeline/small_spool.yml +++ /dev/null @@ -1,11 +0,0 @@ -pipeline.queue.spool: - file: - path: ${test.tmpdir}/${test.name}-spool.dat - size: 1MiB - page_size: 4KiB - prealloc: true - write: - buffer_size: 16KiB - flush_timeout: 100ms - read: - flush_timeout: 0 diff --git a/libbeat/publisher/pipeline/stress/stress_test.go b/libbeat/publisher/pipeline/stress/stress_test.go index b12af68681f8..c0afcc3a0218 100644 --- a/libbeat/publisher/pipeline/stress/stress_test.go +++ b/libbeat/publisher/pipeline/stress/stress_test.go @@ -34,7 +34,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/publisher/pipeline/stress" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/memqueue" - _ "github.com/elastic/beats/v7/libbeat/publisher/queue/spool" ) // additional flags diff --git a/libbeat/publisher/queue/spool/codec.go b/libbeat/publisher/queue/spool/codec.go deleted file mode 100644 index 69f693a4817e..000000000000 --- a/libbeat/publisher/queue/spool/codec.go +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "bytes" - "fmt" - "time" - - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/outputs/codec" - "github.com/elastic/beats/v7/libbeat/publisher" - "github.com/elastic/go-structform" - "github.com/elastic/go-structform/cborl" - "github.com/elastic/go-structform/gotype" - "github.com/elastic/go-structform/json" - "github.com/elastic/go-structform/ubjson" -) - -type encoder struct { - buf bytes.Buffer - folder *gotype.Iterator - codec codecID -} - -type decoder struct { - buf []byte - - json *json.Parser - cborl *cborl.Parser - ubjson *ubjson.Parser - unfolder *gotype.Unfolder -} - -type codecID uint8 - -type entry struct { - Timestamp int64 - Flags uint8 - Meta common.MapStr - Fields common.MapStr -} - -const ( - // Note: Never change order. Codec IDs must be not change in the future. Only - // adding new IDs is allowed. - codecUnknown codecID = iota - codecJSON - codecUBJSON - codecCBORL - - flagGuaranteed uint8 = 1 << 0 -) - -func newEncoder(codec codecID) (*encoder, error) { - switch codec { - case codecJSON, codecCBORL, codecUBJSON: - break - default: - return nil, fmt.Errorf("unknown codec type '%v'", codec) - } - - e := &encoder{codec: codec} - e.reset() - return e, nil -} - -func (e *encoder) reset() { - e.folder = nil - - var visitor structform.Visitor - switch e.codec { - case codecJSON: - visitor = json.NewVisitor(&e.buf) - case codecCBORL: - visitor = cborl.NewVisitor(&e.buf) - case codecUBJSON: - visitor = ubjson.NewVisitor(&e.buf) - default: - panic("no codec configured") - } - - folder, err := gotype.NewIterator(visitor, - gotype.Folders( - codec.MakeTimestampEncoder(), - codec.MakeBCTimestampEncoder(), - ), - ) - if err != nil { - panic(err) - } - - e.folder = folder -} - -func (e *encoder) encode(event *publisher.Event) ([]byte, error) { - e.buf.Reset() - e.buf.WriteByte(byte(e.codec)) - - var flags uint8 - if (event.Flags & publisher.GuaranteedSend) == publisher.GuaranteedSend { - flags = flagGuaranteed - } - - err := e.folder.Fold(entry{ - Timestamp: event.Content.Timestamp.UTC().UnixNano(), - Flags: flags, - Meta: event.Content.Meta, - Fields: event.Content.Fields, - }) - if err != nil { - e.reset() - return nil, err - } - - return e.buf.Bytes(), nil -} - -func newDecoder() *decoder { - d := &decoder{} - d.reset() - return d -} - -func (d *decoder) reset() { - unfolder, err := gotype.NewUnfolder(nil) - if err != nil { - panic(err) // can not happen - } - - d.unfolder = unfolder - d.json = json.NewParser(unfolder) - d.cborl = cborl.NewParser(unfolder) - d.ubjson = ubjson.NewParser(unfolder) -} - -// Buffer prepares the read buffer to hold the next event of n bytes. -func (d *decoder) Buffer(n int) []byte { - if cap(d.buf) > n { - d.buf = d.buf[:n] - } else { - d.buf = make([]byte, n) - } - return d.buf -} - -func (d *decoder) Decode() (publisher.Event, error) { - var ( - to entry - err error - codec = codecID(d.buf[0]) - contents = d.buf[1:] - ) - - d.unfolder.SetTarget(&to) - defer d.unfolder.Reset() - - switch codec { - case codecJSON: - err = d.json.Parse(contents) - case codecUBJSON: - err = d.ubjson.Parse(contents) - case codecCBORL: - err = d.cborl.Parse(contents) - default: - return publisher.Event{}, fmt.Errorf("unknown codec type '%v'", codec) - } - - if err != nil { - d.reset() // reset parser just in case - return publisher.Event{}, err - } - - var flags publisher.EventFlags - if (to.Flags & flagGuaranteed) != 0 { - flags |= publisher.GuaranteedSend - } - - return publisher.Event{ - Flags: flags, - Content: beat.Event{ - Timestamp: time.Unix(0, to.Timestamp), - Fields: to.Fields, - Meta: to.Meta, - }, - }, nil -} diff --git a/libbeat/publisher/queue/spool/codec_test.go b/libbeat/publisher/queue/spool/codec_test.go deleted file mode 100644 index 6460985f6c30..000000000000 --- a/libbeat/publisher/queue/spool/codec_test.go +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" - - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/publisher" -) - -func TestEncodeDecode(t *testing.T) { - tests := map[string]codecID{ - "json": codecJSON, - "ubjson": codecUBJSON, - "cborl": codecCBORL, - } - - fieldTimeStr := "2020-01-14T20:33:23.779Z" - fieldTime, _ := time.Parse(time.RFC3339Nano, fieldTimeStr) - event := publisher.Event{ - Content: beat.Event{ - Timestamp: time.Now().Round(0), - Fields: common.MapStr{ - "time": fieldTime, - "commontime": common.Time(fieldTime), - }, - }, - } - expected := publisher.Event{ - Content: beat.Event{ - Timestamp: event.Content.Timestamp, - Fields: common.MapStr{ - "time": fieldTime.Format(time.RFC3339Nano), - "commontime": common.Time(fieldTime).String(), - }, - }, - } - - for name, codec := range tests { - t.Run(name, func(t *testing.T) { - encoder, err := newEncoder(codec) - assert.NoError(t, err) - - encoded, err := encoder.encode(&event) - assert.NoError(t, err) - - decoder := newDecoder() - decoder.buf = encoded - - observed, err := decoder.Decode() - assert.NoError(t, err) - - assert.Equal(t, expected, observed) - }) - } -} diff --git a/libbeat/publisher/queue/spool/config.go b/libbeat/publisher/queue/spool/config.go deleted file mode 100644 index 1d9d9a3299d4..000000000000 --- a/libbeat/publisher/queue/spool/config.go +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "errors" - "fmt" - "os" - "strings" - "time" - - "github.com/dustin/go-humanize" - "github.com/joeshaw/multierror" - - "github.com/elastic/beats/v7/libbeat/common/cfgtype" -) - -type config struct { - File pathConfig `config:"file"` - Write writeConfig `config:"write"` - Read readConfig `config:"read"` -} - -type pathConfig struct { - Path string `config:"path"` - Permissions os.FileMode `config:"permissions"` - MaxSize cfgtype.ByteSize `config:"size"` - PageSize cfgtype.ByteSize `config:"page_size"` - Prealloc bool `config:"prealloc"` -} - -type writeConfig struct { - BufferSize cfgtype.ByteSize `config:"buffer_size"` - FlushEvents int `config:"flush.events"` - FlushTimeout time.Duration `config:"flush.timeout"` - Codec codecID `config:"codec"` -} - -type readConfig struct { - FlushTimeout time.Duration `config:"flush.timeout"` -} - -func defaultConfig() config { - return config{ - File: pathConfig{ - Path: "", - Permissions: 0600, - MaxSize: 100 * humanize.MiByte, - PageSize: 4 * humanize.KiByte, - Prealloc: true, - }, - Write: writeConfig{ - BufferSize: 1 * humanize.MiByte, - FlushTimeout: 1 * time.Second, - FlushEvents: 16 * 1024, - Codec: codecCBORL, - }, - Read: readConfig{ - FlushTimeout: 0, - }, - } -} - -func (c *pathConfig) Validate() error { - var errs multierror.Errors - - if c.MaxSize < humanize.MiByte { - errs = append(errs, errors.New("max size must be larger 1MiB")) - } - - if !c.Permissions.IsRegular() { - errs = append(errs, fmt.Errorf("permissions %v are not regular file permissions", c.Permissions.String())) - } else { - m := c.Permissions.Perm() - if (m & 0400) == 0 { - errs = append(errs, errors.New("file must be readable by current user")) - } - if (m & 0200) == 0 { - errs = append(errs, errors.New("file must be writable by current user")) - } - } - - // TODO: good 'limit' on pageSize? - - if c.PageSize >= c.MaxSize { - errs = append(errs, fmt.Errorf("page_size (%v) must be less then size (%v)", c.PageSize, c.MaxSize)) - } - - return errs.Err() -} - -func (c *writeConfig) Validate() error { - return nil -} - -func (c *readConfig) Validate() error { - return nil -} - -func (c *codecID) Unpack(value string) error { - ids := map[string]codecID{ - "json": codecJSON, - "ubjson": codecUBJSON, - "cbor": codecCBORL, - } - - id, exists := ids[strings.ToLower(value)] - if !exists { - return fmt.Errorf("codec '%v' not available", value) - } - - *c = id - return nil -} diff --git a/libbeat/publisher/queue/spool/consume.go b/libbeat/publisher/queue/spool/consume.go deleted file mode 100644 index 74f3058f739f..000000000000 --- a/libbeat/publisher/queue/spool/consume.go +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "errors" - "io" - - "github.com/elastic/beats/v7/libbeat/common/atomic" - "github.com/elastic/beats/v7/libbeat/publisher" - "github.com/elastic/beats/v7/libbeat/publisher/queue" -) - -type consumer struct { - ctx *spoolCtx - closed atomic.Bool - done chan struct{} - - resp chan getResponse - requ chan getRequest -} - -type batch struct { - events []publisher.Event - state ackState - ack chan batchAckMsg -} - -type ackState uint8 - -const ( - batchActive ackState = iota - batchACK -) - -func newConsumer(ctx *spoolCtx, requ chan getRequest) *consumer { - return &consumer{ - ctx: ctx, - closed: atomic.MakeBool(false), - done: make(chan struct{}), - - // internal API - resp: make(chan getResponse), - requ: requ, - } -} - -func (c *consumer) Close() error { - if c.closed.Swap(true) { - return errors.New("already closed") - } - - close(c.done) - return nil -} - -func (c *consumer) Closed() bool { - return c.closed.Load() || c.ctx.Closed() -} - -func (c *consumer) Get(sz int) (queue.Batch, error) { - log := c.ctx.logger - - if c.Closed() { - return nil, io.EOF - } - - var resp getResponse - for { - select { - case <-c.ctx.Done(): - return nil, io.EOF - - case <-c.done: - return nil, io.EOF - - case c.requ <- getRequest{sz: sz, resp: c.resp}: - } - - resp = <-c.resp - err := resp.err - if err == nil { - break - } - - if err != errRetry { - log.Debug("consumer: error response:", err) - return nil, err - } - } - - log.Debug("consumer: received batch:", len(resp.buf)) - return &batch{ - events: resp.buf, - state: batchActive, - ack: resp.ack, - }, nil -} - -func (b *batch) Events() []publisher.Event { - if b.state != batchActive { - panic("Get Events from inactive batch") - } - return b.events -} - -func (b *batch) ACK() { - if b.state != batchActive { - switch b.state { - case batchACK: - panic("Can not acknowledge already acknowledged batch") - default: - panic("inactive batch") - } - } - - b.report() -} - -func (b *batch) report() { - if b.ack != nil { - b.ack <- batchAckMsg{} - } -} diff --git a/libbeat/publisher/queue/spool/inbroker.go b/libbeat/publisher/queue/spool/inbroker.go deleted file mode 100644 index b165f2a152b9..000000000000 --- a/libbeat/publisher/queue/spool/inbroker.go +++ /dev/null @@ -1,550 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "fmt" - "math" - "time" - - "github.com/elastic/beats/v7/libbeat/publisher/queue" - "github.com/elastic/go-txfile/pq" -) - -type inBroker struct { - ctx *spoolCtx - ackListener queue.ACKListener - - // active state handler - state func(*inBroker) bool - - // api channels - events chan pushRequest - pubCancel chan producerCancelRequest - - // queue signaling - sigACK chan struct{} - sigFlush chan uint - ackDone chan struct{} - - // queue state - queue *pq.Queue - writer *pq.Writer - clientStates clientStates - - // Event contents, that still needs to be send to the queue. An event is - // pending if it has been serialized, but not added to the write buffer in - // full, as some I/O operation on the write buffer failed. - // => - // - keep pointer to yet unwritten event contents - // - do not accept any events if pending is not nil - // - wait for signal from reader/queue-gc to retry writing the pending - // events contents - pending []byte - - bufferedEvents uint // number of buffered events - - // flush settings - timer *timer - flushEvents uint - - enc *encoder -} - -const ( - inSigChannelSize = 3 - inEventChannelSize = 20 -) - -func newInBroker( - ctx *spoolCtx, - ackListener queue.ACKListener, - qu *pq.Queue, - codec codecID, - flushTimeout time.Duration, - flushEvents uint, -) (*inBroker, error) { - enc, err := newEncoder(codec) - if err != nil { - return nil, err - } - - writer, err := qu.Writer() - if err != nil { - return nil, err - } - - b := &inBroker{ - ctx: ctx, - ackListener: ackListener, - state: (*inBroker).stateEmpty, - - // API - events: make(chan pushRequest, inEventChannelSize), - pubCancel: make(chan producerCancelRequest), - sigACK: make(chan struct{}, inSigChannelSize), - sigFlush: make(chan uint, inSigChannelSize), - ackDone: make(chan struct{}), - - // queue state - queue: qu, - writer: writer, - clientStates: clientStates{}, - pending: nil, - bufferedEvents: 0, - - // internal - timer: newTimer(flushTimeout), - flushEvents: flushEvents, - enc: enc, - } - - ctx.Go(b.eventLoop) - ctx.Go(b.ackLoop) - return b, nil -} - -func (b *inBroker) Producer(cfg queue.ProducerConfig) queue.Producer { - return newProducer(b.ctx, b.pubCancel, b.events, cfg.ACK, cfg.OnDrop, cfg.DropOnCancel) -} - -// onFlush is run whenever the queue flushes it's write buffer. The callback is -// run in the same go-routine as the Flush was executed from. -// Only the (*inBroker).eventLoop triggers a flush. -func (b *inBroker) onFlush(n uint) { - log := b.ctx.logger - log.Debug("inbroker: onFlush ", n) - - if n == 0 { - return - } - - if b.ackListener != nil { - b.ackListener.OnACK(int(n)) - } - b.ctx.logger.Debug("inbroker: flushed events:", n) - b.bufferedEvents -= n - b.sigFlush <- n -} - -// onACK is run whenever the queue releases ACKed events. The number of acked -// events and freed pages will is reported. -// Flush events are forward to the brokers eventloop, so to give the broker a -// chance to retry writing in case it has been blocked on a full queue. -func (b *inBroker) onACK(events, pages uint) { - if pages > 0 { - b.sigACK <- struct{}{} - } -} - -func (b *inBroker) ackLoop() { - log := b.ctx.logger - - log.Debug("start flush ack loop") - defer log.Debug("stop flush ack loop") - - for { - var n uint - select { - case <-b.ackDone: - return - - case n = <-b.sigFlush: - log.Debug("inbroker: receive flush", n) - states := b.clientStates.Pop(int(n)) - b.sendACKs(states) - } - } -} - -// sendACKs returns the range of ACKed/Flushed events to the individual -// producers ACK handlers. -func (b *inBroker) sendACKs(states []clientState) { - log := b.ctx.logger - - // reverse iteration on client states, so to report ranges of ACKed events - // only once. - N := len(states) - total := 0 - for i := N - 1; i != -1; i-- { - st := &states[i] - if st.state == nil { - continue - } - - count := (st.seq - st.state.lastACK) - if count == 0 || count > math.MaxUint32/2 { - // seq number comparison did underflow. This happens only if st.seq has - // already been acknowledged - // log.Debug("seq number already acked: ", st.seq) - - st.state = nil - continue - } - - log.Debugf("broker ACK events: count=%v, start-seq=%v, end-seq=%v\n", - count, - st.state.lastACK+1, - st.seq, - ) - - total += int(count) - if total > N { - panic(fmt.Sprintf("Too many events acked (expected=%v, total=%v)", - N, total, - )) - } - - // report range of ACKed events - st.state.ackCB(int(count)) - st.state.lastACK = st.seq - st.state = nil - } -} - -func (b *inBroker) eventLoop() { - log := b.ctx.logger - log.Info("spool input eventloop start") - defer log.Info("spool input eventloop stop") - - // notify ackLoop to stop only after eventLoop has finished (after last flush) - defer close(b.ackDone) - defer b.eventloopShutdown() - - for { - ok := b.state(b) - if !ok { - break - } - } -} - -func (b *inBroker) eventloopShutdown() { - // try to flush events/buffers on shutdown. - if b.bufferedEvents == 0 { - return - } - - // Try to flush pending events. - w := b.writer - for len(b.pending) > 0 { - n, err := w.Write(b.pending) - b.pending = b.pending[n:] - if err != nil { - return - } - } - w.Flush() -} - -// stateEmpty is the brokers active state if the write buffer is empty and the -// queue did not block on write or flush operations. -// ACKs from the output are ignored, as events can still be added to the write -// buffer. -// -// stateEmpty transitions: -// -> stateEmpty if serializing the event failed -// -> stateWithTimer if event is written to buffer without flush -// => start timer -// -> stateBlocked if queue did return an error on write (Flush failed) -func (b *inBroker) stateEmpty() bool { - log := b.ctx.logger - - select { - case <-b.ctx.Done(): - return false - - case req := <-b.events: - log.Debug("inbroker (stateEmpty): new event") - - buf, st, err := b.encodeEvent(&req) - if err != nil { - log.Debug(" inbroker (stateEmpty): encode failed") - b.respondDrop(&req) - break - } - - // write/flush failed -> block until space in file becomes available - err = b.addEvent(buf, st) - if err != nil { - log.Debug(" inbroker: append failed, blocking") - b.state = (*inBroker).stateBlocked - break - } - - // start flush timer - if b.flushEvents > 0 && b.bufferedEvents == b.flushEvents { - log.Debug(" inbroker (stateEmpty): flush events") - err := b.flushBuffer() - if err != nil { - log.Debug(" inbroker (stateEmpty): flush failed, blocking") - b.state = (*inBroker).stateBlocked - } - break - - } else if b.bufferedEvents > 0 { - log.Debug(" inbroker (stateEmpty): start flush timer") - b.timer.Start() - b.state = (*inBroker).stateWithTimer - } - - case req := <-b.pubCancel: - b.handleCancel(&req) - - case <-b.sigACK: - // ignore ACKs as long as we can write without blocking - } - - return true -} - -// stateWithTimer is the brokers active state, if the write buffer is not empty. -// The flush timer is enabled as long as the broker is in this state. -// ACKs from the output are ignored, as events can still be added to the write -// buffer. -// -// stateWithTimer transitions: -// -> stateWithTimer -// - if serializing failed -// - if event is added to buffer, without flush -// - flush, but more events are available in the buffer (might reset timer) -// -> stateEmpty if all events have been flushed -// -> stateBlocked if queue did return an error on write/flush (Flush failed) -func (b *inBroker) stateWithTimer() bool { - log := b.ctx.logger - - select { - case <-b.ctx.Done(): - return false - - case req := <-b.events: - log.Debug("inbroker (stateWithTimer): new event") - - buf, st, err := b.encodeEvent(&req) - if err != nil { - log.Debug(" inbroker (stateWithTimer): encode failed") - b.respondDrop(&req) - break - } - - count := b.bufferedEvents - err = b.addEvent(buf, st) - if err != nil { - log.Debug(" inbroker (stateWithTimer): append failed, blocking") - b.state = (*inBroker).stateBlocked - break - } - - flushed := b.bufferedEvents < count - if !flushed && b.flushEvents > 0 && b.bufferedEvents == b.flushEvents { - err := b.flushBuffer() - if err != nil { - log.Debug(" inbroker (stateWithTimer): flush failed, blocking") - b.state = (*inBroker).stateBlocked - break - } - - flushed = true - } - - if !flushed { - break - } - - // write buffer has been flushed, reset timer and broker state - log.Debug(" inbroker (stateWithTimer): buffer flushed") - if b.bufferedEvents == 0 { - b.timer.Stop(false) - b.state = (*inBroker).stateEmpty - } else { - // restart timer, as new event is most likely the only event buffered - // -> reduce IO - log.Debug(" inbroker (stateWithTimer): start flush timer") - b.timer.Restart() - } - - case req := <-b.pubCancel: - b.handleCancel(&req) - - case <-b.timer.C: - log.Debug("inbroker (stateWithTimer): flush timeout", b.bufferedEvents) - - b.timer.Stop(true) - - err := b.flushBuffer() - if err != nil { - log.Debug(" inbroker (stateWithTimer): flush failed, blocking") - b.state = (*inBroker).stateBlocked - break - } - - log.Debug(" inbroker (stateWithTimer): flush succeeded") - - if b.bufferedEvents > 0 { - // flush did not push all events? Restart timer. - log.Debug(" inbroker (stateWithTimer): start flush timer", b.bufferedEvents) - b.timer.Start() - break - } - - b.state = (*inBroker).stateEmpty - - case <-b.sigACK: - // ignore ACKs as long as we can write without blocking - } - - return true -} - -// stateBlocked is the brokers active state if the write buffer can not accept -// any new events. -// The broker will wait for an ACK signal from the outputs and retry flushing, -// in the hope of enough memory being available to flush the buffers. -// If flush did succeed, we try to add the pending event. -// For the time the broker is in this state, no events from any producers will -// be accepted. Thusly all producers will block. Closing a producer, unblocks -// the producer. The producers event (after close) might be processed or -// ignored in the future. -// -// stateBlocked transitions: -// -> stateEmpty if flush was successful and write buffer is empty -// -> stateWithTimer if flush was successful, but we still have some pending events -// -> stateBlocked if flush failed (still not enough space) -func (b *inBroker) stateBlocked() bool { - log := b.ctx.logger - - select { - case <-b.ctx.Done(): - return false - - case req := <-b.pubCancel: - b.handleCancel(&req) - - case <-b.sigACK: - // TODO: - // Have write buffer report number of unallocated pages and take number - // of freed pages into account before retrying. This way no transaction - // must be created if it's already clear the flush will not succeed. - - log.Debug("inbroker (stateBlocked): ACK event from queue -> try to unblock") - - err := b.flushBuffer() - if err != nil { - log.Debug(" inbroker (stateBlocked): flush failed, blocking") - break - } - - if len(b.pending) > 0 { - tmp := b.pending - b.pending = nil - err := b.writeEvent(tmp) - if err != nil || len(b.pending) > 0 { - log.Debugf("writing pending event failed: %+v", err) - break - } - } - - if b.bufferedEvents == 0 { - b.state = (*inBroker).stateEmpty - break - } - - b.timer.Start() - log.Debug(" inbroker (stateBlocked): start flush timer") - b.state = (*inBroker).stateWithTimer - } - - return true -} - -func (b *inBroker) handleCancel(req *producerCancelRequest) { - // mark state as cancelled, so to not accept any new events - // from the state object. - if st := req.state; st != nil { - st.cancelled = true - } - - if req.resp != nil { - req.resp <- producerCancelResponse{removed: 0} - } -} - -func (b *inBroker) encodeEvent(req *pushRequest) ([]byte, clientState, error) { - buf, err := b.enc.encode(&req.event) - if err != nil { - return nil, clientState{}, err - } - - if req.state == nil { - return buf, clientState{}, nil - } - - return buf, clientState{seq: req.seq, state: req.state}, nil -} - -func (b *inBroker) respondDrop(req *pushRequest) { - if req.state != nil { - if cb := req.state.dropCB; cb != nil { - cb(req.event.Content) - } - } -} - -func (b *inBroker) addEvent(buf []byte, st clientState) error { - log := b.ctx.logger - - b.bufferedEvents++ - log.Debug(" inbroker: add event of size", len(buf), b.bufferedEvents) - - count := b.clientStates.Add(st) - log.Debug(" add event -> active:", count) - - err := b.writeEvent(buf) - log.Debugf(" inbroker write -> events=%v, err=%+v ", b.bufferedEvents, err) - - return err -} - -func (b *inBroker) writeEvent(buf []byte) error { - log := b.ctx.logger - - // append event to queue - w := b.writer - n, err := w.Write(buf) - buf = buf[n:] - if len(buf) > 0 { - b.pending = buf - } else if err == nil { - log.Debug("writer: finalize event in buffer") - err = w.Next() - } - - if err != nil { - log.Debugf("Appending event content to write buffer failed with %+v", err) - } - return err -} - -func (b *inBroker) flushBuffer() error { - err := b.writer.Flush() - if err != nil { - log := b.ctx.logger - log.Errorf("Spool flush failed with: %+v", err) - } - return err -} diff --git a/libbeat/publisher/queue/spool/internal_api.go b/libbeat/publisher/queue/spool/internal_api.go deleted file mode 100644 index a6fd97102d4b..000000000000 --- a/libbeat/publisher/queue/spool/internal_api.go +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "github.com/elastic/beats/v7/libbeat/publisher" -) - -// producer -> broker API -type ( - pushRequest struct { - event publisher.Event - seq uint32 - state *produceState - } - - producerCancelRequest struct { - state *produceState - resp chan producerCancelResponse - } - - producerCancelResponse struct { - removed int - } -) - -// consumer -> broker API - -type ( - getRequest struct { - sz int // request sz events from the broker - resp chan getResponse // channel to send response to - } - - getResponse struct { - ack chan batchAckMsg - err error - buf []publisher.Event - } - - batchAckMsg struct{} - - batchCancelRequest struct { - // ack *ackChan - } -) diff --git a/libbeat/publisher/queue/spool/log.go b/libbeat/publisher/queue/spool/log.go deleted file mode 100644 index 64150366b531..000000000000 --- a/libbeat/publisher/queue/spool/log.go +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "fmt" - "sync" - - "github.com/elastic/beats/v7/libbeat/logp" -) - -type logger interface { - Debug(...interface{}) - Debugf(string, ...interface{}) - - Info(...interface{}) - Infof(string, ...interface{}) - - Error(...interface{}) - Errorf(string, ...interface{}) -} - -var _defaultLogger struct { - singleton logger - init sync.Once -} - -func defaultLogger() logger { - _defaultLogger.init.Do(func() { - _defaultLogger.singleton = logp.NewLogger("spool") - }) - return _defaultLogger.singleton -} - -// func defaultLogger() logger { return (*outLogger)(nil) } - -type outLogger struct{} - -func (l *outLogger) Debug(vs ...interface{}) { l.report("Debug", vs) } -func (l *outLogger) Debugf(fmt string, vs ...interface{}) { l.reportf("Debug: ", fmt, vs) } - -func (l *outLogger) Info(vs ...interface{}) { l.report("Info", vs) } -func (l *outLogger) Infof(fmt string, vs ...interface{}) { l.reportf("Info", fmt, vs) } - -func (l *outLogger) Error(vs ...interface{}) { l.report("Error", vs) } -func (l *outLogger) Errorf(fmt string, vs ...interface{}) { l.reportf("Error", fmt, vs) } - -func (l *outLogger) report(level string, vs []interface{}) { - args := append([]interface{}{level, ":"}, vs...) - fmt.Println(args...) -} - -func (*outLogger) reportf(level string, str string, vs []interface{}) { - str = level + ": " + str - fmt.Printf(str, vs...) -} diff --git a/libbeat/publisher/queue/spool/module.go b/libbeat/publisher/queue/spool/module.go deleted file mode 100644 index acf22145c4b2..000000000000 --- a/libbeat/publisher/queue/spool/module.go +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/cfgwarn" - "github.com/elastic/beats/v7/libbeat/feature" - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/paths" - "github.com/elastic/beats/v7/libbeat/publisher/queue" - "github.com/elastic/go-txfile" -) - -func init() { - queue.RegisterQueueType( - "spool", - create, - feature.MakeDetails( - "Disk spool", - "Buffer events in disk spool before sending to the output.", - feature.Beta)) -} - -func create( - ackListener queue.ACKListener, logp *logp.Logger, cfg *common.Config, inQueueSize int, -) (queue.Queue, error) { - cfgwarn.Beta("Spooling to disk is beta") - - config := defaultConfig() - if err := cfg.Unpack(&config); err != nil { - return nil, err - } - - path := config.File.Path - if path == "" { - path = paths.Resolve(paths.Data, "spool.dat") - } - - flushEvents := uint(0) - if count := config.Write.FlushEvents; count > 0 { - flushEvents = uint(count) - } - - var log logger = logp - if logp == nil { - log = defaultLogger() - } - - return newDiskSpool(log, path, settings{ - ACKListener: ackListener, - Mode: config.File.Permissions, - WriteBuffer: uint(config.Write.BufferSize), - WriteFlushTimeout: config.Write.FlushTimeout, - WriteFlushEvents: flushEvents, - ReadFlushTimeout: config.Read.FlushTimeout, - Codec: config.Write.Codec, - File: txfile.Options{ - MaxSize: uint64(config.File.MaxSize), - PageSize: uint32(config.File.PageSize), - Prealloc: config.File.Prealloc, - Readonly: false, - }, - }) -} diff --git a/libbeat/publisher/queue/spool/outbroker.go b/libbeat/publisher/queue/spool/outbroker.go deleted file mode 100644 index 409b2cde3885..000000000000 --- a/libbeat/publisher/queue/spool/outbroker.go +++ /dev/null @@ -1,536 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "errors" - "sync" - "time" - - "github.com/elastic/beats/v7/libbeat/publisher" - "github.com/elastic/go-txfile/pq" -) - -type outBroker struct { - ctx *spoolCtx - state func(*outBroker) bool - - // internal API - sigFlushed chan uint - get chan getRequest - - // ack signaling - pendingACKs chanList // list of pending batches to be forwarded to the ackLoop - scheduledACKs chan chanList // shared channel for forwarding batches to ackLoop - schedACKs chan chanList // active ack forwarding channel, as used by broker (nil if pendingACKs is empty) - - // queue state - queue *pq.Queue - reader *pq.Reader - available uint // number of available events. getRequests are only accepted if available > 0 - events []publisher.Event - required int - total int - active getRequest - - // internal - timer *timer - dec *decoder -} - -type chanList struct { - head *ackChan - tail *ackChan -} - -type ackChan struct { - next *ackChan - ch chan batchAckMsg - total int // total number of events to ACK with this batch -} - -const ( - // maximum number of events if getRequest size is <0 - maxEvents = 2048 - - outSigChannelSize = 3 -) - -var ackChanPool = sync.Pool{ - New: func() interface{} { - return &ackChan{ - ch: make(chan batchAckMsg, 1), - } - }, -} - -var errRetry = errors.New("retry") - -func newOutBroker(ctx *spoolCtx, qu *pq.Queue, flushTimeout time.Duration) (*outBroker, error) { - reader := qu.Reader() - - var ( - avail uint - err error - ) - func() { - if err = reader.Begin(); err != nil { - return - } - defer reader.Done() - avail, err = reader.Available() - }() - if err != nil { - return nil, err - } - - b := &outBroker{ - ctx: ctx, - state: nil, - - // API - sigFlushed: make(chan uint, outSigChannelSize), - get: make(chan getRequest), - - // ack signaling - pendingACKs: chanList{}, - scheduledACKs: make(chan chanList), - schedACKs: nil, - - // queue state - queue: qu, - reader: reader, - available: avail, - events: nil, - required: 0, - total: 0, - active: getRequest{}, - - // internal - timer: newTimer(flushTimeout), - dec: newDecoder(), - } - - b.initState() - ctx.Go(b.eventLoop) - ctx.Go(b.ackLoop) - return b, nil -} - -func (b *outBroker) Consumer() *consumer { - return newConsumer(b.ctx, b.get) -} - -// onFlush is run whenever the queue flushes it's write buffer. The callback is -// run in the same go-routine as the Flush was executed from. -func (b *outBroker) onFlush(n uint) { - if n > 0 { - select { - case <-b.ctx.Done(): // ignore flush messages on shutdown - - case b.sigFlushed <- n: - - } - } -} - -// onACK is run whenever the queue releases ACKed events. The number of acked -// events and freed pages will is reported. -func (b *outBroker) onACK(events, pages uint) { -} - -func (b *outBroker) ackLoop() { - log := b.ctx.logger - - log.Debug("start output ack loop") - defer log.Debug("stop output ack loop") - - var ackList chanList // list of pending acks - for { - select { - case <-b.ctx.Done(): - return - - case lst := <-b.scheduledACKs: - ackList.concat(&lst) - - case <-ackList.channel(): - ackCh := ackList.pop() - - for { - log.Debugf("receive ACK of %v events\n", ackCh.total) - err := b.queue.ACK(uint(ackCh.total)) - if err != nil { - log.Debugf("ack failed with: %+v", err) - time.Sleep(1 * time.Second) - continue - } - - log.Debug("ACK succeeded") - break - } - - releaseACKChan(ackCh) - } - } -} - -func (b *outBroker) eventLoop() { - for { - ok := b.state(b) - if !ok { - break - } - } -} - -// initState resets the brokers state to the initial state and clears -// buffers/points from last state updates. -func (b *outBroker) initState() { - b.events = nil - b.required = 0 - b.total = 0 - b.active = getRequest{} - if b.available == 0 { - b.state = (*outBroker).stateWaitEvents - } else { - b.state = (*outBroker).stateActive - } -} - -// stateWaitEvents is the brokers state if the queue is empty. -// The broker waits for new events and does not accept and consumer requests. -// -// stateWaitEvents transitions: -// -> stateActive: if a queue flush signal has been received -func (b *outBroker) stateWaitEvents() bool { - log := b.ctx.logger - log.Debug("outbroker (stateWaitEvents): waiting for new events") - - select { - case <-b.ctx.Done(): - return false - - case n := <-b.sigFlushed: - log.Debug("outbroker (stateWaitEvents): flush event", n) - b.available += n - b.state = (*outBroker).stateActive - - case b.schedACKs <- b.pendingACKs: - b.handleACKsScheduled() - } - - return true -} - -// stateActive is the brokers initial state, waiting for consumer to request -// new events. -// Flush signals from the input are ignored. -// -// stateActive transitions: -// -> stateActive: if consumer event get request has been fulfilled (N events -// copied or 0 timeout) -// -> stateWaitEvents: if queue is empty after read -// -> stateWithTimer: if only small number of events are available and flush -// timeout is configured. -func (b *outBroker) stateActive() bool { - log := b.ctx.logger - - select { - case <-b.ctx.Done(): - return false - - case n := <-b.sigFlushed: - b.available += n - - case b.schedACKs <- b.pendingACKs: - b.handleACKsScheduled() - - case req := <-b.get: - var events []publisher.Event - required := maxEvents - if req.sz > 0 { - events = make([]publisher.Event, 0, req.sz) - required = req.sz - } - - log.Debug("outbroker (stateActive): get request", required) - - var err error - var total int - events, total, err = b.collectEvents(events, required) - required -= len(events) - b.available -= uint(total) - - log.Debug(" outbroker (stateActive): events collected", len(events), total, err) - - // forward error to consumer and continue with current state - if err != nil { - log.Debug(" outbroker (stateActive): return error") - b.returnError(req, events, total, err) - b.initState() - break - } - - // enough events? Return - if required == 0 || (len(events) > 0 && b.timer.Zero()) { - log.Debug(" outbroker (stateActive): return events") - b.returnEvents(req, events, total) - b.initState() // prepare for next request - break - } - - // If no events have been decoded, signal an error to the consumer to retry. - // Meanwhile reinitialize state, waiting for more events. - if len(events) == 0 { - b.returnError(req, nil, total, errRetry) - b.initState() - break - } - - // not enough events -> start timer and try to collect more - b.events = events - b.required = required - b.active = req - b.total = total - b.timer.Start() - log.Debug(" outbroker (stateActive): switch to stateWithTimer") - b.state = (*outBroker).stateWithTimer - } - - return true -} - -// stateWithTimer is the brokers active state, if the events read is less then -// the minimal number of requested events. -// Once the timer triggers or more events have been consumed, the get response -// will be send to the consumer. -// -// stateWithTimer transitions: -// -> stateWithTimer: if some, but not enough events have been read from the -// queue -// -> stateActive: if the timer triggers or enough events have been returned -// to the consumer -func (b *outBroker) stateWithTimer() bool { - log := b.ctx.logger - - select { - case <-b.ctx.Done(): - return false - - case b.schedACKs <- b.pendingACKs: - b.handleACKsScheduled() - - case <-b.timer.C: - b.timer.Stop(true) - log.Debug("outbroker (stateWithTimer): flush timer") - b.returnEvents(b.active, b.events, b.total) - - log.Debug("outbroker (stateWithTimer): switch to stateActive") - b.initState() - - case n := <-b.sigFlushed: - // yay, more events \o/ - - b.available += n - - L := len(b.events) - required := b.required - events, total, err := b.collectEvents(b.events, required) - b.available -= uint(total) - collected := len(events) - L - required -= collected - total += b.total - - log.Debug(" outbroker (stateWithTimer): events collected", len(events), total, err) - - // continue with stateWithTimer? - if err == nil && required > 0 { - b.events = events - b.total = total - b.required = required - log.Debug(" outbroker (stateWithTimer): switch to stateWithTimer") - break - } - - // done serving consumer request - b.timer.Stop(false) - if err != nil { - log.Debug(" outbroker (stateWithTimer): return error") - b.returnError(b.active, events, total, err) - } else { - log.Debug(" outbroker (stateWithTimer): return events") - b.returnEvents(b.active, events, total) - } - - log.Debug("outbroker (stateWithTimer): switch to stateActive") - b.initState() - } - - return true -} - -func (b *outBroker) handleACKsScheduled() { - b.schedACKs = nil - b.pendingACKs = chanList{} -} - -func (b *outBroker) newACKChan(total int) *ackChan { - ackCh := newACKChan(total) - b.pendingACKs.append(ackCh) - b.schedACKs = b.scheduledACKs - return ackCh -} - -// signalDrop forwards an ACK of total events to the ackloop. -// The batch is marked as ACKed by the output. -// signalDrop is used to free space in the queue, in case -// a continuous set of events has been dropped due to decoding errors. -func (b *outBroker) signalDrop(total int) { - ackCh := b.newACKChan(total) - ackCh.ch <- batchAckMsg{} -} - -func (b *outBroker) returnEvents(req getRequest, events []publisher.Event, total int) { - ackCh := b.newACKChan(total) - req.resp <- getResponse{ - ack: ackCh.ch, - err: nil, - buf: events, - } -} - -func (b *outBroker) returnError( - req getRequest, - events []publisher.Event, - total int, - err error, -) { - var ch chan batchAckMsg - - if len(events) == 0 && total > 0 { - b.signalDrop(total) - } - if len(events) > 0 { - ackCh := b.newACKChan(total) - ch = ackCh.ch - } - - req.resp <- getResponse{ - ack: ch, - err: err, - buf: events, - } -} - -func (b *outBroker) collectEvents( - events []publisher.Event, - N int, -) ([]publisher.Event, int, error) { - log := b.ctx.logger - reader := b.reader - - // ensure all read operations happen within same transaction - err := reader.Begin() - if err != nil { - return nil, 0, err - } - defer reader.Done() - - count := 0 - for N > 0 { - sz, err := reader.Next() - if sz <= 0 || err != nil { - return events, count, err - } - - count++ - - buf := b.dec.Buffer(sz) - _, err = reader.Read(buf) - if err != nil { - return events, count, err - } - - event, err := b.dec.Decode() - if err != nil { - log.Debug("Failed to decode event from spool: %v", err) - continue - } - - events = append(events, event) - N-- - } - - return events, count, nil -} - -func newACKChan(total int) *ackChan { - c := ackChanPool.Get().(*ackChan) - c.next = nil - c.total = total - return c -} - -func releaseACKChan(c *ackChan) { - c.next = nil - ackChanPool.Put(c) -} - -func (l *chanList) append(ch *ackChan) { - if l.head == nil { - l.head = ch - } else { - l.tail.next = ch - } - l.tail = ch -} - -func (l *chanList) concat(other *chanList) { - if other.head == nil { - return - } - - if l.head == nil { - *l = *other - return - } - - l.tail.next = other.head - l.tail = other.tail -} - -func (l *chanList) channel() chan batchAckMsg { - if l.head == nil { - return nil - } - return l.head.ch -} - -func (l *chanList) pop() *ackChan { - ch := l.head - if ch != nil { - l.head = ch.next - if l.head == nil { - l.tail = nil - } - } - - ch.next = nil - return ch -} diff --git a/libbeat/publisher/queue/spool/produce.go b/libbeat/publisher/queue/spool/produce.go deleted file mode 100644 index 6a74d93b1c61..000000000000 --- a/libbeat/publisher/queue/spool/produce.go +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "sync" - - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/publisher" - "github.com/elastic/beats/v7/libbeat/publisher/queue" -) - -// forgetfulProducer forwards event to the inBroker. The forgetfulProducer -// provides no event ACK handling and no callbacks. -type forgetfulProducer struct { - openState openState -} - -// ackProducer forwards events to the inBroker. The ackBroker provides -// functionality for ACK/Drop callbacks. -type ackProducer struct { - dropOnCancel bool - seq uint32 - state produceState - openState openState - pubCancel chan producerCancelRequest -} - -// openState tracks the producer->inBroker connection state. -type openState struct { - ctx *spoolCtx - done chan struct{} - events chan pushRequest -} - -// produceState holds the ackProducer internal callback and event ACK state -// shared between ackProducer instances and inBroker instances. -// The state is used to compute the number of per producer ACKed events and -// executing locally configured callbacks. -type produceState struct { - ackCB ackHandler - dropCB func(beat.Event) - cancelled bool - lastACK uint32 -} - -type ackHandler func(count int) - -type clientStates struct { - mux sync.Mutex - clients []clientState -} - -type clientState struct { - seq uint32 // event sequence number - state *produceState // the producer it's state used to compute and signal the ACK count -} - -func newProducer( - ctx *spoolCtx, - pubCancel chan producerCancelRequest, - events chan pushRequest, - ackCB ackHandler, - dropCB func(beat.Event), - dropOnCancel bool, -) queue.Producer { - openState := openState{ - ctx: ctx, - done: make(chan struct{}), - events: events, - } - - if ackCB == nil { - return &forgetfulProducer{openState: openState} - } - - p := &ackProducer{ - seq: 1, - dropOnCancel: dropOnCancel, - openState: openState, - pubCancel: pubCancel, - } - p.state.ackCB = ackCB - p.state.dropCB = dropCB - return p -} - -func (p *forgetfulProducer) Publish(event publisher.Event) bool { - return p.openState.publish(p.makeRequest(event)) -} - -func (p *forgetfulProducer) TryPublish(event publisher.Event) bool { - return p.openState.tryPublish(p.makeRequest(event)) -} - -func (p *forgetfulProducer) makeRequest(event publisher.Event) pushRequest { - return pushRequest{event: event} -} - -func (p *forgetfulProducer) Cancel() int { - p.openState.Close() - return 0 -} - -func (p *ackProducer) Publish(event publisher.Event) bool { - return p.updSeq(p.openState.publish(p.makeRequest(event))) -} - -func (p *ackProducer) TryPublish(event publisher.Event) bool { - return p.updSeq(p.openState.tryPublish(p.makeRequest(event))) -} - -func (p *ackProducer) Cancel() int { - p.openState.Close() - - if p.dropOnCancel { - ch := make(chan producerCancelResponse) - p.pubCancel <- producerCancelRequest{ - state: &p.state, - resp: ch, - } - - // wait for cancel to being processed - resp := <-ch - return resp.removed - } - return 0 -} - -func (p *ackProducer) updSeq(ok bool) bool { - if ok { - p.seq++ - } - return ok -} - -func (p *ackProducer) makeRequest(event publisher.Event) pushRequest { - return pushRequest{event: event, seq: p.seq, state: &p.state} -} - -func (st *openState) Close() { - close(st.done) -} - -func (st *openState) publish(req pushRequest) bool { - select { - case st.events <- req: - return true - case <-st.done: - st.events = nil - return false - } -} - -func (st *openState) tryPublish(req pushRequest) bool { - select { - case st.events <- req: - return true - case <-st.done: - st.events = nil - return false - default: - log := st.ctx.logger - log.Debugf("Dropping event, queue is blocked (seq=%v) ", req.seq) - return false - } -} - -func (s *clientStates) Add(st clientState) int { - s.mux.Lock() - s.clients = append(s.clients, st) - l := len(s.clients) - s.mux.Unlock() - return l -} - -func (s *clientStates) RemoveLast() { - s.mux.Lock() - s.clients = s.clients[:len(s.clients)-1] - s.mux.Unlock() -} - -func (s *clientStates) Pop(n int) (states []clientState) { - s.mux.Lock() - states, s.clients = s.clients[:n], s.clients[n:] - s.mux.Unlock() - return states -} diff --git a/libbeat/publisher/queue/spool/spool.go b/libbeat/publisher/queue/spool/spool.go deleted file mode 100644 index c796170fdc75..000000000000 --- a/libbeat/publisher/queue/spool/spool.go +++ /dev/null @@ -1,250 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "fmt" - "os" - "runtime" - "sync" - "time" - - "github.com/pkg/errors" - - "github.com/elastic/beats/v7/libbeat/common/atomic" - "github.com/elastic/beats/v7/libbeat/publisher/queue" - "github.com/elastic/go-txfile" - "github.com/elastic/go-txfile/pq" -) - -// diskSpool implements an on-disk queue.Queue. -type diskSpool struct { - // producer/input support - inCtx *spoolCtx - inBroker *inBroker - - // consumer/output support - outCtx *spoolCtx - outBroker *outBroker - - queue *pq.Queue - file *txfile.File -} - -type spoolCtx struct { - logger logger - wg sync.WaitGroup - active atomic.Bool - done chan struct{} -} - -// settings configure a new spool to be created. -type settings struct { - Mode os.FileMode - - File txfile.Options - - // Queue write buffer size. If a single event is bigger then the - // write-buffer, the write-buffer will grow. In this case will the write - // buffer be flushed and reset to its original size. - WriteBuffer uint - - ACKListener queue.ACKListener - - WriteFlushTimeout time.Duration - WriteFlushEvents uint - ReadFlushTimeout time.Duration - - Codec codecID -} - -const minInFlushTimeout = 100 * time.Millisecond -const minOutFlushTimeout = 0 * time.Millisecond - -// newDiskSpool creates and initializes a new file based queue. -func newDiskSpool(logger logger, path string, settings settings) (*diskSpool, error) { - mode := settings.Mode - if mode == 0 { - mode = os.ModePerm - } - - ok := false - inCtx := newSpoolCtx(logger) - outCtx := newSpoolCtx(logger) - defer ifNotOK(&ok, inCtx.Close) - defer ifNotOK(&ok, outCtx.Close) - - if info, err := os.Lstat(path); err != nil { - if !os.IsNotExist(err) { - return nil, err - } - } else if runtime.GOOS != "windows" { - perm := info.Mode().Perm() - cfgPerm := settings.Mode.Perm() - - // check if file has permissions set, that must not be set via config - if (perm | cfgPerm) != cfgPerm { - return nil, fmt.Errorf("file permissions for '%v' must be more strict (required permissions: %v, actual permissions: %v)", - path, cfgPerm, perm) - } - } - - f, err := txfile.Open(path, mode, settings.File) - if err != nil { - return nil, errors.Wrapf(err, "spool queue: failed to open file at path '%s'", path) - } - defer ifNotOK(&ok, ignoreErr(f.Close)) - - queueDelegate, err := pq.NewStandaloneDelegate(f) - if err != nil { - return nil, err - } - - spool := &diskSpool{ - inCtx: inCtx, - outCtx: outCtx, - } - - queue, err := pq.New(queueDelegate, pq.Settings{ - WriteBuffer: settings.WriteBuffer, - Flushed: spool.onFlush, - ACKed: spool.onACK, - }) - if err != nil { - return nil, err - } - defer ifNotOK(&ok, ignoreErr(queue.Close)) - - inFlushTimeout := settings.WriteFlushTimeout - if inFlushTimeout < minInFlushTimeout { - inFlushTimeout = minInFlushTimeout - } - inBroker, err := newInBroker( - inCtx, settings.ACKListener, queue, settings.Codec, - inFlushTimeout, settings.WriteFlushEvents) - if err != nil { - return nil, err - } - - outFlushTimeout := settings.ReadFlushTimeout - if outFlushTimeout < minOutFlushTimeout { - outFlushTimeout = minOutFlushTimeout - } - outBroker, err := newOutBroker(outCtx, queue, outFlushTimeout) - if err != nil { - return nil, err - } - - ok = true - spool.queue = queue - spool.inBroker = inBroker - spool.outBroker = outBroker - spool.file = f - return spool, nil -} - -// Close shuts down the queue and closes the used file. -func (s *diskSpool) Close() error { - // stop all workers (waits for all workers to be finished) - s.outCtx.Close() - s.inCtx.Close() - - // close queue (potentially flushing write buffer) - err := s.queue.Close() - - // finally unmap and close file - s.file.Close() - - return err -} - -// BufferConfig returns the queue initial buffer settings. -func (s *diskSpool) BufferConfig() queue.BufferConfig { - return queue.BufferConfig{MaxEvents: -1} -} - -// Producer creates a new queue producer for publishing events. -func (s *diskSpool) Producer(cfg queue.ProducerConfig) queue.Producer { - return s.inBroker.Producer(cfg) -} - -// Consumer creates a new queue consumer for consuming and acking events. -func (s *diskSpool) Consumer() queue.Consumer { - return s.outBroker.Consumer() -} - -// onFlush is run whenever the queue signals it's write buffer being flushed. -// Flush events are forwarded to all workers. -// The onFlush callback is directly called by the queue writer (same go-routine) -// on Write or Flush operations. -func (s *diskSpool) onFlush(n uint) { - s.inBroker.onFlush(n) - s.outBroker.onFlush(n) -} - -// onACK is run whenever the queue signals events being acked and removed from -// the queue. -// ACK events are forwarded to all workers. -func (s *diskSpool) onACK(events, pages uint) { - s.inBroker.onACK(events, pages) -} - -func newSpoolCtx(logger logger) *spoolCtx { - return &spoolCtx{ - logger: logger, - active: atomic.MakeBool(true), - done: make(chan struct{}), - } -} - -func (ctx *spoolCtx) Close() { - if ctx.active.CAS(true, false) { - close(ctx.done) - ctx.wg.Wait() - } -} - -func (ctx *spoolCtx) Done() <-chan struct{} { - return ctx.done -} - -func (ctx *spoolCtx) Open() bool { - return ctx.active.Load() -} - -func (ctx *spoolCtx) Closed() bool { - return !ctx.Open() -} - -func (ctx *spoolCtx) Go(fn func()) { - ctx.wg.Add(1) - go func() { - defer ctx.wg.Done() - fn() - }() -} - -func ifNotOK(b *bool, fn func()) { - if !(*b) { - fn() - } -} - -func ignoreErr(fn func() error) func() { - return func() { fn() } -} diff --git a/libbeat/publisher/queue/spool/spool_test.go b/libbeat/publisher/queue/spool/spool_test.go deleted file mode 100644 index b5947152d9a9..000000000000 --- a/libbeat/publisher/queue/spool/spool_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "flag" - "fmt" - "math/rand" - "testing" - "time" - - humanize "github.com/dustin/go-humanize" - - "github.com/elastic/beats/v7/libbeat/publisher/queue" - "github.com/elastic/beats/v7/libbeat/publisher/queue/queuetest" - "github.com/elastic/go-txfile" - "github.com/elastic/go-txfile/txfiletest" -) - -var seed int64 -var debug bool - -type testQueue struct { - *diskSpool - teardown func() -} - -type testLogger struct { - t *testing.T -} - -type silentLogger struct{} - -func init() { - flag.Int64Var(&seed, "seed", time.Now().UnixNano(), "test random seed") - flag.BoolVar(&debug, "noisy", false, "print test logs to console") -} - -func TestProduceConsumer(t *testing.T) { - maxEvents := 4096 - minEvents := 32 - - rand.Seed(seed) - events := rand.Intn(maxEvents-minEvents) + minEvents - batchSize := rand.Intn(events-8) + 4 - - t.Log("seed: ", seed) - t.Log("events: ", events) - t.Log("batchSize: ", batchSize) - - testWith := func(factory queuetest.QueueFactory) func(t *testing.T) { - return func(test *testing.T) { - t.Run("single", func(t *testing.T) { - queuetest.TestSingleProducerConsumer(t, events, batchSize, factory) - }) - t.Run("multi", func(t *testing.T) { - queuetest.TestMultiProducerConsumer(t, events, batchSize, factory) - }) - } - } - - testWith(makeTestQueue( - 128*humanize.KiByte, 4*humanize.KiByte, 16*humanize.KiByte, - 100*time.Millisecond, - ))(t) -} - -func makeTestQueue( - maxSize, pageSize, writeBuffer uint, - flushTimeout time.Duration, -) func(*testing.T) queue.Queue { - return func(t *testing.T) queue.Queue { - if debug { - fmt.Println("Test:", t.Name()) - } - - ok := false - path, cleanPath := txfiletest.SetupPath(t, "") - defer func() { - if !ok { - cleanPath() - } - }() - - var logger logger - if debug { - logger = &testLogger{t} - } else { - logger = new(silentLogger) - } - - spool, err := newDiskSpool(logger, path, settings{ - WriteBuffer: writeBuffer, - WriteFlushTimeout: flushTimeout, - Codec: codecCBORL, - File: txfile.Options{ - MaxSize: uint64(maxSize), - PageSize: uint32(pageSize), - Prealloc: true, - Readonly: false, - }, - }) - if err != nil { - t.Fatal(err) - } - - tq := &testQueue{diskSpool: spool, teardown: cleanPath} - return tq - } -} - -func (t *testQueue) Close() error { - err := t.diskSpool.Close() - t.teardown() - return err -} - -func (l *testLogger) Debug(vs ...interface{}) { l.report("Debug", vs) } -func (l *testLogger) Debugf(fmt string, vs ...interface{}) { l.reportf("Debug: ", fmt, vs) } - -func (l *testLogger) Info(vs ...interface{}) { l.report("Info", vs) } -func (l *testLogger) Infof(fmt string, vs ...interface{}) { l.reportf("Info", fmt, vs) } - -func (l *testLogger) Error(vs ...interface{}) { l.report("Error", vs) } -func (l *testLogger) Errorf(fmt string, vs ...interface{}) { l.reportf("Error", fmt, vs) } - -func (l *testLogger) report(level string, vs []interface{}) { - args := append([]interface{}{level, ":"}, vs...) - l.t.Log(args...) - fmt.Println(args...) -} - -func (l *testLogger) reportf(level string, str string, vs []interface{}) { - str = level + ": " + str - l.t.Logf(str, vs...) - fmt.Printf(str, vs...) -} - -func (*silentLogger) Debug(vs ...interface{}) {} -func (*silentLogger) Debugf(fmt string, vs ...interface{}) {} -func (*silentLogger) Info(vs ...interface{}) {} -func (*silentLogger) Infof(fmt string, vs ...interface{}) {} -func (*silentLogger) Error(vs ...interface{}) {} -func (*silentLogger) Errorf(fmt string, vs ...interface{}) {} diff --git a/libbeat/publisher/queue/spool/timer.go b/libbeat/publisher/queue/spool/timer.go deleted file mode 100644 index 9f08dcfc69aa..000000000000 --- a/libbeat/publisher/queue/spool/timer.go +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package spool - -import ( - "time" -) - -type timer struct { - // flush timer - timer *time.Timer - C <-chan time.Time - duration time.Duration -} - -func newTimer(duration time.Duration) *timer { - stdtimer := time.NewTimer(duration) - if !stdtimer.Stop() { - <-stdtimer.C - } - - return &timer{ - timer: stdtimer, - C: nil, - duration: duration, - } -} - -func (t *timer) Zero() bool { - return t.duration == 0 -} - -func (t *timer) Restart() { - t.Stop(false) - t.Start() -} - -func (t *timer) Start() { - if t.C != nil { - return - } - - t.timer.Reset(t.duration) - t.C = t.timer.C -} - -func (t *timer) Stop(triggered bool) { - if t.C == nil { - return - } - - if !triggered && !t.timer.Stop() { - <-t.C - } - - t.C = nil -} diff --git a/libbeat/scripts/cmd/stress_pipeline/main.go b/libbeat/scripts/cmd/stress_pipeline/main.go index 49ba19c686c0..2b32ad596a97 100644 --- a/libbeat/scripts/cmd/stress_pipeline/main.go +++ b/libbeat/scripts/cmd/stress_pipeline/main.go @@ -35,7 +35,6 @@ import ( "github.com/elastic/beats/v7/libbeat/paths" "github.com/elastic/beats/v7/libbeat/publisher/pipeline/stress" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/memqueue" - _ "github.com/elastic/beats/v7/libbeat/publisher/queue/spool" "github.com/elastic/beats/v7/libbeat/service" ) diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 178a5cb2411e..7673d7b01b50 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -1020,66 +1020,6 @@ metricbeat.modules: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index a34efacdc331..5f931ddde706 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -692,66 +692,6 @@ packetbeat.ignore_outgoing: false # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 1705648185a4..4cca1af761e6 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -120,66 +120,6 @@ winlogbeat.event_logs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index c5f30eecbe0c..f52cc6feab15 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -253,66 +253,6 @@ auditbeat.modules: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/dockerlogbeat/main.go b/x-pack/dockerlogbeat/main.go index e363aefb6670..36472e2ec9e8 100644 --- a/x-pack/dockerlogbeat/main.go +++ b/x-pack/dockerlogbeat/main.go @@ -20,7 +20,6 @@ import ( _ "github.com/elastic/beats/v7/libbeat/outputs/logstash" _ "github.com/elastic/beats/v7/libbeat/outputs/redis" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/memqueue" - _ "github.com/elastic/beats/v7/libbeat/publisher/queue/spool" "github.com/elastic/beats/v7/libbeat/service" "github.com/elastic/beats/v7/x-pack/dockerlogbeat/pipelinemanager" ) diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index c25163576d10..e96b8e7f97dc 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -3264,66 +3264,6 @@ filebeat.inputs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index 397214f8cd50..5ea23a3b0dbf 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -375,66 +375,6 @@ functionbeat.provider.aws.functions: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index 6bac78d08c20..8f0f019626bd 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -343,66 +343,6 @@ heartbeat.jobs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 575581600bd6..be4adb144c8a 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -1541,66 +1541,6 @@ metricbeat.modules: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/osquerybeat/osquerybeat.reference.yml b/x-pack/osquerybeat/osquerybeat.reference.yml index c22416ddb193..edb3adcfb1d4 100644 --- a/x-pack/osquerybeat/osquerybeat.reference.yml +++ b/x-pack/osquerybeat/osquerybeat.reference.yml @@ -94,66 +94,6 @@ seccomp.enabled: false # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index a34efacdc331..5f931ddde706 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -692,66 +692,6 @@ packetbeat.ignore_outgoing: false # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 982b46591ec9..5d06be1566a1 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -163,66 +163,6 @@ winlogbeat.event_logs: # length of its retry interval each time, up to this maximum. #max_retry_interval: 30s - # The spool queue will store events in a local spool file, before - # forwarding the events to the outputs. - # Note: the spool queue is deprecated and will be removed in the future. - # Use the disk queue instead. - # - # The spool file is a circular buffer, which blocks once the file/buffer is full. - # Events are put into a write buffer and flushed once the write buffer - # is full or the flush_timeout is triggered. - # Once ACKed by the output, events are removed immediately from the queue, - # making space for new events to be persisted. - #spool: - # The file namespace configures the file path and the file creation settings. - # Once the file exists, the `size`, `page_size` and `prealloc` settings - # will have no more effect. - #file: - # Location of spool file. The default value is ${path.data}/spool.dat. - #path: "${path.data}/spool.dat" - - # Configure file permissions if file is created. The default value is 0600. - #permissions: 0600 - - # File size hint. The spool blocks, once this limit is reached. The default value is 100 MiB. - #size: 100MiB - - # The files page size. A file is split into multiple pages of the same size. The default value is 4KiB. - #page_size: 4KiB - - # If prealloc is set, the required space for the file is reserved using - # truncate. The default value is true. - #prealloc: true - - # Spool writer settings - # Events are serialized into a write buffer. The write buffer is flushed if: - # - The buffer limit has been reached. - # - The configured limit of buffered events is reached. - # - The flush timeout is triggered. - #write: - # Sets the write buffer size. - #buffer_size: 1MiB - - # Maximum duration after which events are flushed if the write buffer - # is not full yet. The default value is 1s. - #flush.timeout: 1s - - # Number of maximum buffered events. The write buffer is flushed once the - # limit is reached. - #flush.events: 16384 - - # Configure the on-disk event encoding. The encoding can be changed - # between restarts. - # Valid encodings are: json, ubjson, and cbor. - #codec: cbor - #read: - # Reader flush timeout, waiting for more events to become available, so - # to fill a complete batch as required by the outputs. - # If flush_timeout is 0, all available events are forwarded to the - # outputs immediately. - # The default value is 0s. - #flush.timeout: 0s - # Sets the maximum number of CPUs that can be executing simultaneously. The # default is the number of logical CPUs available in the system. #max_procs: From 3e84736ab7f1d94e131092b31ccc0d1356851c59 Mon Sep 17 00:00:00 2001 From: Xiaohui Wen <35361142+hubbleview@users.noreply.github.com> Date: Tue, 23 Nov 2021 14:32:18 -0800 Subject: [PATCH 020/172] Change "filebeat.config.modules.enabled" to "true" (#28769) * Change filebeat.config.modules.enabled to true As per https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-configuration-reloading.html#load-module-config, the default value of filebeat.config.modules.enabled is `true`. Having it as `false` in filebeat.reference.yml would bring in confusion. * Fix build error Co-authored-by: dedemorton --- filebeat/_meta/config/filebeat.global.reference.yml.tmpl | 2 +- filebeat/filebeat.reference.yml | 2 +- x-pack/filebeat/filebeat.reference.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/filebeat/_meta/config/filebeat.global.reference.yml.tmpl b/filebeat/_meta/config/filebeat.global.reference.yml.tmpl index dccfc790a7c5..5686fe14f228 100644 --- a/filebeat/_meta/config/filebeat.global.reference.yml.tmpl +++ b/filebeat/_meta/config/filebeat.global.reference.yml.tmpl @@ -40,7 +40,7 @@ #reload.enabled: true #reload.period: 10s #modules: - #enabled: false + #enabled: true #path: modules.d/*.yml #reload.enabled: true #reload.period: 10s diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 45d679cc1944..6f85f929d280 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -1026,7 +1026,7 @@ filebeat.inputs: #reload.enabled: true #reload.period: 10s #modules: - #enabled: false + #enabled: true #path: modules.d/*.yml #reload.enabled: true #reload.period: 10s diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index e96b8e7f97dc..50cb79578be8 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -3179,7 +3179,7 @@ filebeat.inputs: #reload.enabled: true #reload.period: 10s #modules: - #enabled: false + #enabled: true #path: modules.d/*.yml #reload.enabled: true #reload.period: 10s From 1207d635d4636412652e52d457af96091b8336a2 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Wed, 24 Nov 2021 09:40:39 +0100 Subject: [PATCH 021/172] Skip config check in autodiscover for duplicated configurations (#29048) If the configuration is already running, it has been already checked, don't try to check it again to avoid problems with configuration checks that fail if some resource already exist with the same identifiers. --- CHANGELOG.next.asciidoc | 1 + libbeat/autodiscover/autodiscover.go | 39 +++++++++----- libbeat/autodiscover/autodiscover_test.go | 64 +++++++++++++++++++++++ 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 8308f6c3a419..8c10a23c61df 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -144,6 +144,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Allows disable pod events enrichment with deployment name {pull}28521[28521] - Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] +- Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] *Auditbeat* diff --git a/libbeat/autodiscover/autodiscover.go b/libbeat/autodiscover/autodiscover.go index 8c6977e8362b..e1f1d8d2bfcd 100644 --- a/libbeat/autodiscover/autodiscover.go +++ b/libbeat/autodiscover/autodiscover.go @@ -64,6 +64,10 @@ type Autodiscover struct { meta *meta.Map listener bus.Listener logger *logp.Logger + + // workDone is a channel used for testing purpouses, to know when the worker has + // done some work. + workDone chan struct{} } // NewAutodiscover instantiates and returns a new Autodiscover manager @@ -165,6 +169,11 @@ func (a *Autodiscover) worker() { // reset updated status updated = false } + + // For testing purpouses. + if a.workDone != nil { + a.workDone <- struct{}{} + } } } @@ -207,26 +216,30 @@ func (a *Autodiscover) handleStart(event bus.Event) bool { continue } - err = a.factory.CheckConfig(config) - if err != nil { - a.logger.Error(errors.Wrap(err, fmt.Sprintf( - "Auto discover config check failed for config '%s', won't start runner", - common.DebugString(config, true)))) - continue - } - // Update meta no matter what dynFields := a.meta.Store(hash, meta) + if _, ok := newCfg[hash]; ok { + a.logger.Debugf("Config %v duplicated in start event", common.DebugString(config, true)) + continue + } + if cfg, ok := a.configs[eventID][hash]; ok { a.logger.Debugf("Config %v is already running", common.DebugString(config, true)) newCfg[hash] = cfg continue - } else { - newCfg[hash] = &reload.ConfigWithMeta{ - Config: config, - Meta: &dynFields, - } + } + + err = a.factory.CheckConfig(config) + if err != nil { + a.logger.Error(errors.Wrap(err, fmt.Sprintf( + "Auto discover config check failed for config '%s', won't start runner", + common.DebugString(config, true)))) + continue + } + newCfg[hash] = &reload.ConfigWithMeta{ + Config: config, + Meta: &dynFields, } updated = true diff --git a/libbeat/autodiscover/autodiscover_test.go b/libbeat/autodiscover/autodiscover_test.go index 4b2ecfef1283..2d0ea26b6897 100644 --- a/libbeat/autodiscover/autodiscover_test.go +++ b/libbeat/autodiscover/autodiscover_test.go @@ -75,6 +75,8 @@ type mockAdapter struct { mutex sync.Mutex configs []*common.Config runners []*mockRunner + + CheckConfigCallCount int } // CreateConfig generates a valid list of configs from the given event, the received event will have all keys defined by `StartFilter` @@ -87,6 +89,8 @@ func (m *mockAdapter) CreateConfig(event bus.Event) ([]*common.Config, error) { // CheckConfig tests given config to check if it will work or not, returns errors in case it won't work func (m *mockAdapter) CheckConfig(c *common.Config) error { + m.CheckConfigCallCount++ + config := struct { Broken bool `config:"broken"` }{} @@ -324,6 +328,66 @@ func TestAutodiscoverHash(t *testing.T) { assert.False(t, runners[1].stopped) } +func TestAutodiscoverDuplicatedConfigConfigCheckCalledOnce(t *testing.T) { + goroutines := resources.NewGoroutinesChecker() + defer goroutines.Check(t) + + // Register mock autodiscover provider + busChan := make(chan bus.Bus, 1) + + Registry = NewRegistry() + Registry.AddProvider("mock", func(beatName string, b bus.Bus, uuid uuid.UUID, c *common.Config, k keystore.Keystore) (Provider, error) { + // intercept bus to mock events + busChan <- b + + return &mockProvider{}, nil + }) + + // Create a mock adapter that returns a duplicated config + runnerConfig, _ := common.NewConfigFrom(map[string]string{ + "id": "foo", + }) + adapter := mockAdapter{ + configs: []*common.Config{runnerConfig, runnerConfig}, + } + + // and settings: + providerConfig, _ := common.NewConfigFrom(map[string]string{ + "type": "mock", + }) + config := Config{ + Providers: []*common.Config{providerConfig}, + } + k, _ := keystore.NewFileKeystore("test") + // Create autodiscover manager + autodiscover, err := NewAutodiscover("test", nil, &adapter, &adapter, &config, k) + if err != nil { + t.Fatal(err) + } + + autodiscover.workDone = make(chan struct{}) + + // Start it + autodiscover.Start() + defer autodiscover.Stop() + eventBus := <-busChan + + // Publish a couple of events. + for i := 0; i < 2; i++ { + eventBus.Publish(bus.Event{ + "id": "foo", + "provider": "mock", + "start": true, + "meta": common.MapStr{ + "foo": "bar", + }, + }) + <-autodiscover.workDone + assert.Equal(t, 1, len(adapter.Runners()), "Only one runner should be started") + assert.Equal(t, 1, adapter.CheckConfigCallCount, "Check config should have been called only once") + } +} + func TestAutodiscoverWithConfigCheckFailures(t *testing.T) { goroutines := resources.NewGoroutinesChecker() defer goroutines.Check(t) From 606a7d27e9f14d7bf0eec3136de04b850c7db3bd Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Wed, 24 Nov 2021 10:15:41 +0100 Subject: [PATCH 022/172] override host on statsd metricset (#29103) * override host on statsd metricset * changelog --- CHANGELOG.next.asciidoc | 1 + metricbeat/helper/server/udp/udp.go | 4 ++++ x-pack/metricbeat/module/statsd/server/server.go | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 8c10a23c61df..d5d97facca22 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -372,6 +372,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Preliminary AIX support {pull}27954[27954] - Register additional name for `storage` metricset in the azure module. {pull}28447[28447] - Update reference to gosigar pacakge for filesystem windows fix. {pull}28909[28909] +- Override `Host()` on statsd MetricSet {pull}29103[29103] *Packetbeat* diff --git a/metricbeat/helper/server/udp/udp.go b/metricbeat/helper/server/udp/udp.go index e19f86975196..6bec8489b46f 100644 --- a/metricbeat/helper/server/udp/udp.go +++ b/metricbeat/helper/server/udp/udp.go @@ -71,6 +71,10 @@ func NewUdpServer(base mb.BaseMetricSet) (server.Server, error) { }, nil } +func (g *UdpServer) GetHost() string { + return g.udpaddr.String() +} + func (g *UdpServer) Start() error { listener, err := net.ListenUDP("udp", g.udpaddr) if err != nil { diff --git a/x-pack/metricbeat/module/statsd/server/server.go b/x-pack/metricbeat/module/statsd/server/server.go index 3e9f35d84366..b9df691b6b88 100644 --- a/x-pack/metricbeat/module/statsd/server/server.go +++ b/x-pack/metricbeat/module/statsd/server/server.go @@ -104,6 +104,12 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { }, nil } +// Host returns the hostname or other module specific value that identifies a +// specific host or service instance from which to collect metrics. +func (b *MetricSet) Host() string { + return b.server.(*udp.UdpServer).GetHost() +} + func buildMappings(config []StatsdMapping) (map[string]StatsdMapping, error) { mappings := make(map[string]StatsdMapping, len(config)) replacer := strings.NewReplacer(".", `\.`, "<", "(?P<", ">", ">[^.]+)") From db5de274fd5a55d113d0bf95323c78e51d3adbfd Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 24 Nov 2021 12:54:21 +0200 Subject: [PATCH 023/172] Use NamedWatcher in Agent's k8s provider (#29095) --- libbeat/common/kubernetes/watcher.go | 6 +++--- .../pkg/composable/providers/kubernetes/node.go | 2 +- .../pkg/composable/providers/kubernetes/pod.go | 6 +++--- .../pkg/composable/providers/kubernetes/service.go | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libbeat/common/kubernetes/watcher.go b/libbeat/common/kubernetes/watcher.go index b96b837e4e3a..75f32f66d667 100644 --- a/libbeat/common/kubernetes/watcher.go +++ b/libbeat/common/kubernetes/watcher.go @@ -99,9 +99,9 @@ func NewWatcher(client kubernetes.Interface, resource Resource, opts WatchOption return NewNamedWatcher("", client, resource, opts, indexers) } -// NewNamedWatcher does the same as NewWatcher, but also allows to name the k8s -// client's workqueue that is used by the watcher, unlike NewWatcher which sets -// the workqueue name to "". Workqueue name is important for exposing workqueue +// NewNamedWatcher initializes the watcher client to provide an events handler for +// resource from the cluster (filtered to the given node) and also allows to name the k8s +// client's workqueue that is used by the watcher. Workqueue name is important for exposing workqueue // metrics, if it is empty, its metrics will not be logged by the k8s client. func NewNamedWatcher(name string, client kubernetes.Interface, resource Resource, opts WatchOptions, indexers cache.Indexers) (Watcher, error) { var store cache.Store diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/node.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/node.go index db63a1cc2abb..29cac3efdb56 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/node.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/node.go @@ -43,7 +43,7 @@ func NewNodeEventer( logger *logp.Logger, client k8s.Interface, scope string) (Eventer, error) { - watcher, err := kubernetes.NewWatcher(client, &kubernetes.Node{}, kubernetes.WatchOptions{ + watcher, err := kubernetes.NewNamedWatcher("agent-node", client, &kubernetes.Node{}, kubernetes.WatchOptions{ SyncTimeout: cfg.SyncPeriod, Node: cfg.Node, IsUpdated: isUpdated, diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go index 735e123b7c0a..3a702b95c0e0 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go @@ -74,7 +74,7 @@ func NewPodEventer( logger *logp.Logger, client k8s.Interface, scope string) (Eventer, error) { - watcher, err := kubernetes.NewWatcher(client, &kubernetes.Pod{}, kubernetes.WatchOptions{ + watcher, err := kubernetes.NewNamedWatcher("agent-pod", client, &kubernetes.Pod{}, kubernetes.WatchOptions{ SyncTimeout: cfg.SyncPeriod, Node: cfg.Node, Namespace: cfg.Namespace, @@ -92,11 +92,11 @@ func NewPodEventer( if metaConf == nil { metaConf = metadata.GetDefaultResourceMetadataConfig() } - nodeWatcher, err := kubernetes.NewWatcher(client, &kubernetes.Node{}, options, nil) + nodeWatcher, err := kubernetes.NewNamedWatcher("agent-node", client, &kubernetes.Node{}, options, nil) if err != nil { logger.Errorf("couldn't create watcher for %T due to error %+v", &kubernetes.Node{}, err) } - namespaceWatcher, err := kubernetes.NewWatcher(client, &kubernetes.Namespace{}, kubernetes.WatchOptions{ + namespaceWatcher, err := kubernetes.NewNamedWatcher("agent-namespace", client, &kubernetes.Namespace{}, kubernetes.WatchOptions{ SyncTimeout: cfg.SyncPeriod, }, nil) if err != nil { diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go index 40e12bb53ffb..5f6f588fd23b 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/service.go @@ -44,7 +44,7 @@ func NewServiceEventer( logger *logp.Logger, client k8s.Interface, scope string) (Eventer, error) { - watcher, err := kubernetes.NewWatcher(client, &kubernetes.Service{}, kubernetes.WatchOptions{ + watcher, err := kubernetes.NewNamedWatcher("agent-service", client, &kubernetes.Service{}, kubernetes.WatchOptions{ SyncTimeout: cfg.SyncPeriod, Node: cfg.Node, HonorReSyncs: true, @@ -54,7 +54,7 @@ func NewServiceEventer( } metaConf := metadata.GetDefaultResourceMetadataConfig() - namespaceWatcher, err := kubernetes.NewWatcher(client, &kubernetes.Namespace{}, kubernetes.WatchOptions{ + namespaceWatcher, err := kubernetes.NewNamedWatcher("agent-namespace", client, &kubernetes.Namespace{}, kubernetes.WatchOptions{ SyncTimeout: cfg.SyncPeriod, Namespace: cfg.Namespace, }, nil) From 73333b450e5594d25594121a5fcf74874769b26f Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Wed, 24 Nov 2021 11:58:11 +0000 Subject: [PATCH 024/172] [mergify]: notify conflicts in PRs that are still open (#29122) --- .mergify.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 15ef4cd538ab..d2ee975b7e1f 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -14,6 +14,8 @@ pull_request_rules: title: "[{{ destination_branch }}](backport #{{ number }}) {{ title }}" - name: ask to resolve conflict conditions: + - -merged + - -closed - conflict actions: comment: From 559492373b6b52ca6f306064c61728fcbdec5ee2 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Wed, 24 Nov 2021 09:02:07 -0700 Subject: [PATCH 025/172] Fix rds metadata in cloudwatch metricset (#29106) --- CHANGELOG.next.asciidoc | 1 + x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index d5d97facca22..a4f34cb48ba6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -237,6 +237,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix list_docker.go {pull}28374[28374] - Use xpack.enabled on SM modules to write into .monitoring indices when using Metricbeat standalone {pull}28365[28365] - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] +- Fix rds metadata in cloudwatch metricset. {pull}29106[29106] *Packetbeat* diff --git a/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go b/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go index c74234af7ce9..e732749d0162 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go @@ -87,7 +87,8 @@ func getDBInstancesPerRegion(svc rdsiface.ClientAPI) (map[string]*rds.DBInstance instancesOutputs := map[string]*rds.DBInstance{} for _, dbInstance := range output.DBInstances { - instancesOutputs[*dbInstance.DBInstanceIdentifier] = &dbInstance + instance := dbInstance + instancesOutputs[*instance.DBInstanceIdentifier] = &instance } return instancesOutputs, nil } From 8e6345f4cdbf92df04e2e8b6d36c1e6e2af76f98 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Wed, 24 Nov 2021 11:15:10 -0800 Subject: [PATCH 026/172] Remove links to Journalbeat (#29134) --- libbeat/docs/getting-started.asciidoc | 1 - libbeat/docs/overview.asciidoc | 1 - 2 files changed, 2 deletions(-) diff --git a/libbeat/docs/getting-started.asciidoc b/libbeat/docs/getting-started.asciidoc index 5291f755e5b8..619ed2e03cb5 100644 --- a/libbeat/docs/getting-started.asciidoc +++ b/libbeat/docs/getting-started.asciidoc @@ -7,7 +7,6 @@ Each Beat is a separately installable product. To learn how to get started, see: * {filebeat-ref}/filebeat-installation-configuration.html[Filebeat] * {functionbeat-ref}/functionbeat-installation-configuration.html[Functionbeat] * {heartbeat-ref}/heartbeat-installation-configuration.html[Heartbeat] -* {journalbeat-ref}/journalbeat-installation-configuration.html[Journalbeat] * {metricbeat-ref}/metricbeat-installation-configuration.html[Metricbeat] * {packetbeat-ref}/packetbeat-installation-configuration.html[Packetbeat] * {winlogbeat-ref}/winlogbeat-installation-configuration.html[Winlogbeat] diff --git a/libbeat/docs/overview.asciidoc b/libbeat/docs/overview.asciidoc index bdc46aaaf280..6306874112fb 100644 --- a/libbeat/docs/overview.asciidoc +++ b/libbeat/docs/overview.asciidoc @@ -11,7 +11,6 @@ Audit data:: https://www.elastic.co/products/beats/auditbeat[Auditbeat] Log files:: https://www.elastic.co/products/beats/filebeat[Filebeat] Cloud data:: https://www.elastic.co/products/beats/functionbeat[Functionbeat] Availability:: https://www.elastic.co/products/beats/heartbeat[Heartbeat] -Systemd journals:: https://www.elastic.co/downloads/beats/journalbeat[Journalbeat] Metrics:: https://www.elastic.co/products/beats/metricbeat[Metricbeat] Network traffic:: https://www.elastic.co/products/beats/packetbeat[Packetbeat] Windows event logs:: https://www.elastic.co/products/beats/winlogbeat[Winlogbeat] From 3dc0afb3e07ba5f50203f2c41328f566e69f6639 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Thu, 25 Nov 2021 10:04:25 +0000 Subject: [PATCH 027/172] CI: enable AWS cloud testing on a PR basis if changes in certain files (#29047) --- Jenkinsfile | 19 +++++++++++-------- x-pack/filebeat/Jenkinsfile.yml | 14 ++++++++++++++ x-pack/metricbeat/Jenkinsfile.yml | 12 ++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 35ae38cb840b..9d52f95553f8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -291,13 +291,13 @@ def generateStages(Map args = [:]) { def cloud(Map args = [:]) { withGithubNotify(context: args.context) { withNode(labels: args.label, forceWorkspace: true){ - startCloudTestEnv(name: args.directory, dirs: args.dirs) + startCloudTestEnv(name: args.directory, dirs: args.dirs, withAWS: args.withAWS) } - withCloudTestEnv() { + withCloudTestEnv(args) { try { target(context: args.context, command: args.command, directory: args.directory, label: args.label, withModule: args.withModule, isMage: true, id: args.id) } finally { - terraformCleanup(name: args.directory, dir: args.directory) + terraformCleanup(name: args.directory, dir: args.directory, withAWS: args.withAWS) } } } @@ -868,14 +868,15 @@ def tarAndUploadArtifacts(Map args = [:]) { * This method executes a closure with credentials for cloud test * environments. */ -def withCloudTestEnv(Closure body) { +def withCloudTestEnv(Map args = [:], Closure body) { def maskedVars = [] def testTags = "${env.TEST_TAGS}" // Allow AWS credentials when the build was configured to do so with: // - the cloudtests build parameters // - the aws github label - if (params.allCloudTests || params.awsCloudTests || matchesPrLabel(label: 'aws')) { + // - forced with the cloud argument aws github label + if (params.allCloudTests || params.awsCloudTests || matchesPrLabel(label: 'aws') || args.get('withAWS', false)) { testTags = "${testTags},aws" def aws = getVaultSecret(secret: "${AWS_ACCOUNT_SECRET}").data if (!aws.containsKey('access_key')) { @@ -889,6 +890,7 @@ def withCloudTestEnv(Closure body) { [var: "AWS_ACCESS_KEY_ID", password: aws.access_key], [var: "AWS_SECRET_ACCESS_KEY", password: aws.secret_key], ]) + log(level: 'INFO', text: 'withCloudTestEnv: it has been configured to run in AWS.') } withEnv([ @@ -914,7 +916,7 @@ def startCloudTestEnv(Map args = [:]) { String name = normalise(args.name) def dirs = args.get('dirs',[]) stage("${name}-prepare-cloud-env"){ - withCloudTestEnv() { + withCloudTestEnv(args) { withBeatsEnv(archive: false, withModule: false) { try { dirs?.each { folder -> @@ -957,7 +959,7 @@ def terraformCleanup(Map args = [:]) { String name = normalise(args.name) String directory = args.dir stage("${name}-tear-down-cloud-env"){ - withCloudTestEnv() { + withCloudTestEnv(args) { withBeatsEnv(archive: false, withModule: false) { unstash("terraform-${name}") retryWithSleep(retries: 2, seconds: 5, backoff: true) { @@ -1082,6 +1084,7 @@ class RunCommand extends co.elastic.beats.BeatsFunction { public run(Map args = [:]){ steps.stageStatusCache(args){ def withModule = args.content.get('withModule', false) + def withAWS = args.content.get('withAWS', false) // // What's the retry policy for fighting the flakiness: // 1) Lint/Packaging/Cloud/k8sTest stages don't retry, since their failures are normally legitim @@ -1140,7 +1143,7 @@ class RunCommand extends co.elastic.beats.BeatsFunction { steps.k8sTest(context: args.context, versions: args.content.k8sTest.split(','), label: args.label, id: args.id) } if(args?.content?.containsKey('cloud')) { - steps.cloud(context: args.context, command: args.content.cloud, directory: args.project, label: args.label, withModule: withModule, dirs: args.content.dirs, id: args.id) + steps.cloud(context: args.context, command: args.content.cloud, directory: args.project, label: args.label, withModule: withModule, dirs: args.content.dirs, id: args.id, withAWS: withAWS) } } } diff --git a/x-pack/filebeat/Jenkinsfile.yml b/x-pack/filebeat/Jenkinsfile.yml index 6cc9fd969f27..8ea1c14fa033 100644 --- a/x-pack/filebeat/Jenkinsfile.yml +++ b/x-pack/filebeat/Jenkinsfile.yml @@ -113,6 +113,20 @@ stages: labels: - "aws" stage: extended + cloudAWS: + cloud: "mage build test" + withAWS: true ## Enable the tests to run in AWS + withModule: true ## run the ITs only if the changeset affects a specific module. + dirs: ## run the cloud tests for the given modules. + - "x-pack/filebeat/input/awss3/_meta/terraform" + when: ## Override the top-level when. + changeset: ## when PR contains any of those entries in the changeset + - "^x-pack/filebeat/input/awss3/.*" + - "^x-pack/filebeat/module/aws/.*" + - "^x-pack/filebeat/input/awscloudwatch/.*" + - "^x-pack/filebeat/Jenkinsfile.yml" + - "^x-pack/libbeat/common/aws/.*" + stage: extended #windows-7-32: See https://github.com/elastic/beats/issues/22315 # mage: "mage build unitTest" # platforms: ## override default labels in this specific stage. diff --git a/x-pack/metricbeat/Jenkinsfile.yml b/x-pack/metricbeat/Jenkinsfile.yml index a9be741ddae5..7a619ed6f160 100644 --- a/x-pack/metricbeat/Jenkinsfile.yml +++ b/x-pack/metricbeat/Jenkinsfile.yml @@ -45,6 +45,18 @@ stages: labels: - "aws" stage: extended + cloudAWS: + cloud: "mage build test" + withAWS: true ## Enable the tests to run in AWS + withModule: true ## run the ITs only if the changeset affects a specific module. + dirs: ## run the cloud tests for the given modules. + - "x-pack/metricbeat/module/aws" + when: ## Override the top-level when. + changeset: ## when PR contains any of those entries in the changeset + - "^x-pack/metricbeat/module/aws/.*" + - "^x-pack/metricbeat/Jenkinsfile.yml" + - "^x-pack/libbeat/common/aws/.*" + stage: extended macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. From c43db8ce74d6dac1da04abb770c0d2abbed43015 Mon Sep 17 00:00:00 2001 From: Henadzi Siardziukou <92367828+nxei@users.noreply.github.com> Date: Thu, 25 Nov 2021 15:47:06 +0300 Subject: [PATCH 028/172] Added workflow file for builds with macos (#29148) * Added workflow file for builds with macos --- .github/workflows/macos-build.yml | 73 +++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/workflows/macos-build.yml diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml new file mode 100644 index 000000000000..eab20e98d7eb --- /dev/null +++ b/.github/workflows/macos-build.yml @@ -0,0 +1,73 @@ +name: build + +env: + GOPATH: /home/runner/work/gotest/gotest + GO111MODULE: off + REPO_PATH: src/gotest + MACOS_GOPATH: /Users/runner/work/gotest/gotest + GITHUB_TOKEN: ${{ github.token }} + +on: + workflow_dispatch: + inputs: + id: + description: 'Run ID' + required: true + runner: + description: 'Github actions runner' + required: false + default: 'macos-latest' + path: + description: 'Directory where to run command' + required: false + default: '' + pr: + description: 'Pull request id' + required: false + default: '' + go_version: + description: 'Go version' + required: false + default: '1.17' + command: + description: 'Command to run' + required: true + default: '' +jobs: + build: + runs-on: ${{ github.event.inputs.runner }} + steps: + - name: ${{ format('Run ID {0}', github.event.inputs.id) }} + run: echo Run ID ${{github.event.inputs.id}} + - name: Set environment for macos + if: ${{ contains(github.event.inputs.runner, 'macos') }} + run: | + echo Changed GOPATH to ${{ env.MACOS_GOPATH }} + echo "GOPATH="${{ env.MACOS_GOPATH }} >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ github.event.inputs.go_version }} + - name: Install dependencies + run: go get -u github.com/magefile/mage + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + ref: ${{ env.GITHUB_REF }} + path: ${{ env.REPO_PATH }} + - name: Checkout and merge PR + if: ${{ github.event.inputs.pr }} + run: | + set -x + cd ${{ env.GOPATH }}/${{ env.REPO_PATH }} + git config --global user.email "user@example.com" + git config --global user.name "user" + git fetch origin pull/${{ github.event.inputs.pr }}/head:${{ github.event.inputs.id }} + git checkout ${{ github.event.inputs.id }} + git checkout $GITHUB_REF_NAME + git merge --no-ff ${{ github.event.inputs.id }} + - name: Run command + run: | + set -x + cd ${{ env.GOPATH }}/${{ env.REPO_PATH }}/${{ github.event.inputs.path }} + ${{ github.event.inputs.command }} From 692ee17fb00c9aa2a57c1758c9af2b24b3c280c7 Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Thu, 25 Nov 2021 15:35:34 -0800 Subject: [PATCH 029/172] Fix agent download timeout values in yaml files (#29039) --- x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl | 2 +- x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl | 2 +- x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl | 2 +- x-pack/elastic-agent/_meta/elastic-agent.fleet.yml | 2 +- x-pack/elastic-agent/_meta/elastic-agent.yml | 2 +- x-pack/elastic-agent/elastic-agent.docker.yml | 2 +- x-pack/elastic-agent/elastic-agent.reference.yml | 2 +- x-pack/elastic-agent/elastic-agent.yml | 2 +- .../elastic-agent/pkg/agent/application/configuration_embed.go | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl index 23d6203c2ecc..a451165969f5 100644 --- a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl @@ -94,7 +94,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl index 312730db5920..922e6a4dd6a8 100644 --- a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl @@ -63,7 +63,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl index 78c64b51494b..a82360333039 100644 --- a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl @@ -63,7 +63,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/_meta/elastic-agent.fleet.yml b/x-pack/elastic-agent/_meta/elastic-agent.fleet.yml index 5e73fbe08210..9189547155ef 100644 --- a/x-pack/elastic-agent/_meta/elastic-agent.fleet.yml +++ b/x-pack/elastic-agent/_meta/elastic-agent.fleet.yml @@ -12,7 +12,7 @@ fleet: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present Elastic Agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/_meta/elastic-agent.yml b/x-pack/elastic-agent/_meta/elastic-agent.yml index 6167575e7690..493887180138 100644 --- a/x-pack/elastic-agent/_meta/elastic-agent.yml +++ b/x-pack/elastic-agent/_meta/elastic-agent.yml @@ -63,7 +63,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/elastic-agent.docker.yml b/x-pack/elastic-agent/elastic-agent.docker.yml index 81b48af034dd..a1ef12ae4059 100644 --- a/x-pack/elastic-agent/elastic-agent.docker.yml +++ b/x-pack/elastic-agent/elastic-agent.docker.yml @@ -63,7 +63,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/elastic-agent.reference.yml b/x-pack/elastic-agent/elastic-agent.reference.yml index e0c4077f282d..d41b7c54ed8b 100644 --- a/x-pack/elastic-agent/elastic-agent.reference.yml +++ b/x-pack/elastic-agent/elastic-agent.reference.yml @@ -69,7 +69,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/elastic-agent.yml b/x-pack/elastic-agent/elastic-agent.yml index 70926508570e..2ea81fda476d 100644 --- a/x-pack/elastic-agent/elastic-agent.yml +++ b/x-pack/elastic-agent/elastic-agent.yml @@ -100,7 +100,7 @@ inputs: # # path to the directory containing downloaded packages # target_directory: "${path.data}/downloads" # # timeout for downloading package -# timeout: 30s +# timeout: 120s # # file path to a public key used for verifying downloaded artifacts # # if not file is present agent will try to load public key from elastic.co website. # pgpfile: "${path.data}/elastic.pgp" diff --git a/x-pack/elastic-agent/pkg/agent/application/configuration_embed.go b/x-pack/elastic-agent/pkg/agent/application/configuration_embed.go index 85c6137d7d32..eb1679a536e2 100644 --- a/x-pack/elastic-agent/pkg/agent/application/configuration_embed.go +++ b/x-pack/elastic-agent/pkg/agent/application/configuration_embed.go @@ -15,7 +15,7 @@ var DefaultAgentFleetConfig []byte func init() { // Packed File // _meta/elastic-agent.fleet.yml - unpacked := packer.MustUnpack("eJycVUuTo7oV3udnzD43PJqpIVVZWHQjxLTpGF9LSJsUkjwytoSp2GCLVP57SuC2u29Npabugo2QzuN7nPOfL/8y23P9t62uT+dG/LVW2/b82w+93Z5/s0Z/+fsXZBfxP3/3fu1bg4yRSAuTntDzL755fN+RBQkjqScs6IQFex5EpibSFwYfUIZ7BrFFL+zECPZeExDxcKNokPYIlpoZ3bM1OPOw8FBWaJmVHTdyTJqlYm0+8DXwarhR60A3lEQ7lOL8tQHsHiPDFwZTj0339Igg6zjcKAm/KRrEPTO6lVWuUVYe2RqMrCq9mkStsO5+6rk81P2H0SATMMoKXHiYe4ysFG0PqjRXzapVn5i5/jd1VAjinpL8xMjqK8pKK8nm+xSHSM3bVc9gHHJzHShZfXXnKFnsUVYMssr3bA0G1sw90Sr3asJ2NCzH1wRYVqV+XeVaWKA5TEcJ9R7Ba1cHGyVCl6fwpl5g2rME9JT4HTdC8YAqCXcawbzjJrU1weM9L9z0zC4GGeipLmH9p7dn2m+Nvsx3wMhDbGmA8eZw+IqS/Ciz8iLG4/AapFZCbSgpPGGje02vphheg3KQQXTiQXoQNm5m/r81j37BTkI18TDXVnbC4L2Esd2uJ414lOjecYHgI5bDXcB0Xwdpy6rld2QXCmXlThipZRofHD40LAfRulrRYRtOeXqnAVp5wwP7ckTquEfJQiHHNfE1D7GHIBtEAw48lD2H8Y5B3TMLLpQU/3b83TC5339rFuMyu9WRLBUz+sTW4EKr8oiyckDwRYkMN3zi6qy3a+CLAB9ueQJW5R1r9cTTh9o0S8BOtGXHTLqXH+LXhCpuYu9dx3W1VCLLtQhwLxOQ3nXxkraMRB7KZMfhRcksj+Z6Jt39sSYjTHxGEJ9oVXg1WfY0+KZkgBsRaI+tn244g1bMeX+OLbnuRFh21EYXFi4eXEPdi7DccXj9IWDq1Qk4sKrYC6MbVi1v/F8HGqReTeIewdh8eOOwuOMvbHwRJm6FSc/CPql1tZowoOQ6cjtj+8g7YWwZSQ+TjjJgeSAtJZ4SIdA00KYmxU5CPfB22d+47XhbeJRcT9Xc3097rUk0SpieeII+eVtk+UADPIrxeOeMTzr2dzyZZweCkc9JrkUDDA+Rq2Ung2jqU5h4z6pivGsb+h3X8fTurVlcl8+Ly3Jx1+2ZVruOV/iMMjCIdqV4i8/UYHvrfRQwDfk0Z13vhRZhocVlfs9J+lSF07uv6Hl5cbEf/iw7TvAgq5ViJrYIFg5Hb/ZjpKX9VGuPMnlk5End+59nfc/DlRIh3k9nAfM5vEbvsd5nqIS7Tnzw4IeZ6LkZiGB8YVU+89Tcd8hYk1JPOwS+KGbSjmfYstXc2w3THxLqMyOxL5+PajmCMXGeh7M3XttcO1+8PeaA5iZtOHQxSy0hto67SaPBTjudTnqqSjejXB0XHhZj7Wb9+kmVEBta4ZNMpn/GafLunZ/shHd9CIM9YbQWfrzn4eTjUUC8rwnrXO4Hp7FB2VRzN2H+4vZj6vNs9sDSPt1jblzM9uB2nM+dLgKqlmtwZiTtHTcyAWFNricE3e67xSTuXqRn7jeKEuaxCs1nkO1qcvWF2bz7ZMLB7ZIqKAZJomkWPrxXun0Qoay4MFJ0zPVnwcHNCIcdb8BZWNCwqgwZwf3/7cvxNuec3/9+/HDmcvm7bRq/x/6MHUmfauL7fP1ncy8un/wSzH29NQufr+66SbcZGLjBvYTa+fzAKqdNt3/xOHmjKo8OSzbN2MMUW2a5ptVt1lugP8d4cIkD7dXJtGfu7ymJDuj5g3ZGh8nihJ7p5TVZXJf7D/j8oSdm0pMINu+6fBIw7p0fapKe3pqbblfHf3z571/+FwAA//9N0n8p") + unpacked := packer.MustUnpack("eJycVUuTo7oV3udnzD43PIauITsLN0KModO4jZA2KSS5BbaEqWsDhlT+e0rgtrtv3aSmsmAjpPP4Huf869s/9f5S/m2vyvOl5n8t5b65/Pau9vvLb6NW3/7+DY0r/x9v1q99WxBR7CmuwzNa/+Kbx/cTjSCgOLT4CFo+ggNzPF1iYXOdH1GUdxTmI3qmZ4pzaxMAj7k7SZywQzBTVKuObsGFuamFolSJKGuZFlNQJ5I2cc+2wCrhTm4dVRPsVSjM400N6D1GlA8Uhhad76kJQdoyuJMC/pDE8TuqVSOKWKEoO9EtmGiRWSX2Gj6a+6Fl8hDzH3q9CMAkCjAwN7YofpWkOcpMXxUtXrtAL/W/yJNEMO8Ijs8Uvz6hKBsF3v2c42ChWPPaUei7TF97gl+fzDkKVgcUpb0o4gPdgp7WS0+kiK0S04q42bQJwEiL0C6LWPERKAbDSUB1QPDals5OctfkSa25Fxh2NAAdwXbLNJfMIVLASiEYt0yHY4nz6Z4X7jo6rnrhqLkuPtrfX9ak22s1LHfAxNx8JE6e747HJxTEJxFlA59O/cYJRwGVJji1+Ojda9rotN84WS8c78yc8MhHv174/1E/+gWVgHLmYakta7nODwL64347a8QiWHWGCwQfsQzuHIaH0gkbWiQ/0biSKMoqroUSoX80+BA363ljakXHvTvn6YwGSGH1D+yzCcnTAQUriQzX2FbMzS0Eac9rcGSu6Bj0KwpVR0cwEJz+bvi7YXK//1KvrskBfMJz0ReHoVUGwGIjqFAEbKKvLRnB77Q4SlGkigZAMxdJofOxxNT7sz4/8/+Ir/RNi7rEV4WMpiOjjdRoS2b4WnE3M7kAdfJOBMAt8fVsdLjfzvXM8f9Y081LXzhEkVCkSVsBd92t74G6S96XelXH0WUgRXba6KwSMPQ3Tn4mRWqVOOk4FMMnfFvWpBbB13Ox8CEpzCfixi3R+XTz3pk5aSWg6lk9e+D+5g+c9zyKe+rGFSuSDj0ra8YAhmfu/FiwXd3zzhhznd955NpvuA4vKEoHitOWanUgRdYyx5s2t3pL7E0ChmcW+nN/f96r6ribVQwOdWDewbCh2LM2DRiZkyruJg9vQ+NDdSF4kBz6owhAJ7Bd0wJJqv3R1EIK0c19RnFPnHzizodHwaXE3vv8bn2SydtqSNarRfdBIhkOv5fYttl2mUsIejbDseL1rXeDt+MZvZneD7RIp7tvoF3tQ39+91KvpmS9GpLVf/XEweAoFhw7WvAvtW5q4JYw74wWb/3Lskgk076Z2zaZz1It8PVs/L3Eyo8Ixp7h39wVUF0o9m3xqMHwYPDqOczHhafvc1wzu7mjjrSITW8VgrQq8dXmenebCQumhZu1DOe9KF6f0DoZ+HAy+6havOGNtMjG/dvpjifFXkXMTA/AkRaZ4tpwZzQqTrTIToYzrnOLN8e5Dg79iTuqZnDXoWezr0KbRa/zP6qNJu/eUUyHNYP58aUGFm9y9ZiFsRJR3NIifSeObxsfcxco4ihtZvUnTo0v5prN+aYGzxTTSuDr4oF10t1jhnNMD8G0F9izEPQ1Wj9LhvOKNYabVykcdWYBqOn2HvOIoN/NuxLbZo9oYXbzcqYJVmezXz58MuOgleK2f2Bu3s36HO7cHSm+VvstmDjMDyWmLTWYQDMjjrLE3yUzPOrcEk6u2P/uy/A2x729f/p8hkZwIUX1/hH7K3Z2tYfqIrD1f+dOoi9+Wfp6O8kUW3fdZEU1MMdTrMla43MKc4sWsfGu2dfGG1Y5Y5mZGestczsbzV5cZn0i6dcYn7gUrZmZyQSmx3uz41fTQzvJjMkmWDlJMMjkDX3G52tPkFYsSj92mdpHoGc67wRUFVufPnT789u///KfAAAA//+w0n9F") raw, ok := unpacked["_meta/elastic-agent.fleet.yml"] if !ok { // ensure we have something loaded. From f9e4ddeab19f3556d89f199f97ed1e74d62c46ae Mon Sep 17 00:00:00 2001 From: Henadzi Siardziukou <92367828+nxei@users.noreply.github.com> Date: Fri, 26 Nov 2021 12:39:38 +0300 Subject: [PATCH 030/172] Workflow for macos (#29156) * Added workflow file for builds with macos * changed runner parameter to optional * renamed workflow and fixed pathes * added GO111MODULE=off --- .github/workflows/macos-build.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml index eab20e98d7eb..1b45fecd2711 100644 --- a/.github/workflows/macos-build.yml +++ b/.github/workflows/macos-build.yml @@ -1,12 +1,10 @@ -name: build - +name: macos-build env: - GOPATH: /home/runner/work/gotest/gotest + GOPATH: /home/runner/work/beats/beats GO111MODULE: off - REPO_PATH: src/gotest - MACOS_GOPATH: /Users/runner/work/gotest/gotest + REPO_PATH: src/beats + MACOS_GOPATH: /Users/runner/work/beats/beats GITHUB_TOKEN: ${{ github.token }} - on: workflow_dispatch: inputs: From 37c6229e3e90baaeec91ba4276d821b7a66c107c Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Mon, 29 Nov 2021 11:31:12 +0100 Subject: [PATCH 031/172] Fix `decode_json_fields` processor to always add error key (#29107) When the `decode_json_fields` processor encountered an error while decoding the JSON it was not always respecting the `add_error_key` configuration. This commit fixes it. --- CHANGELOG.next.asciidoc | 1 + .../processors/actions/decode_json_fields.go | 5 +++++ .../actions/decode_json_fields_test.go | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index a4f34cb48ba6..51e6623bb603 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -145,6 +145,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] - Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] +- Fix `decode_json_processor` to always respect `add_error_key` {pull}29107[29107] *Auditbeat* diff --git a/libbeat/processors/actions/decode_json_fields.go b/libbeat/processors/actions/decode_json_fields.go index 611b5b8d8e3c..be852a471338 100644 --- a/libbeat/processors/actions/decode_json_fields.go +++ b/libbeat/processors/actions/decode_json_fields.go @@ -122,6 +122,11 @@ func (f *decodeJSONFields) Run(event *beat.Event) (*beat.Event, error) { if err != nil { f.logger.Debugf("Error trying to unmarshal %s", text) errs = append(errs, err.Error()) + event.SetErrorWithOption(common.MapStr{ + "message": "parsing input as JSON: " + err.Error(), + "data": text, + "field": field, + }, f.addErrorKey) continue } diff --git a/libbeat/processors/actions/decode_json_fields_test.go b/libbeat/processors/actions/decode_json_fields_test.go index 73d4f3a5fccf..f58efd29b465 100644 --- a/libbeat/processors/actions/decode_json_fields_test.go +++ b/libbeat/processors/actions/decode_json_fields_test.go @@ -491,6 +491,27 @@ func TestOverwriteMetadata(t *testing.T) { assert.Equal(t, expected, actual) } +func TestAddErrorToEventOnUnmarshalError(t *testing.T) { + testConfig := common.MustNewConfigFrom(map[string]interface{}{ + "fields": "message", + "add_error_key": true, + }) + + input := common.MapStr{ + "message": "Broken JSON [[", + } + + actual := getActualValue(t, testConfig, input) + + errObj, ok := actual["error"].(common.MapStr) + require.True(t, ok, "'error' field not present or of invalid type") + require.NotNil(t, actual["error"]) + + assert.Equal(t, "message", errObj["field"]) + assert.NotNil(t, errObj["data"]) + assert.NotNil(t, errObj["message"]) +} + func getActualValue(t *testing.T, config *common.Config, input common.MapStr) common.MapStr { log := logp.NewLogger("decode_json_fields_test") From 7ad680025fbe8730ed3aa89f1082684e90222bc1 Mon Sep 17 00:00:00 2001 From: Henadzi Siardziukou <92367828+nxei@users.noreply.github.com> Date: Mon, 29 Nov 2021 15:56:30 +0300 Subject: [PATCH 032/172] Workflow for macos (#29174) * removed GO111MODULE=off environment variable --- .github/workflows/macos-build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml index 1b45fecd2711..6f392dff9e4d 100644 --- a/.github/workflows/macos-build.yml +++ b/.github/workflows/macos-build.yml @@ -1,7 +1,6 @@ name: macos-build env: GOPATH: /home/runner/work/beats/beats - GO111MODULE: off REPO_PATH: src/beats MACOS_GOPATH: /Users/runner/work/beats/beats GITHUB_TOKEN: ${{ github.token }} From 24d6bbd19e8b154806c4e7fedd17d8472ed3810d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Mon, 29 Nov 2021 16:51:13 +0100 Subject: [PATCH 033/172] Use the generic helper for opening file to read in filestream (#29180) Closes #29113 --- CHANGELOG.next.asciidoc | 1 + filebeat/input/filestream/input.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 51e6623bb603..80fead3fb4cc 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -192,6 +192,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Revert usageDetails api version to 2019-01-01. {pull}28995[28995] - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] - Fix `threatintel.misp` filters configuration. {issue}27970[27970] +- Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] *Heartbeat* diff --git a/filebeat/input/filestream/input.go b/filebeat/input/filestream/input.go index c1ba829d65fb..654938869af1 100644 --- a/filebeat/input/filestream/input.go +++ b/filebeat/input/filestream/input.go @@ -29,6 +29,7 @@ import ( input "github.com/elastic/beats/v7/filebeat/input/v2" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cleanup" + "github.com/elastic/beats/v7/libbeat/common/file" "github.com/elastic/beats/v7/libbeat/common/match" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" @@ -244,7 +245,7 @@ func (inp *filestream) openFile(log *logp.Logger, path string, offset int64) (*o } ok := false - f, err := os.OpenFile(path, os.O_RDONLY, os.FileMode(0)) + f, err := file.ReadOpen(path) if err != nil { return nil, fmt.Errorf("failed opening %s: %s", path, err) } From 74bc6cdd40fb377e08a1f8be48b2db339727da65 Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:37:24 +1030 Subject: [PATCH 034/172] packetbeat: preparation for npcap addition (#29017) * packetbeat: run gofmt -s * packetbeat/protos/tls: prep for gofumpt * packetbeat: run gofumpt * packetbeat: clean up lint Address the following output from staticcheck. Checked lines are fixed here. - [ ] beater/processor.go:143:15: error strings should not be capitalized (ST1005) - [ ] decoder/decoder.go:142:15: error strings should not be capitalized (ST1005) - [ ] flows/flowid_test.go:57:6: func addUDP is unused (U1000) - [x] flows/flows_test.go:58:2: this value of err is never used (SA4006) - [x] flows/flows_test.go:59:2: this value of err is never used (SA4006) - [x] flows/flows_test.go:60:2: this value of err is never used (SA4006) - [x] flows/flows_test.go:61:2: this value of err is never used (SA4006) - [x] flows/flows_test.go:62:2: this value of err is never used (SA4006) - [x] flows/worker.go:110:17: should use time.Until instead of t.Sub(time.Now()) (S1024) - [ ] pb/event.go:435:13: error strings should not be capitalized (ST1005) - [x] procs/procs.go:216:55: should use time.Since instead of time.Now().Sub (S1012) - [x] protos/amqp/amqp.go:90:5: should omit comparison to bool constant, can be simplified to !amqp.hideConnectionInformation (S1002) - [ ] protos/amqp/amqp_fields.go:48:4: this value of fields is never used (SA4006) **BUG** - [ ] protos/amqp/amqp_fields.go:73:4: this value of fields is never used (SA4006) **BUG** - [x] protos/amqp/amqp_parser.go:77:22: func (*amqpStream).prepareForNewMessage is unused (U1000) - [x] protos/amqp/amqp_parser.go:162:5: should omit comparison to bool constant, can be simplified to amqp.parseHeaders (S1002) - [x] protos/amqp/amqp_parser.go:345:12: should omit comparison to bool constant, can be simplified to m.isRequest (S1002) - [x] protos/amqp/amqp_parser.go:347:12: should omit comparison to bool constant, can be simplified to !m.isRequest (S1002) - [x] protos/amqp/amqp_parser.go:353:9: should omit comparison to bool constant, can be simplified to amqp.hideConnectionInformation (S1002) - [x] protos/amqp/amqp_test.go:672:2: this value of private is never used (SA4006) - [x] protos/amqp/amqp_test.go:739:2: this value of private is never used (SA4006) - [x] protos/cassandra/cassandra.go:203:25: func (*connection).dropStreams is unused (U1000) - [ ] protos/cassandra/internal/gocql/array_decoder.go:29:6: func readInt is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:279:6: func getApacheCassandraType is unused (U1000) - [x] protos/cassandra/internal/gocql/marshal.go:352:7: receiver name should be a reflection of its identity; don't use generic names such as "this" or "self" (ST1006) - [ ] protos/cassandra/internal/gocql/marshal.go:569:2: const flagValues is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:570:2: const flagSkipMetaData is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:571:2: const flagPageSize is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:572:2: const flagWithPagingState is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:573:2: const flagWithSerialConsistency is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:574:2: const flagDefaultTimestamp is unused (U1000) - [ ] protos/cassandra/internal/gocql/marshal.go:575:2: const flagWithNameValues is unused (U1000) - [x] protos/cassandra/parser.go:72:2: field transactionTimeout is unused (U1000) - [ ] protos/cassandra/parser.go:79:22: error strings should not be capitalized (ST1005) - [x] protos/cassandra/pub.go:36:2: field ignoredOps is unused (U1000) - [ ] protos/dhcpv4/option_ip_addresses.go:42:15: error strings should not be capitalized (ST1005) - [x] protos/dns/dns.go:68:2: const query is unused (U1000) - [x] protos/dns/dns.go:69:2: const response is unused (U1000) - [x] protos/dns/dns.go:206:2: field responseTime is unused (U1000) - [x] protos/http/http.go:929:24: func (*messageList).last is unused (U1000) - [ ] protos/http/http_parser.go:264:18: error strings should not be capitalized (ST1005) - [ ] protos/http/http_parser.go:271:16: error strings should not be capitalized (ST1005) - [x] protos/http/http_test.go:59:22: func (*eventStore).empty is unused (U1000) - [x] protos/http/http_test.go:541:2: this value of msg is never used (SA4006) - [x] protos/http/http_test.go:647:2: this value of complete is never used (SA4006) - [x] protos/http/http_test.go:647:2: this value of ok is never used (SA4006) - [x] protos/http/http_test.go:653:2: this value of complete is never used (SA4006) - [x] protos/http/http_test.go:653:2: this value of ok is never used (SA4006) - [x] protos/http/http_test.go:658:2: this value of complete is never used (SA4006) - [x] protos/http/http_test.go:658:2: this value of ok is never used (SA4006) - [x] protos/http/http_test.go:673:2: this value of complete is never used (SA4006) - [x] protos/http/http_test.go:673:2: this value of ok is never used (SA4006) - [x] protos/icmp/icmp.go:260:25: func (*icmpPlugin).getTransaction is unused (U1000) - [ ] protos/icmp/message.go:93:2: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [ ] protos/icmp/message.go:104:2: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [ ] protos/icmp/message.go:115:2: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [ ] protos/icmp/message.go:136:2: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [ ] protos/icmp/message.go:147:2: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [x] protos/memcache/binary.go:31:6: type memcacheMagic is unused (U1000) - [x] protos/memcache/binary.go:60:2: var extraValue is unused (U1000) - [ ] protos/memcache/errors.go:26:5: var errNotImplemented is unused (U1000) - [ ] protos/memcache/errors.go:33:2: var errExpectedNumber is unused (U1000) - [ ] protos/memcache/errors.go:35:2: var errExpectedCRLF is unused (U1000) - [ ] protos/memcache/errors.go:54:2: var errResponseUnknownTransaction is unused (U1000) - [x] protos/memcache/parse.go:29:2: const codeSpace is unused (U1000) - [x] protos/memcache/parse.go:29:2: only the first constant in this group has an explicit type (SA9004) - [x] protos/memcache/parse.go:30:2: const codeTab is unused (U1000) - [x] protos/memcache/plugin_tcp.go:63:7: const defaultTCPTransDuration is unused (U1000) - [ ] protos/memcache/plugin_tcp.go:377:4: logp.WTF is deprecated: Use logp.NewLogger and its Panic or DPanic methods. (SA1019) - [x] protos/memcache/text.go:410:6: func makeValue2Arg is unused (U1000) - [x] protos/mongodb/mongodb_parser.go:118:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:119:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:120:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:165:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:166:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:167:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:169:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:181:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:232:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:233:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:236:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:237:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:277:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:278:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:279:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:290:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:291:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:292:2: this value of err is never used (SA4006) - [ ] protos/mongodb/mongodb_parser.go:401:13: error strings should not be capitalized (ST1005) - [x] protos/mongodb/mongodb_parser.go:436:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_parser.go:461:2: this value of err is never used (SA4006) - [ ] protos/mongodb/mongodb_parser.go:470:24: error strings should not be capitalized (ST1005) - [x] protos/mongodb/mongodb_test.go:163:2: this value of err is never used (SA4006) - [x] protos/mongodb/mongodb_test.go:174:2: this value of err is never used (SA4006) - [x] protos/mysql/mysql.go:65:2: field fields is unused (U1000) - [x] protos/mysql/mysql.go:66:2: field rows is unused (U1000) - [x] protos/mysql/mysql.go:86:2: field params is unused (U1000) - [x] protos/mysql/mysql.go:944:4: empty branch (SA9003) - [x] protos/mysql/mysql_test.go:52:22: func (*eventStore).empty is unused (U1000) - [x] protos/mysql/mysql_test.go:679:3: this value of private is never used (SA4006) - [x] protos/nfs/xdr.go:43:15: func (*xdr).getInt is unused (U1000) - [x] protos/nfs/xdr.go:55:15: func (*xdr).getHyper is unused (U1000) - [x] protos/pgsql/pgsql.go:432:5: should omit nil check; len() for nil slices is defined as zero (S1009) - [x] protos/pgsql/pgsql_test.go:49:22: func (*eventStore).empty is unused (U1000) - [x] protos/protos_test.go:74:2: redundant return statement (S1023) - [x] protos/protos_test.go:103:2: redundant return statement (S1023) - [ ] protos/sip/parser.go:254:18: error strings should not be capitalized (ST1005) - [ ] protos/sip/parser.go:261:16: error strings should not be capitalized (ST1005) - [x] protos/tcp/tcp.go:291:6: func tcpSeqBefore is unused (U1000) - [ ] protos/tcp/tcp.go:309:17: error strings should not be capitalized (ST1005) - [x] protos/tcp/tcp_test.go:200:76: redundant return statement (S1023) - [ ] protos/thrift/thrift.go:272:10: error strings should not be capitalized (ST1005) - [ ] protos/thrift/thrift.go:279:10: error strings should not be capitalized (ST1005) - [x] protos/thrift/thrift_idl.go:52:28: should use make([]*string, max + 1) instead (S1019) - [ ] protos/thrift/thrift_idl.go:94:19: error strings should not be capitalized (ST1005) - [x] protos/thrift/thrift_test.go:125:2: this value of m is never used (SA4006) - [x] protos/thrift/thrift_test.go:133:2: this value of m is never used (SA4006) - [x] protos/thrift/thrift_test.go:153:2: this value of m is never used (SA4006) - [ ] protos/tls/alerts.go:72:15: error strings should not be capitalized (ST1005) - [ ] protos/tls/parse.go:21:2: package crypto/dsa is deprecated: DSA is a legacy algorithm, and modern alternatives such as Ed25519 (implemented by package crypto/ed25519) should be used instead. Keys with 1024-bit moduli (L1024N160 parameters) are cryptographically weak, while bigger keys are not widely supported. Note that FIPS 186-5 no longer approves DSA for signature generation. (SA1019) - [x] protos/tls/parse.go:56:2: only the first constant in this group has an explicit type (SA9004) - [x] protos/tls/parse.go:65:2: only the first constant in this group has an explicit type (SA9004) - [x] protos/tls/parse_test.go:128:6: func mapInt is unused (U1000) - [x] protos/tls/parse_test.go:175:2: this value of err is never used (SA4006) - [x] protos/tls/tls.go:175:5: don't use Yoda conditions (ST1017) - [x] protos/tls/tls_test.go:327:2: this value of err is never used (SA4006) - [x] protos/tls/tls_test.go:390:2: this value of err is never used (SA4006) - [x] protos/tls/tls_test.go:402:2: this value of err is never used (SA4006) - [x] protos/tls/tls_test.go:434:2: this value of err is never used (SA4006) - [x] protos/tls/tls_test.go:441:2: this value of err is never used (SA4006) - [ ] protos/udp/udp.go:93:17: error strings should not be capitalized (ST1005) - [x] protos/udp/udp_test.go:81:2: redundant return statement (S1023) - [ ] scripts/mage/config.go:28:2: const configTemplateGlob is unused (U1000) - [ ] scripts/mage/package.go:69:4: the surrounding loop is unconditionally terminated (SA4004) - [ ] sniffer/afpacket.go:40:19: error strings should not be capitalized (ST1005) - [ ] sniffer/afpacket_nonlinux.go:36:14: error strings should not be capitalized (ST1005) - [ ] sniffer/afpacket_nonlinux.go:40:19: error strings should not be capitalized (ST1005) - [ ] sniffer/afpacket_nonlinux.go:44:9: error strings should not be capitalized (ST1005) - [x] sniffer/device.go:65:13: the argument is already a string, there's no need to use fmt.Sprintf (S1025) - [ ] sniffer/device.go:84:15: error strings should not be capitalized (ST1005) - [ ] sniffer/device.go:89:15: error strings should not be capitalized (ST1005) - [ ] sniffer/device.go:100:14: error strings should not be capitalized (ST1005) - [ ] sniffer/file.go:82:20: error strings should not be capitalized (ST1005) - [x] sniffer/sniffer.go:42:2: field dumper is unused (U1000) - [ ] sniffer/sniffer.go:150:10: error strings should not be capitalized (ST1005) - [ ] sniffer/sniffer.go:195:11: error strings should not be capitalized (ST1005) - [ ] sniffer/sniffer.go:226:15: error strings should not be capitalized (ST1005) - [ ] sniffer/sniffer.go:250:10: error strings should not be capitalized (ST1005) - [x] sniffer/sniffer_test.go:55:2: this value of blockSize is never used (SA4006) - [x] sniffer/sniffer_test.go:55:2: this value of frameSize is never used (SA4006) - [x] sniffer/sniffer_test.go:55:2: this value of numBlocks is never used (SA4006) - [x] sniffer/sniffer_test.go:61:2: this value of err is never used (SA4006) * packetbeat/protos/amqp: clean up conditions * packetbeat/protos/cassandra: simplify ignored operations check * packetbeat/protos/icmp: simplify selector expression * packetbeat/sniffer: improve device name formatting logic * packetbeat/protos/amqp: clarify expectation for common.MapStr destination The previous code would drop data rather than fill the fields common.MapStr. This change clarifies that it is the caller's responsibility to provide a valid destination. * packetbeat: apply condition simplification staticcheck quickfix suggestions - [ ] flows/table.go:88:21: could remove embedded field "rawFlowID" from selector (QF1008) - [x] pb/event.go:240:2: could use tagged switch on f.Network.Transport (QF1002) - [x] protos/cassandra/config.go:48:5: could apply De Morgan's law (QF1001) - [x] protos/cassandra/internal/gocql/array_decoder.go:166:5: could apply De Morgan's law (QF1001) - [x] protos/cassandra/internal/gocql/stream_decoder.go:152:5: could apply De Morgan's law (QF1001) - [ ] protos/dhcpv4/dhcpv4.go:80:11: could remove embedded field "dhcpv4Config" from selector (QF1008) - [ ] protos/memcache/memcache.go:183:5: could remove embedded field "tcpConfig" from selector (QF1008) - [x] protos/memcache/memcache.go:257:3: could use tagged switch on prev.command.code (QF1003) - [ ] protos/memcache/memcache.go:377:4: could remove embedded field "Transaction" from selector (QF1008) - [ ] protos/memcache/plugin_tcp.go:115:4: could remove embedded field "Stream" from selector (QF1008) - [ ] protos/memcache/plugin_tcp.go:443:9: could remove embedded field "Stream" from selector (QF1008) - [x] protos/mongodb/mongodb.go:345:4: could use tagged switch on t.method (QF1003) - [x] protos/mysql/mysql.go:688:4: could use tagged switch on msg.typ (QF1003) - [x] protos/mysql/mysql.go:698:3: could use tagged switch on msg.typ (QF1003) - [ ] protos/redis/redis.go:120:4: could remove embedded field "Stream" from selector (QF1008) - [ ] protos/redis/redis.go:237:4: could remove embedded field "Stream" from selector (QF1008) - [ ] protos/redis/redis_test.go:215:5: could remove embedded field "Stream" from selector (QF1008) - [ ] protos/redis/redis_test.go:255:6: could remove embedded field "Stream" from selector (QF1008) - [x] protos/sip/parser.go:272:5: could apply De Morgan's law (QF1001) - [ ] protos/tls/parse.go:552:18: could remove embedded field "Parameters" from selector (QF1008) - [ ] protos/tls/tls.go:226:4: could remove embedded field "Stream" from selector (QF1008) Embedded field selector simplification are not applied because in many cases these probably should not be embedded fields or they clarify the intention. --- CHANGELOG.next.asciidoc | 2 + packetbeat/cmd/root.go | 2 +- packetbeat/config/agent.go | 4 +- packetbeat/decoder/decoder.go | 3 +- packetbeat/flows/flows_test.go | 6 +- packetbeat/flows/worker.go | 2 +- packetbeat/flows/worker_test.go | 8 +- packetbeat/pb/event.go | 10 +- .../add_kubernetes_metadata/indexers.go | 4 +- packetbeat/procs/procs.go | 2 +- packetbeat/procs/procs_linux_test.go | 4 +- packetbeat/procs/procs_windows.go | 16 ++- packetbeat/procs/procs_windows_test.go | 38 +++-- packetbeat/procs/zsyscall_windows.go | 4 +- packetbeat/protos/amqp/amqp.go | 54 +++---- packetbeat/protos/amqp/amqp_fields.go | 38 +++-- packetbeat/protos/amqp/amqp_methods.go | 30 ++-- packetbeat/protos/amqp/amqp_parser.go | 44 +++--- packetbeat/protos/amqp/amqp_structs.go | 16 +-- packetbeat/protos/amqp/amqp_test.go | 46 +++--- packetbeat/protos/amqp/config.go | 20 ++- packetbeat/protos/cassandra/cassandra.go | 9 +- packetbeat/protos/cassandra/config.go | 22 ++- .../cassandra/internal/gocql/array_decoder.go | 6 +- .../cassandra/internal/gocql/compressor.go | 4 +- .../cassandra/internal/gocql/decoder.go | 15 -- .../protos/cassandra/internal/gocql/frame.go | 33 ++--- .../cassandra/internal/gocql/marshal.go | 6 +- .../internal/gocql/stream_decoder.go | 2 +- packetbeat/protos/cassandra/parser.go | 20 +-- packetbeat/protos/cassandra/pub.go | 5 +- packetbeat/protos/cassandra/trans.go | 3 +- packetbeat/protos/dhcpv4/config.go | 12 +- packetbeat/protos/dns/config.go | 12 +- packetbeat/protos/dns/dns.go | 23 +-- packetbeat/protos/dns/dns_tcp.go | 6 +- packetbeat/protos/dns/dns_test.go | 6 +- packetbeat/protos/dns/dns_udp_test.go | 6 +- packetbeat/protos/http/config.go | 16 +-- packetbeat/protos/http/http.go | 24 ++-- packetbeat/protos/http/http_parser.go | 6 +- packetbeat/protos/http/http_test.go | 31 ++-- packetbeat/protos/icmp/config.go | 8 +- packetbeat/protos/icmp/icmp.go | 14 +- packetbeat/protos/icmp/tuple_test.go | 3 +- packetbeat/protos/memcache/binary.go | 11 +- packetbeat/protos/memcache/config.go | 14 +- packetbeat/protos/memcache/errors.go | 4 +- packetbeat/protos/memcache/parse.go | 5 - packetbeat/protos/memcache/parse_test.go | 6 +- packetbeat/protos/memcache/plugin_tcp.go | 2 - packetbeat/protos/memcache/text.go | 29 ++-- packetbeat/protos/mongodb/config.go | 16 +-- packetbeat/protos/mongodb/mongodb.go | 12 +- packetbeat/protos/mongodb/mongodb_parser.go | 105 ++++++++++++-- packetbeat/protos/mongodb/mongodb_test.go | 2 + packetbeat/protos/mysql/config.go | 18 ++- packetbeat/protos/mysql/mysql.go | 52 ++++--- packetbeat/protos/mysql/mysql_test.go | 54 +++---- packetbeat/protos/nfs/config.go | 12 +- packetbeat/protos/nfs/request_handler.go | 4 +- packetbeat/protos/nfs/rpc.go | 10 +- packetbeat/protos/nfs/xdr.go | 12 -- packetbeat/protos/pgsql/config.go | 16 +-- packetbeat/protos/pgsql/parse.go | 24 ++-- packetbeat/protos/pgsql/pgsql.go | 26 ++-- packetbeat/protos/pgsql/pgsql_test.go | 10 +- packetbeat/protos/protos.go | 1 - packetbeat/protos/protos_test.go | 8 +- packetbeat/protos/redis/config.go | 20 ++- packetbeat/protos/redis/redis.go | 10 +- packetbeat/protos/sip/config.go | 18 ++- packetbeat/protos/sip/parser.go | 3 +- packetbeat/protos/tcp/tcp.go | 13 +- packetbeat/protos/tcp/tcp_test.go | 27 ++-- packetbeat/protos/thrift/config.go | 24 ++-- packetbeat/protos/thrift/thrift.go | 25 ++-- packetbeat/protos/thrift/thrift_idl.go | 2 +- packetbeat/protos/thrift/thrift_test.go | 3 - packetbeat/protos/tls/alerts.go | 10 +- packetbeat/protos/tls/algos.go | 22 +-- packetbeat/protos/tls/config.go | 18 ++- packetbeat/protos/tls/extensions.go | 15 +- packetbeat/protos/tls/extensions_test.go | 2 - packetbeat/protos/tls/fingerprint.go | 6 +- packetbeat/protos/tls/ja3.go | 1 - packetbeat/protos/tls/parse.go | 13 +- packetbeat/protos/tls/parse_test.go | 8 +- packetbeat/protos/tls/tls.go | 7 +- packetbeat/protos/tls/tls_test.go | 5 + packetbeat/protos/udp/udp.go | 2 +- packetbeat/protos/udp/udp_test.go | 4 +- packetbeat/publish/publish.go | 1 - packetbeat/publish/publish_test.go | 4 +- packetbeat/scripts/mage/package.go | 4 +- packetbeat/sniffer/afpacket.go | 4 +- packetbeat/sniffer/afpacket_linux.go | 4 +- packetbeat/sniffer/afpacket_nonlinux.go | 7 +- packetbeat/sniffer/device.go | 42 +++--- packetbeat/sniffer/device_test.go | 136 ++++++++++++++++++ packetbeat/sniffer/sniffer.go | 2 - packetbeat/sniffer/sniffer_test.go | 5 +- 102 files changed, 835 insertions(+), 730 deletions(-) create mode 100644 packetbeat/sniffer/device_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 80fead3fb4cc..00383fb51cfc 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -243,6 +243,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Packetbeat* +- Prevent incorrect use of AMQP protocol parsing from causing silent failure. {pull}29017[29017] +- Fix error handling in MongoDB protocol parsing. {pull}29017[29017] *Winlogbeat* diff --git a/packetbeat/cmd/root.go b/packetbeat/cmd/root.go index 808de836fb3d..6032089c9fc2 100644 --- a/packetbeat/cmd/root.go +++ b/packetbeat/cmd/root.go @@ -50,7 +50,7 @@ var RootCmd *cmd.BeatsRootCmd // PacketbeatSettings contains the default settings for packetbeat func PacketbeatSettings() instance.Settings { - var runFlags = pflag.NewFlagSet(Name, pflag.ExitOnError) + runFlags := pflag.NewFlagSet(Name, pflag.ExitOnError) runFlags.AddGoFlag(flag.CommandLine.Lookup("I")) runFlags.AddGoFlag(flag.CommandLine.Lookup("t")) runFlags.AddGoFlag(flag.CommandLine.Lookup("O")) diff --git a/packetbeat/config/agent.go b/packetbeat/config/agent.go index 36e3c977b445..34df1721597d 100644 --- a/packetbeat/config/agent.go +++ b/packetbeat/config/agent.go @@ -66,7 +66,7 @@ func (i agentInput) addProcessorsAndIndex(cfg *common.Config) (*common.Config, e mergeConfig, err := common.NewConfigFrom(common.MapStr{ "index": datastreamConfig.Datastream.Type + "-" + datastreamConfig.Datastream.Dataset + "-" + namespace, "processors": append([]common.MapStr{ - common.MapStr{ + { "add_fields": common.MapStr{ "target": "data_stream", "fields": common.MapStr{ @@ -76,7 +76,7 @@ func (i agentInput) addProcessorsAndIndex(cfg *common.Config) (*common.Config, e }, }, }, - common.MapStr{ + { "add_fields": common.MapStr{ "target": "event", "fields": common.MapStr{ diff --git a/packetbeat/decoder/decoder.go b/packetbeat/decoder/decoder.go index 50e8f5954818..ae8eeb9d84bb 100644 --- a/packetbeat/decoder/decoder.go +++ b/packetbeat/decoder/decoder.go @@ -87,7 +87,8 @@ func New( d := Decoder{ flows: f, decoders: make(map[gopacket.LayerType]gopacket.DecodingLayer), - icmp4Proc: icmp4, icmp6Proc: icmp6, tcpProc: tcp, udpProc: udp} + icmp4Proc: icmp4, icmp6Proc: icmp6, tcpProc: tcp, udpProc: udp, + } d.stD1Q.init(&d.d1q[0], &d.d1q[1]) d.stIP4.init(&d.ip4[0], &d.ip4[1]) d.stIP6.init(&d.ip6[0], &d.ip6[1]) diff --git a/packetbeat/flows/flows_test.go b/packetbeat/flows/flows_test.go index 601613e61d12..9cee1c59e2d0 100644 --- a/packetbeat/flows/flows_test.go +++ b/packetbeat/flows/flows_test.go @@ -56,12 +56,16 @@ func TestFlowsCounting(t *testing.T) { assert.NoError(t, err) uint1, err := module.NewUint("uint1") + assert.NoError(t, err) uint2, err := module.NewUint("uint2") + assert.NoError(t, err) int1, err := module.NewInt("int1") + assert.NoError(t, err) int2, err := module.NewInt("int2") + assert.NoError(t, err) float1, err := module.NewFloat("float1") + assert.NoError(t, err) float2, err := module.NewFloat("float2") - assert.NoError(t, err) pub := &flowsChan{make(chan []beat.Event, 1)} diff --git a/packetbeat/flows/worker.go b/packetbeat/flows/worker.go index f0080cf68d28..b339a75fa4db 100644 --- a/packetbeat/flows/worker.go +++ b/packetbeat/flows/worker.go @@ -107,7 +107,7 @@ func makeWorker( if align > 0 { // round time to nearest 10 seconds for alignment aligned := time.Unix(((time.Now().Unix()+(align-1))/align)*align, 0) - waitStart := aligned.Sub(time.Now()) + waitStart := time.Until(aligned) debugf("worker wait start(%v): %v", aligned, waitStart) if cont := w.sleep(waitStart); !cont { return diff --git a/packetbeat/flows/worker_test.go b/packetbeat/flows/worker_test.go index 3bec75f2fe31..520d107f9ab4 100644 --- a/packetbeat/flows/worker_test.go +++ b/packetbeat/flows/worker_test.go @@ -33,10 +33,8 @@ import ( "github.com/elastic/beats/v7/packetbeat/procs" ) -var ( - // Use `go test -data` to update sample event files. - dataFlag = flag.Bool("data", false, "Write updated data.json files") -) +// Use `go test -data` to update sample event files. +var dataFlag = flag.Bool("data", false, "Write updated data.json files") func TestCreateEvent(t *testing.T) { logp.TestingSetup() @@ -124,7 +122,7 @@ func TestCreateEvent(t *testing.T) { t.Fatal(err) } - if err := ioutil.WriteFile("../_meta/sample_outputs/flow.json", output, 0644); err != nil { + if err := ioutil.WriteFile("../_meta/sample_outputs/flow.json", output, 0o644); err != nil { t.Fatal(err) } } diff --git a/packetbeat/pb/event.go b/packetbeat/pb/event.go index 683e22253beb..4ba7e4acf155 100644 --- a/packetbeat/pb/event.go +++ b/packetbeat/pb/event.go @@ -237,14 +237,14 @@ func (f *Fields) ComputeValues(localIPs []net.IP, internalNetworks []string) err } // network.community_id - switch { - case f.Network.Transport == "udp": + switch f.Network.Transport { + case "udp": flow.Protocol = 17 - case f.Network.Transport == "tcp": + case "tcp": flow.Protocol = 6 - case f.Network.Transport == "icmp": + case "icmp": flow.Protocol = 1 - case f.Network.Transport == "ipv6-icmp": + case "ipv6-icmp": flow.Protocol = 58 } flow.ICMP.Type = f.ICMPType diff --git a/packetbeat/processor/add_kubernetes_metadata/indexers.go b/packetbeat/processor/add_kubernetes_metadata/indexers.go index 474f111e97fe..3e547e3a8c18 100644 --- a/packetbeat/processor/add_kubernetes_metadata/indexers.go +++ b/packetbeat/processor/add_kubernetes_metadata/indexers.go @@ -26,14 +26,14 @@ func init() { // Register default indexers cfg := common.NewConfig() - //Add IP Port Indexer as a default indexer + // Add IP Port Indexer as a default indexer kubernetes.Indexing.AddDefaultIndexerConfig(kubernetes.IPPortIndexerName, *cfg) formatCfg, err := common.NewConfigFrom(map[string]interface{}{ "format": "%{[ip]}:%{[port]}", }) if err == nil { - //Add field matcher with field to lookup as metricset.host + // Add field matcher with field to lookup as metricset.host kubernetes.Indexing.AddDefaultMatcherConfig(kubernetes.FieldFormatMatcherName, *formatCfg) } } diff --git a/packetbeat/procs/procs.go b/packetbeat/procs/procs.go index bf3daab9ff24..a3d031ec72f0 100644 --- a/packetbeat/procs/procs.go +++ b/packetbeat/procs/procs.go @@ -213,7 +213,7 @@ func (proc *ProcessesWatcher) updateMap(transport applayer.Transport) { if logp.HasSelector("procsdetailed") { start := time.Now() defer func() { - logp.Debug("procsdetailed", "updateMap() took %v", time.Now().Sub(start)) + logp.Debug("procsdetailed", "updateMap() took %v", time.Since(start)) }() } diff --git a/packetbeat/procs/procs_linux_test.go b/packetbeat/procs/procs_linux_test.go index 39c8a9377411..e36bd50a208f 100644 --- a/packetbeat/procs/procs_linux_test.go +++ b/packetbeat/procs/procs_linux_test.go @@ -39,14 +39,14 @@ func createFakeDirectoryStructure(prefix string, files []testProcFile) error { var err error for _, file := range files { dir := filepath.Dir(file.path) - err = os.MkdirAll(filepath.Join(prefix, dir), 0755) + err = os.MkdirAll(filepath.Join(prefix, dir), 0o755) if err != nil { return err } if !file.isLink { err = ioutil.WriteFile(filepath.Join(prefix, file.path), - []byte(file.contents), 0644) + []byte(file.contents), 0o644) if err != nil { return err } diff --git a/packetbeat/procs/procs_windows.go b/packetbeat/procs/procs_windows.go index 50807691efa6..ee3eee1a28db 100644 --- a/packetbeat/procs/procs_windows.go +++ b/packetbeat/procs/procs_windows.go @@ -42,13 +42,17 @@ type extractor interface { Size() int } -type callbackFn func(net.IP, uint16, int) -type extractorFactory func(fn callbackFn) extractor +type ( + callbackFn func(net.IP, uint16, int) + extractorFactory func(fn callbackFn) extractor +) -type tcpRowOwnerPIDExtractor callbackFn -type tcp6RowOwnerPIDExtractor callbackFn -type udpRowOwnerPIDExtractor callbackFn -type udp6RowOwnerPIDExtractor callbackFn +type ( + tcpRowOwnerPIDExtractor callbackFn + tcp6RowOwnerPIDExtractor callbackFn + udpRowOwnerPIDExtractor callbackFn + udp6RowOwnerPIDExtractor callbackFn +) var tablesByTransport = map[applayer.Transport][]struct { family uint32 diff --git a/packetbeat/procs/procs_windows_test.go b/packetbeat/procs/procs_windows_test.go index 51cc8391d68f..4abfe359b71d 100644 --- a/packetbeat/procs/procs_windows_test.go +++ b/packetbeat/procs/procs_windows_test.go @@ -42,21 +42,33 @@ func TestParseTableRaw(t *testing.T) { expected []portProcMapping mustErr bool }{ - {"Empty table IPv4", IPv4, - "00000000", nil, false}, - {"Empty table IPv6", IPv6, - "00000000", nil, false}, - {"Short table (no length)", IPv4, - "000000", nil, true}, - {"Short table (partial entry)", IPv6, - "01000000AAAAAAAAAAAAAAAAAAAA", nil, true}, - {"One entry (IPv4)", IPv4, + { + "Empty table IPv4", IPv4, + "00000000", nil, false, + }, + { + "Empty table IPv6", IPv6, + "00000000", nil, false, + }, + { + "Short table (no length)", IPv4, + "000000", nil, true, + }, + { + "Short table (partial entry)", IPv6, + "01000000AAAAAAAAAAAAAAAAAAAA", nil, true, + }, + { + "One entry (IPv4)", IPv4, "01000000" + "77777777AAAAAAAA12340000BBBBBBBBFFFF0000CCCCCCCC", []portProcMapping{ {endpoint: endpoint{address: "170.170.170.170", port: 0x1234}, pid: int(pid)}, - }, false}, - {"Two entries (IPv6)", IPv6, + }, + false, + }, + { + "Two entries (IPv6)", IPv6, "02000000" + // First entry "11112222333344445555666677778888F0F0F0F0" + @@ -76,7 +88,9 @@ func TestParseTableRaw(t *testing.T) { []portProcMapping{ {endpoint: endpoint{address: "1111:2222:3333:4444:5555:6666:7777:8888", port: 0xABCD}, pid: 1}, {endpoint: endpoint{address: "aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa", port: 0}, pid: 0xffff}, - }, false}, + }, + false, + }, } { msg := fmt.Sprintf("Test case #%d: %s", idx+1, testCase.name) table, err := hex.DecodeString(testCase.raw) diff --git a/packetbeat/procs/zsyscall_windows.go b/packetbeat/procs/zsyscall_windows.go index b313698211e9..f938c08f792a 100644 --- a/packetbeat/procs/zsyscall_windows.go +++ b/packetbeat/procs/zsyscall_windows.go @@ -34,9 +34,7 @@ const ( errnoERROR_IO_PENDING = 997 ) -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) +var errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) // errnoErr returns common boxed Errno values, to prevent // allocations at runtime. diff --git a/packetbeat/protos/amqp/amqp.go b/packetbeat/protos/amqp/amqp.go index f0c1e26dd28a..2402b9150e36 100644 --- a/packetbeat/protos/amqp/amqp.go +++ b/packetbeat/protos/amqp/amqp.go @@ -50,7 +50,7 @@ type amqpPlugin struct { results protos.Reporter watcher procs.ProcessesWatcher - //map containing functions associated with different method numbers + // map containing functions associated with different method numbers methodMap map[codeClass]map[codeMethod]amqpMethod } @@ -87,7 +87,7 @@ func (amqp *amqpPlugin) init(results protos.Reporter, watcher procs.ProcessesWat amqp.initMethodMap() amqp.setFromConfig(config) - if amqp.hideConnectionInformation == false { + if !amqp.hideConnectionInformation { amqp.addConnectionMethods() } amqp.transactions = common.NewCache( @@ -194,8 +194,8 @@ func (amqp *amqpPlugin) ConnectionTimeout() time.Duration { } func (amqp *amqpPlugin) Parse(pkt *protos.Packet, tcptuple *common.TCPTuple, - dir uint8, private protos.ProtocolData) protos.ProtocolData { - + dir uint8, private protos.ProtocolData, +) protos.ProtocolData { defer logp.Recover("ParseAmqp exception") detailedf("Parse method triggered") @@ -284,7 +284,7 @@ func (amqp *amqpPlugin) handleAmqpRequest(msg *amqpMessage) { } else { trans.request = msg.method } - //length = message + 4 bytes header + frame end octet + // length = message + 4 bytes header + frame end octet trans.bytesIn = msg.bodySize + 12 if msg.fields != nil { trans.amqp = msg.fields @@ -292,9 +292,9 @@ func (amqp *amqpPlugin) handleAmqpRequest(msg *amqpMessage) { trans.amqp = common.MapStr{} } - //if error or exception, publish it now. sometimes client or server never send - //an ack message and the error is lost. Also, if nowait flag set, don't expect - //any response and publish + // if error or exception, publish it now. sometimes client or server never send + // an ack message and the error is lost. Also, if nowait flag set, don't expect + // any response and publish if isAsynchronous(trans) { amqp.publishTransaction(trans) debugf("Amqp transaction completed") @@ -317,9 +317,9 @@ func (amqp *amqpPlugin) handleAmqpResponse(msg *amqpMessage) { return } - //length = message + 4 bytes class/method + frame end octet + header + // length = message + 4 bytes class/method + frame end octet + header trans.bytesOut = msg.bodySize + 12 - //merge the both fields from request and response + // merge the both fields from request and response trans.amqp.Update(msg.fields) trans.response = common.OK_STATUS @@ -344,8 +344,8 @@ func (amqp *amqpPlugin) handleAmqpResponse(msg *amqpMessage) { func (amqp *amqpPlugin) expireTransaction(trans *amqpTransaction) { debugf("Transaction expired") - //possibility of a connection.close or channel.close method that didn't get an - //ok answer. Let's publish it. + // possibility of a connection.close or channel.close method that didn't get an + // ok answer. Let's publish it. if isCloseError(trans) { trans.notes = append(trans.notes, "Close-ok method not received by sender") amqp.publishTransaction(trans) @@ -354,8 +354,8 @@ func (amqp *amqpPlugin) expireTransaction(trans *amqpTransaction) { amqp.transactions.Delete(trans.tuple.Hashable()) } -//This method handles published messages from clients. Being an async -//process, the method, header and body frames are regrouped in one transaction +// This method handles published messages from clients. Being an async +// process, the method, header and body frames are regrouped in one transaction func (amqp *amqpPlugin) handlePublishing(client *amqpMessage) { tuple := client.tcpTuple trans := amqp.getTransaction(tuple.Hashable()) @@ -369,8 +369,8 @@ func (amqp *amqpPlugin) handlePublishing(client *amqpMessage) { trans.src, trans.dst = common.MakeEndpointPair(client.tcpTuple.BaseTuple, client.cmdlineTuple) trans.method = client.method - //for publishing and delivering, bytes in and out represent the length of the - //message itself + // for publishing and delivering, bytes in and out represent the length of the + // message itself trans.bytesIn = client.bodySize if client.bodySize > uint64(amqp.maxBodyLength) { @@ -384,13 +384,13 @@ func (amqp *amqpPlugin) handlePublishing(client *amqpMessage) { trans.amqp = client.fields amqp.publishTransaction(trans) debugf("Amqp transaction completed") - //delete trans from map + // delete trans from map amqp.transactions.Delete(trans.tuple.Hashable()) } -//This method handles delivered messages via basic.deliver and basic.get-ok AND -//returned messages to clients. Being an async process, the method, header and -//body frames are regrouped in one transaction +// This method handles delivered messages via basic.deliver and basic.get-ok AND +// returned messages to clients. Being an async process, the method, header and +// body frames are regrouped in one transaction func (amqp *amqpPlugin) handleDelivering(server *amqpMessage) { tuple := server.tcpTuple trans := amqp.getTransaction(tuple.Hashable()) @@ -403,8 +403,8 @@ func (amqp *amqpPlugin) handleDelivering(server *amqpMessage) { trans.ts = server.ts trans.src, trans.dst = common.MakeEndpointPair(server.tcpTuple.BaseTuple, server.cmdlineTuple) - //for publishing and delivering, bytes in and out represent the length of the - //message itself + // for publishing and delivering, bytes in and out represent the length of the + // message itself trans.bytesOut = server.bodySize if server.bodySize > uint64(amqp.maxBodyLength) { @@ -422,7 +422,7 @@ func (amqp *amqpPlugin) handleDelivering(server *amqpMessage) { amqp.publishTransaction(trans) debugf("Amqp transaction completed") - //delete trans from map + // delete trans from map amqp.transactions.Delete(trans.tuple.Hashable()) } @@ -459,7 +459,7 @@ func (amqp *amqpPlugin) publishTransaction(t *amqpTransaction) { fields["user.id"] = userID } - //let's try to convert request/response to a readable format + // let's try to convert request/response to a readable format if amqp.sendRequest { if t.method == "basic.publish" { if t.toString { @@ -503,7 +503,7 @@ func (amqp *amqpPlugin) publishTransaction(t *amqpTransaction) { amqp.results(evt) } -//function to check if method is async or not +// function to check if method is async or not func isAsynchronous(trans *amqpTransaction) bool { if val, ok := trans.amqp["no-wait"]; ok && val == true { return true @@ -514,7 +514,7 @@ func isAsynchronous(trans *amqpTransaction) bool { trans.method == "basic.nack" } -//function to convert a body slice into a readable format +// function to convert a body slice into a readable format func bodyToString(data []byte) string { ret := make([]string, len(data)) for i, c := range data { @@ -523,7 +523,7 @@ func bodyToString(data []byte) string { return strings.Join(ret, " ") } -//function used to check if a body message can be converted to readable string +// function used to check if a body message can be converted to readable string func isStringable(m *amqpMessage) bool { stringable := false diff --git a/packetbeat/protos/amqp/amqp_fields.go b/packetbeat/protos/amqp/amqp_fields.go index ff4f7c382b5c..d75365729785 100644 --- a/packetbeat/protos/amqp/amqp_fields.go +++ b/packetbeat/protos/amqp/amqp_fields.go @@ -28,9 +28,9 @@ import ( "github.com/elastic/beats/v7/libbeat/logp" ) +// getTable updates fields with the table data at the given offset. +// fields must be non_nil on entry. func getTable(fields common.MapStr, data []byte, offset uint32) (next uint32, err bool, exists bool) { - ret := common.MapStr{} - length := binary.BigEndian.Uint32(data[offset : offset+4]) // size declared too big @@ -39,23 +39,20 @@ func getTable(fields common.MapStr, data []byte, offset uint32) (next uint32, er } if length > 0 { exists = true - err := fieldUnmarshal(ret, data[offset+4:offset+4+length], 0, length, -1) + table := common.MapStr{} + err := fieldUnmarshal(table, data[offset+4:offset+4+length], 0, length, -1) if err { logp.Warn("Error while parsing a field table") return 0, true, false } - if fields == nil { - fields = ret - } else { - fields.Update(ret) - } + fields.Update(table) } return length + 4 + offset, false, exists } +// getTable updates fields with the array data at the given offset. +// fields must be non_nil on entry. func getArray(fields common.MapStr, data []byte, offset uint32) (next uint32, err bool, exists bool) { - ret := common.MapStr{} - length := binary.BigEndian.Uint32(data[offset : offset+4]) // size declared too big @@ -64,30 +61,27 @@ func getArray(fields common.MapStr, data []byte, offset uint32) (next uint32, er } if length > 0 { exists = true - err := fieldUnmarshal(ret, data[offset+4:offset+4+length], 0, length, 0) + array := common.MapStr{} + err := fieldUnmarshal(array, data[offset+4:offset+4+length], 0, length, 0) if err { logp.Warn("Error while parsing a field array") return 0, true, false } - if fields == nil { - fields = ret - } else { - fields.Update(ret) - } + fields.Update(array) } return length + 4 + offset, false, exists } -//The index parameter, when set at -1, indicates that the entry is a field table. -//If it's set at 0, it is an array. +// The index parameter, when set at -1, indicates that the entry is a field table. +// If it's set at 0, it is an array. func fieldUnmarshal(table common.MapStr, data []byte, offset uint32, length uint32, index int) (err bool) { var name string if offset >= length { return false } - //get name of the field. If it's an array, it will be the index parameter as a - //string. If it's a table, it will be the name of the field. + // get name of the field. If it's an array, it will be the index parameter as a + // string. If it's a table, it will be the name of the field. if index < 0 { fieldName, offsetTemp, err := getShortString(data, offset+1, uint32(data[offset])) if err { @@ -199,10 +193,10 @@ func fieldUnmarshal(table common.MapStr, data []byte, offset uint32, length uint table[name] = bodyToByteArray(data[offset+1+size : offset+5+size]) offset += 5 + size default: - //unknown field + // unknown field return true } - //advance to next field recursively + // advance to next field recursively return fieldUnmarshal(table, data, offset, length, index) } diff --git a/packetbeat/protos/amqp/amqp_methods.go b/packetbeat/protos/amqp/amqp_methods.go index 93cec5f27474..d74148026c5c 100644 --- a/packetbeat/protos/amqp/amqp_methods.go +++ b/packetbeat/protos/amqp/amqp_methods.go @@ -32,7 +32,7 @@ func connectionStartMethod(m *amqpMessage, args []byte) (bool, bool) { properties := make(common.MapStr) next, err, exists := getTable(properties, args, 2) if err { - //failed to get de peer-properties, size may be wrong, let's quit + // failed to get de peer-properties, size may be wrong, let's quit logp.Warn("Failed to parse server properties in connection.start method") return false, false } @@ -54,7 +54,7 @@ func connectionStartMethod(m *amqpMessage, args []byte) (bool, bool) { "mechanisms": mechanisms, "locales": locales, } - //if there is a server properties table, add it + // if there is a server properties table, add it if exists { m.fields["server-properties"] = properties } @@ -65,7 +65,7 @@ func connectionStartOkMethod(m *amqpMessage, args []byte) (bool, bool) { properties := make(common.MapStr) next, err, exists := getTable(properties, args, 0) if err { - //failed to get de peer-properties, size may be wrong, let's quit + // failed to get de peer-properties, size may be wrong, let's quit logp.Warn("Failed to parse server properties in connection.start method") return false, false } @@ -89,7 +89,7 @@ func connectionStartOkMethod(m *amqpMessage, args []byte) (bool, bool) { "mechanism": mechanism, "locale": locale, } - //if there is a client properties table, add it + // if there is a client properties table, add it if exists { m.fields["client-properties"] = properties } @@ -99,8 +99,8 @@ func connectionStartOkMethod(m *amqpMessage, args []byte) (bool, bool) { func connectionTuneMethod(m *amqpMessage, args []byte) (bool, bool) { m.isRequest = true m.method = "connection.tune" - //parameters are not parsed here, they are further negotiated by the server - //in the connection.tune-ok method + // parameters are not parsed here, they are further negotiated by the server + // in the connection.tune-ok method return true, true } @@ -163,7 +163,7 @@ func channelCloseMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } -//function to fetch fields from channel close and connection close +// function to fetch fields from channel close and connection close func getCloseInfo(args []byte, m *amqpMessage) bool { code := binary.BigEndian.Uint16(args[0:2]) m.isRequest = true @@ -411,7 +411,7 @@ func exchangeDeleteMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } -//this is a method exclusive to RabbitMQ +// this is a method exclusive to RabbitMQ func exchangeBindMethod(m *amqpMessage, args []byte) (bool, bool) { m.method = "exchange.bind" err := exchangeBindUnbindInfo(m, args) @@ -421,7 +421,7 @@ func exchangeBindMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } -//this is a method exclusive to RabbitMQ +// this is a method exclusive to RabbitMQ func exchangeUnbindMethod(m *amqpMessage, args []byte) (bool, bool) { m.method = "exchange.unbind" err := exchangeBindUnbindInfo(m, args) @@ -588,7 +588,7 @@ func basicPublishMethod(m *amqpMessage, args []byte) (bool, bool) { func basicReturnMethod(m *amqpMessage, args []byte) (bool, bool) { code := binary.BigEndian.Uint16(args[0:2]) if code < 300 { - //not an error or exception ? not interesting + // not an error or exception ? not interesting return true, false } replyText, nextOffset, err := getShortString(args, 3, uint32(args[2])) @@ -707,7 +707,7 @@ func basicAckMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } -//this is a rabbitMQ specific method +// this is a rabbitMQ specific method func basicNackMethod(m *amqpMessage, args []byte) (bool, bool) { params := getBitParams(args[8]) m.method = "basic.nack" @@ -761,14 +761,14 @@ func txRollbackMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } -//simple function used when server/client responds to a sync method with no new info +// simple function used when server/client responds to a sync method with no new info func okMethod(m *amqpMessage, args []byte) (bool, bool) { return true, true } // function to get a short string. It sends back an error if slice is too short -//for declared length. if length == 0, the function sends back an empty string and -//advances the offset. Otherwise, it returns the string and the new offset +// for declared length. if length == 0, the function sends back an empty string and +// advances the offset. Otherwise, it returns the string and the new offset func getShortString(data []byte, start uint32, length uint32) (short string, nextOffset uint32, err bool) { if length == 0 { return "", start, false @@ -779,7 +779,7 @@ func getShortString(data []byte, start uint32, length uint32) (short string, nex return string(data[start : start+length]), start + length, false } -//function to extract bit information in various AMQP methods +// function to extract bit information in various AMQP methods func getBitParams(bits byte) (ret [5]bool) { if bits&16 == 16 { ret[4] = true diff --git a/packetbeat/protos/amqp/amqp_parser.go b/packetbeat/protos/amqp/amqp_parser.go index 6ab15ec81591..a623219ca0ba 100644 --- a/packetbeat/protos/amqp/amqp_parser.go +++ b/packetbeat/protos/amqp/amqp_parser.go @@ -42,10 +42,10 @@ func (amqp *amqpPlugin) amqpMessageParser(s *amqpStream) (ok bool, complete bool f, err := readFrameHeader(s.data[s.parseOffset:]) if err { - //incorrect header + // incorrect header return false, false } else if f == nil { - //header not complete + // header not complete return true, false } @@ -67,17 +67,14 @@ func (amqp *amqpPlugin) amqpMessageParser(s *amqpStream) (ok bool, complete bool s.parseOffset += 8 + int(f.size) if !ok { return false, false - } else if complete { + } + if complete { return true, true } } return ok, complete } -func (s *amqpStream) prepareForNewMessage() { - s.message = nil -} - func isProtocolHeader(data []byte) (isHeader bool, version string) { if (string(data[:4]) == "AMQP") && data[4] == 0 { return true, string(data[5:8]) @@ -85,7 +82,7 @@ func isProtocolHeader(data []byte) (isHeader bool, version string) { return false, "" } -//func to read a frame header and check if it is valid and complete +// func to read a frame header and check if it is valid and complete func readFrameHeader(data []byte) (ret *amqpFrame, err bool) { var frame amqpFrame if len(data) < 8 { @@ -103,7 +100,7 @@ func readFrameHeader(data []byte) (ret *amqpFrame, err bool) { } frame.Type = frameType(data[0]) if frame.size == 0 { - //frame content is nil with heartbeat frames + // frame content is nil with heartbeat frames frame.content = nil } else { frame.content = data[7 : frame.size+7] @@ -159,7 +156,7 @@ func (amqp *amqpPlugin) decodeHeaderFrame(s *amqpStream, buf []byte) bool { s.message.bodySize = binary.BigEndian.Uint64(buf[4:12]) debugf("Received Header frame. A message of %d bytes is expected", s.message.bodySize) - if amqp.parseHeaders == true { + if amqp.parseHeaders { err := getMessageProperties(s, buf[12:]) if err { return false @@ -180,7 +177,7 @@ func (s *amqpStream) decodeBodyFrame(buf []byte) (ok bool, complete bool) { debugf("A body frame of %d bytes long has been transmitted", len(buf)) - //is the message complete ? If yes, let's publish it + // is the message complete ? If yes, let's publish it complete = uint64(len(s.message.body)) >= s.message.bodySize return true, complete @@ -190,16 +187,16 @@ func hasProperty(prop, flag byte) bool { return (prop & flag) == flag } -//function to get message content-type and content-encoding +// function to get message content-type and content-encoding func getMessageProperties(s *amqpStream, data []byte) bool { m := s.message - //properties are coded in the two first bytes + // properties are coded in the two first bytes prop1 := data[0] prop2 := data[1] var offset uint32 = 2 - //while last bit set, we have another property flag field + // while last bit set, we have another property flag field for lastbit := 1; data[lastbit]&1 == 1; { lastbit += 2 offset += 2 @@ -238,9 +235,10 @@ func getMessageProperties(s *amqpStream, data []byte) bool { } if hasProperty(prop1, deliveryModeProp) { - if data[offset] == 1 { + switch data[offset] { + case 1: m.fields["delivery-mode"] = "non-persistent" - } else if data[offset] == 2 { + case 2: m.fields["delivery-mode"] = "persistent" } offset++ @@ -337,20 +335,20 @@ func (amqp *amqpPlugin) handleAmqp(m *amqpMessage, tcptuple *common.TCPTuple, di m.direction = dir m.cmdlineTuple = amqp.watcher.FindProcessesTupleTCP(tcptuple.IPPort()) - if m.method == "basic.publish" { + switch { + case m.method == "basic.publish": amqp.handlePublishing(m) - } else if m.method == "basic.deliver" || m.method == "basic.return" || - m.method == "basic.get-ok" { + case m.method == "basic.deliver" || m.method == "basic.return" || m.method == "basic.get-ok": amqp.handleDelivering(m) - } else if m.isRequest == true { + case m.isRequest: amqp.handleAmqpRequest(m) - } else if m.isRequest == false { + default: // !m.isRequest amqp.handleAmqpResponse(m) } } func (amqp *amqpPlugin) mustHideCloseMethod(m *amqpMessage) bool { - return amqp.hideConnectionInformation == true && + return amqp.hideConnectionInformation && (m.method == "connection.close" || m.method == "channel.close") && - getReplyCode(m.fields) < uint16(300) + getReplyCode(m.fields) < 300 } diff --git a/packetbeat/protos/amqp/amqp_structs.go b/packetbeat/protos/amqp/amqp_structs.go index 387e8df6fcb4..ada8441c45a8 100644 --- a/packetbeat/protos/amqp/amqp_structs.go +++ b/packetbeat/protos/amqp/amqp_structs.go @@ -30,12 +30,12 @@ const ( transactionTimeout = 10 * 1e9 ) -//layout used when a timestamp must be parsed +// layout used when a timestamp must be parsed const ( amqpTimeLayout = "January _2 15:04:05 2006" ) -//Frame types and codes +// Frame types and codes type frameType byte @@ -50,7 +50,7 @@ const ( frameEndOctet byte = 206 ) -//Codes for MethodMap +// Codes for MethodMap type codeClass uint16 const ( @@ -137,7 +137,7 @@ const ( txRollbackOk codeMethod = 31 ) -//Message properties codes for byte prop1 in getMessageProperties +// Message properties codes for byte prop1 in getMessageProperties const ( expirationProp byte = 1 replyToProp byte = 2 @@ -149,7 +149,7 @@ const ( contentTypeProp byte = 128 ) -//Message properties codes for byte prop2 in getMessageProperties +// Message properties codes for byte prop2 in getMessageProperties const ( appIDProp byte = 8 @@ -159,7 +159,7 @@ const ( messageIDProp byte = 128 ) -//table types +// table types const ( boolean = 't' shortShortInt = 'b' @@ -179,7 +179,7 @@ const ( timestamp = 'T' fieldTable = 'F' noField = 'V' - byteArray = 'x' //rabbitMQ specific field + byteArray = 'x' // rabbitMQ specific field ) type amqpPrivateData struct { @@ -203,7 +203,7 @@ type amqpMessage struct { direction uint8 parseArguments bool - //mapstr containing all the options for the methods and header fields + // mapstr containing all the options for the methods and header fields fields common.MapStr body []byte diff --git a/packetbeat/protos/amqp/amqp_test.go b/packetbeat/protos/amqp/amqp_test.go index 725de0f3d116..9b7f7dca35c5 100644 --- a/packetbeat/protos/amqp/amqp_test.go +++ b/packetbeat/protos/amqp/amqp_test.go @@ -96,7 +96,7 @@ func TestAmqp_FrameSize(t *testing.T) { _, amqp := amqpModForTests() - //incomplete frame + // incomplete frame data, err := hex.DecodeString("0100000000000c000a001fffff000200") assert.NoError(t, err) @@ -118,7 +118,7 @@ func TestAmqp_PartialFrameSize(t *testing.T) { _, amqp := amqpModForTests() - //incomplete frame + // incomplete frame data, err := hex.DecodeString("414d515000060606010000000000") assert.NoError(t, err) @@ -275,7 +275,7 @@ func TestAmqp_ExchangeDeletion(t *testing.T) { assert.Equal(t, false, m.fields["no-wait"]) } -//this method is exclusive to RabbitMQ +// this method is exclusive to RabbitMQ func TestAmqp_ExchangeBind(t *testing.T) { logp.TestingSetup(logp.WithSelectors("amqp", "amqpdetailed")) @@ -308,7 +308,7 @@ func TestAmqp_ExchangeBind(t *testing.T) { } } -//this method is exclusive to RabbitMQ +// this method is exclusive to RabbitMQ func TestAmqp_ExchangeUnbindTransaction(t *testing.T) { logp.TestingSetup(logp.WithSelectors("amqp", "amqpdetailed")) @@ -365,13 +365,13 @@ func TestAmqp_PublishMessage(t *testing.T) { req := protos.Packet{Payload: data} private := protos.ProtocolData(new(amqpPrivateData)) - //method frame + // method frame private = amqp.Parse(&req, tcptuple, 0, private) req = protos.Packet{Payload: data2} - //header frame + // header frame private = amqp.Parse(&req, tcptuple, 0, private) req = protos.Packet{Payload: data3} - //body frame + // body frame amqp.Parse(&req, tcptuple, 0, private) trans := expectTransaction(t, results) @@ -414,13 +414,13 @@ func TestAmqp_DeliverMessage(t *testing.T) { req := protos.Packet{Payload: data} private := protos.ProtocolData(new(amqpPrivateData)) - //method frame + // method frame private = amqp.Parse(&req, tcptuple, 0, private) req = protos.Packet{Payload: data2} - //header frame + // header frame private = amqp.Parse(&req, tcptuple, 0, private) req = protos.Packet{Payload: data3} - //body frame + // body frame amqp.Parse(&req, tcptuple, 0, private) trans := expectTransaction(t, results) @@ -467,7 +467,7 @@ func TestAmqp_MessagePropertiesFields(t *testing.T) { assert.Equal(t, "el mensaje", m.fields["message-id"]) assert.Equal(t, "love message", m.fields["type"]) assert.Equal(t, "text/plain", m.fields["content-type"]) - //assert.Equal(t, "September 15 15:31:44 2015", m.Fields["timestamp"]) + // assert.Equal(t, "September 15 15:31:44 2015", m.Fields["timestamp"]) priority, ok := m.fields["priority"].(uint8) if !ok { t.Errorf("Field should be present") @@ -576,7 +576,7 @@ func TestAmqp_RejectMessage(t *testing.T) { req := protos.Packet{Payload: data} private := protos.ProtocolData(new(amqpPrivateData)) - //method frame + // method frame amqp.Parse(&req, tcptuple, 0, private) trans := expectTransaction(t, results) @@ -668,8 +668,8 @@ func TestAmqp_MaxBodyLength(t *testing.T) { req := protos.Packet{Payload: data} private := protos.ProtocolData(new(amqpPrivateData)) - //method frame - private = amqp.Parse(&req, tcptuple, 0, private) + // method frame + amqp.Parse(&req, tcptuple, 0, private) trans := expectTransaction(t, results) @@ -699,7 +699,7 @@ func TestAmqp_MaxBodyLength(t *testing.T) { req = protos.Packet{Payload: data} private = protos.ProtocolData(new(amqpPrivateData)) - //method frame + // method frame amqp.Parse(&req, tcptuple, 0, private) trans = expectTransaction(t, results) @@ -728,7 +728,7 @@ func TestAmqp_HideArguments(t *testing.T) { amqp.parseHeaders = false amqp.parseArguments = false - //parse args + // parse args data, err := hex.DecodeString("0100010000004d0032000a00000a5465737448656164" + "6572180000003704626f6f6c74010362697462050568656c6c6f530000001f4869206461" + "726c696e6720c3aac3aac3aac3aac3aac3aac3aae697a5e69cacce") @@ -736,7 +736,7 @@ func TestAmqp_HideArguments(t *testing.T) { tcptuple := testTCPTuple() req := protos.Packet{Payload: data} private := protos.ProtocolData(new(amqpPrivateData)) - private = amqp.Parse(&req, tcptuple, 0, private) + amqp.Parse(&req, tcptuple, 0, private) trans := expectTransaction(t, results) assert.Equal(t, "queue.declare", trans["method"]) @@ -753,7 +753,7 @@ func TestAmqp_HideArguments(t *testing.T) { t.Errorf("Arguments field should not be present") } - //parse headers + // parse headers data, err = hex.DecodeString("01000100000013003c00280000000a546573744865616" + "4657200ce02000100000026003c0000000000000000001a98800a746578742f706c61696" + "e02060a656c206d656e73616a65ce0300010000001a54657374206865616465722066696" + @@ -808,7 +808,7 @@ func TestAmqp_RecoverMethod(t *testing.T) { assert.Equal(t, common.MapStr{"requeue": true}, trans["amqp"]) } -//this is a specific rabbitMQ method +// this is a specific rabbitMQ method func TestAmqp_BasicNack(t *testing.T) { logp.TestingSetup(logp.WithSelectors("amqp", "amqpdetailed")) @@ -887,7 +887,7 @@ func TestAmqp_GetTable(t *testing.T) { assert.Equal(t, true, m.fields["no-wait"]) assert.Equal(t, true, m.fields["auto-delete"]) assert.Equal(t, false, m.fields["exclusive"]) - //assert.Equal(t, "September 15 11:25:29 2015", args["timestamp"]) + // assert.Equal(t, "September 15 11:25:29 2015", args["timestamp"]) assert.Equal(t, "TestHeader", m.request) } @@ -948,7 +948,7 @@ func TestAmqp_ArrayFields(t *testing.T) { _, amqp := amqpModForTests() - //byte array, rabbitMQ specific field + // byte array, rabbitMQ specific field data, err := hex.DecodeString("010001000000260028000a0000057465737431057" + "46f706963020000000f05617272617978000000040a007dd2ce") assert.NoError(t, err) @@ -1025,7 +1025,7 @@ func TestAmqp_WrongTable(t *testing.T) { _, amqp := amqpModForTests() - //declared table size too big + // declared table size too big data, err := hex.DecodeString("010001000000890032000a00000a54657374486561646" + "57218000000da0974696d657374616d70540000000055f7e409036269746205076465636" + "96d616c440500ec49050568656c6c6f530000001f4869206461726c696e6720c3aac3aac" + @@ -1048,7 +1048,7 @@ func TestAmqp_WrongTable(t *testing.T) { } assert.Equal(t, []string{"Failed to parse additional arguments"}, m.notes) - //table size ok, but total non-sense inside + // table size ok, but total non-sense inside data, err = hex.DecodeString("010001000000890032000a00000a54657374486561646" + "57218000000730974696d657374616d7054004400005521e409036269743705076400036" + "96d616c447600ec49180568036c6c0b536400001f480a2064076e6c696e0520c3aac3aac" + diff --git a/packetbeat/protos/amqp/config.go b/packetbeat/protos/amqp/config.go index 2939530046ee..4cbd5a5200a3 100644 --- a/packetbeat/protos/amqp/config.go +++ b/packetbeat/protos/amqp/config.go @@ -30,14 +30,12 @@ type amqpConfig struct { HideConnectionInformation bool `config:"hide_connection_information"` } -var ( - defaultConfig = amqpConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - ParseHeaders: true, - ParseArguments: true, - MaxBodyLength: 1000, - HideConnectionInformation: true, - } -) +var defaultConfig = amqpConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + ParseHeaders: true, + ParseArguments: true, + MaxBodyLength: 1000, + HideConnectionInformation: true, +} diff --git a/packetbeat/protos/cassandra/cassandra.go b/packetbeat/protos/cassandra/cassandra.go index 7d3001a51595..5c7cbd003d1c 100644 --- a/packetbeat/protos/cassandra/cassandra.go +++ b/packetbeat/protos/cassandra/cassandra.go @@ -50,9 +50,7 @@ type stream struct { parser parser } -var ( - debugf = logp.MakeDebug("cassandra") -) +var debugf = logp.MakeDebug("cassandra") func init() { protos.Register("cassandra", New) @@ -202,11 +200,6 @@ func (cassandra *cassandra) ensureConnection(private protos.ProtocolData) *conne return conn } -func (conn *connection) dropStreams() { - conn.streams[0] = nil - conn.streams[1] = nil -} - func getConnection(private protos.ProtocolData) *connection { if private == nil { return nil diff --git a/packetbeat/protos/cassandra/config.go b/packetbeat/protos/cassandra/config.go index 0eafddcd1ee0..8e93239bc6b9 100644 --- a/packetbeat/protos/cassandra/config.go +++ b/packetbeat/protos/cassandra/config.go @@ -34,20 +34,18 @@ type cassandraConfig struct { OPsIgnored []gocql.FrameOp `config:"ignored_ops"` } -var ( - defaultConfig = cassandraConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - SendRequest: true, - SendResponse: true, - }, - SendRequestHeader: true, - SendResponseHeader: true, - } -) +var defaultConfig = cassandraConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + SendRequest: true, + SendResponse: true, + }, + SendRequestHeader: true, + SendResponseHeader: true, +} func (c *cassandraConfig) Validate() error { - if !(c.Compressor == "" || c.Compressor == "snappy") { + if c.Compressor != "" && c.Compressor != "snappy" { return fmt.Errorf("invalid compressor config: %s, only snappy supported", c.Compressor) } return nil diff --git a/packetbeat/protos/cassandra/internal/gocql/array_decoder.go b/packetbeat/protos/cassandra/internal/gocql/array_decoder.go index a224dc7d1b5e..b64ecf8e1462 100644 --- a/packetbeat/protos/cassandra/internal/gocql/array_decoder.go +++ b/packetbeat/protos/cassandra/internal/gocql/array_decoder.go @@ -26,10 +26,6 @@ type ByteArrayDecoder struct { Data *[]byte } -func readInt(p []byte) int32 { - return int32(p[0])<<24 | int32(p[1])<<16 | int32(p[2])<<8 | int32(p[3]) -} - func (f ByteArrayDecoder) ReadByte() (byte, error) { data := *f.Data if len(data) < 1 { @@ -167,7 +163,7 @@ func (f ByteArrayDecoder) ReadInet() (net.IP, int) { size := data[0] *f.Data = data[1:] - if !(size == 4 || size == 16) { + if size != 4 && size != 16 { panic(fmt.Errorf("invalid IP size: %d", size)) } diff --git a/packetbeat/protos/cassandra/internal/gocql/compressor.go b/packetbeat/protos/cassandra/internal/gocql/compressor.go index cfbff208ade2..fe6583c3a772 100644 --- a/packetbeat/protos/cassandra/internal/gocql/compressor.go +++ b/packetbeat/protos/cassandra/internal/gocql/compressor.go @@ -49,11 +49,11 @@ func (s SnappyCompressor) Decode(data []byte) ([]byte, error) { const LZ4 string = "lz4" type LZ4Compressor struct { - //TODO + // TODO } const Deflate string = "deflate" type DeflateCompressor struct { - //TODO + // TODO } diff --git a/packetbeat/protos/cassandra/internal/gocql/decoder.go b/packetbeat/protos/cassandra/internal/gocql/decoder.go index 734a940d8bdb..f628aa651204 100644 --- a/packetbeat/protos/cassandra/internal/gocql/decoder.go +++ b/packetbeat/protos/cassandra/internal/gocql/decoder.go @@ -23,34 +23,19 @@ import ( type Decoder interface { ReadByte() (byte, error) - ReadInt() (n int) - ReadShort() (n uint16) - ReadLong() (n int64) - ReadString() (s string) - ReadLongString() (s string) - ReadUUID() *UUID - ReadStringList() []string - ReadBytesInternal() []byte - ReadBytes() []byte - ReadShortBytes() []byte - ReadInet() (net.IP, int) - ReadConsistency() Consistency - ReadStringMap() map[string]string - ReadBytesMap() map[string][]byte - ReadStringMultiMap() map[string][]string } diff --git a/packetbeat/protos/cassandra/internal/gocql/frame.go b/packetbeat/protos/cassandra/internal/gocql/frame.go index 25e7df5bac88..b8ae7eeac4e8 100644 --- a/packetbeat/protos/cassandra/internal/gocql/frame.go +++ b/packetbeat/protos/cassandra/internal/gocql/frame.go @@ -182,18 +182,17 @@ func (f *Framer) ReadFrame() (data map[string]interface{}, err error) { data = make(map[string]interface{}) - //Only QUERY, PREPARE and EXECUTE queries support tracing - //If a response frame has the tracing flag set, its body contains - //a tracing ID. The tracing ID is a [uuid] and is the first thing in - //the frame body. The rest of the body will then be the usual body - //corresponding to the response opcode. + // Only QUERY, PREPARE and EXECUTE queries support tracing + // If a response frame has the tracing flag set, its body contains + // a tracing ID. The tracing ID is a [uuid] and is the first thing in + // the frame body. The rest of the body will then be the usual body + // corresponding to the response opcode. if f.Header.Flags&flagTracing == flagTracing && (f.Header.Op&opQuery == opQuery || f.Header.Op&opExecute == opExecute || f.Header.Op&opPrepare == opPrepare) { - debugf("tracing enabled") - //seems no UUID to read, protocol incorrect? - //uid := decoder.ReadUUID() - //data["trace_id"] = uid.String() + // seems no UUID to read, protocol incorrect? + // uid := decoder.ReadUUID() + // data["trace_id"] = uid.String() } if f.Header.Flags&flagWarning == flagWarning { @@ -211,7 +210,7 @@ func (f *Framer) ReadFrame() (data map[string]interface{}, err error) { } if f.Header.Flags&flagCompress == flagCompress { - //decompress data and switch to use bytearray decoder + // decompress data and switch to use bytearray decoder if f.compres == nil { logp.Err("hit compress flag, but compressor was not set") panic(errors.New("hit compress flag, but compressor was not set")) @@ -234,13 +233,13 @@ func (f *Framer) ReadFrame() (data map[string]interface{}, err error) { // assumes that the frame body has been read into rbuf switch f.Header.Op { - //below ops are requests + // below ops are requests case opStartup, opAuthResponse, opOptions, opPrepare, opExecute, opBatch, opRegister: - //ignored + // ignored case opQuery: data = f.parseQueryFrame() - //below ops are responses + // below ops are responses case opError: data["error"] = f.parseErrorFrame() case opResult: @@ -259,7 +258,7 @@ func (f *Framer) ReadFrame() (data map[string]interface{}, err error) { // the body should be empty default: - //ignore + // ignore debugf("unknow ops, not processed, %v", f.Header) } @@ -348,7 +347,7 @@ func (f *Framer) parseErrorFrame() (data map[string]interface{}) { case errInvalid, errBootstrapping, errConfig, errCredentials, errOverloaded, errProtocol, errServer, errSyntax, errTruncate, errUnauthorized: - //ignored + // ignored default: logp.Err("unknown error code: 0x%x", code) } @@ -375,8 +374,7 @@ func (f *Framer) parseResultMetadata(getPKinfo bool) map[string]interface{} { meta["col_count"] = colCount if getPKinfo { - - //only for prepared result + // only for prepared result if f.proto >= protoVersion4 { pkeyCount := decoder.ReadInt() pkeys := make([]int, pkeyCount) @@ -450,7 +448,6 @@ func (f *Framer) parseResultPrepared() map[string]interface{} { result := make(map[string]interface{}) uuid, err := UUIDFromBytes((f.decoder).ReadShortBytes()) - if err != nil { logp.Err("Error in parsing UUID") } diff --git a/packetbeat/protos/cassandra/internal/gocql/marshal.go b/packetbeat/protos/cassandra/internal/gocql/marshal.go index 2061bb2f11e8..3c55781cc81c 100644 --- a/packetbeat/protos/cassandra/internal/gocql/marshal.go +++ b/packetbeat/protos/cassandra/internal/gocql/marshal.go @@ -349,8 +349,8 @@ const ( errUnprepared ErrType = 0x2500 ) -func (this ErrType) String() string { - switch this { +func (e ErrType) String() string { + switch e { case errUnavailable: return "errUnavailable" case errWriteTimeout: @@ -680,7 +680,7 @@ func (u UUID) Bytes() []byte { // String returns the UUID in it's canonical form, a 32 digit hexadecimal // number in the form of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. func (u UUID) String() string { - var offsets = [...]int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} + offsets := [...]int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} const hexString = "0123456789abcdef" r := make([]byte, 36) for i, b := range u { diff --git a/packetbeat/protos/cassandra/internal/gocql/stream_decoder.go b/packetbeat/protos/cassandra/internal/gocql/stream_decoder.go index ae107a95e9ed..f39cde2d11e1 100644 --- a/packetbeat/protos/cassandra/internal/gocql/stream_decoder.go +++ b/packetbeat/protos/cassandra/internal/gocql/stream_decoder.go @@ -149,7 +149,7 @@ func (f StreamDecoder) ReadInet() (net.IP, int) { panic(err) } - if !(size == 4 || size == 16) { + if size != 4 && size != 16 { panic(fmt.Errorf("invalid IP size: %d", size)) } diff --git a/packetbeat/protos/cassandra/parser.go b/packetbeat/protos/cassandra/parser.go index f699187b03f3..65ff347a1eab 100644 --- a/packetbeat/protos/cassandra/parser.go +++ b/packetbeat/protos/cassandra/parser.go @@ -44,14 +44,7 @@ type parserConfig struct { // check whether this ops is enabled or not func (p *parser) CheckFrameOpsIgnored() bool { - if p.config.ignoredOps != nil && len(p.config.ignoredOps) > 0 { - //default map value is false - v := p.config.ignoredOps[p.framer.Header.Op] - if v { - return true - } - } - return false + return p.config.ignoredOps[p.framer.Header.Op] } type message struct { @@ -69,8 +62,6 @@ type message struct { // list element use by 'transactions' for correlation next *message - transactionTimeout time.Duration - results transactions } @@ -91,7 +82,6 @@ func (p *parser) init( } isDebug = logp.IsDebug("cassandra") - } func (p *parser) append(data []byte) error { @@ -153,7 +143,7 @@ func (p *parser) parserBody() (bool, error) { return true, nil } - //let's wait for enough buf + // let's wait for enough buf debugf("bodyLength: %d", bdyLen) if !p.buf.Avail(bdyLen) { if isDebug { @@ -162,7 +152,7 @@ func (p *parser) parserBody() (bool, error) { return false, nil } - //check if the ops already ignored + // check if the ops already ignored if p.message.ignored { if isDebug { debugf("message marked to be ignored, let's do this") @@ -232,7 +222,7 @@ func (p *parser) parse() (*message, error) { } } - //check if the ops need to be ignored + // check if the ops need to be ignored if p.CheckFrameOpsIgnored() { // as we already ignore the content, we now mark the result is ignored p.message.ignored = true @@ -248,7 +238,7 @@ func (p *parser) parse() (*message, error) { return nil, err } - //ignore and wait for more data + // ignore and wait for more data if !finished { return nil, nil } diff --git a/packetbeat/protos/cassandra/pub.go b/packetbeat/protos/cassandra/pub.go index 3b90c53feae7..82effab92d31 100644 --- a/packetbeat/protos/cassandra/pub.go +++ b/packetbeat/protos/cassandra/pub.go @@ -33,7 +33,6 @@ type transPub struct { sendResponse bool sendRequestHeader bool sendResponseHeader bool - ignoredOps string results protos.Reporter } @@ -82,7 +81,7 @@ func (pub *transPub) createEvent(requ, resp *message) beat.Event { cassandra := common.MapStr{} status := common.OK_STATUS - //requ can be null, if the message is a PUSHed message + // requ can be null, if the message is a PUSHed message if requ != nil { pbf.Source.Bytes = int64(requ.Size) pbf.Event.Start = requ.Ts @@ -101,7 +100,7 @@ func (pub *transPub) createEvent(requ, resp *message) beat.Event { } } } else { - //dealing with PUSH message + // dealing with PUSH message cassandra["no_request"] = true } diff --git a/packetbeat/protos/cassandra/trans.go b/packetbeat/protos/cassandra/trans.go index 9b055d22c884..d7a9ae60d5f1 100644 --- a/packetbeat/protos/cassandra/trans.go +++ b/packetbeat/protos/cassandra/trans.go @@ -132,7 +132,6 @@ func (trans *transactions) onResponse( func (trans *transactions) tryMergeRequests( prev, msg *message, ) (merged bool, err error) { - msg.isComplete = true return false, nil } @@ -150,7 +149,7 @@ func (trans *transactions) correlate() error { if requests.empty() { for !responses.empty() { - //if the response is EVENT, which pushed from server, we can accept that + // if the response is EVENT, which pushed from server, we can accept that resp := responses.first() if !resp.isComplete { break diff --git a/packetbeat/protos/dhcpv4/config.go b/packetbeat/protos/dhcpv4/config.go index 4121ee66ba75..7245e3c641b0 100644 --- a/packetbeat/protos/dhcpv4/config.go +++ b/packetbeat/protos/dhcpv4/config.go @@ -25,10 +25,8 @@ type dhcpv4Config struct { config.ProtocolCommon `config:",inline"` } -var ( - defaultConfig = dhcpv4Config{ - ProtocolCommon: config.ProtocolCommon{ - Ports: []int{67, 68}, - }, - } -) +var defaultConfig = dhcpv4Config{ + ProtocolCommon: config.ProtocolCommon{ + Ports: []int{67, 68}, + }, +} diff --git a/packetbeat/protos/dns/config.go b/packetbeat/protos/dns/config.go index c98d52f8257f..c1044cf2f7c2 100644 --- a/packetbeat/protos/dns/config.go +++ b/packetbeat/protos/dns/config.go @@ -28,10 +28,8 @@ type dnsConfig struct { IncludeAdditionals bool `config:"include_additionals"` } -var ( - defaultConfig = dnsConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - } -) +var defaultConfig = dnsConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, +} diff --git a/packetbeat/protos/dns/dns.go b/packetbeat/protos/dns/dns.go index 125d6112bae6..04be88a36b15 100644 --- a/packetbeat/protos/dns/dns.go +++ b/packetbeat/protos/dns/dns.go @@ -59,18 +59,10 @@ type dnsPlugin struct { watcher procs.ProcessesWatcher } -var ( - debugf = logp.MakeDebug("dns") -) +var debugf = logp.MakeDebug("dns") const maxDNSTupleRawSize = 16 + 16 + 2 + 2 + 4 + 1 -// Constants used to associate the DNS QR flag with a meaningful value. -const ( - query = false - response = true -) - // Transport protocol. type transport uint8 @@ -203,13 +195,12 @@ func (dns *dnsPlugin) getTransaction(k hashableDNSTuple) *dnsTransaction { } type dnsTransaction struct { - ts time.Time // Time when the request was received. - tuple dnsTuple // Key used to track this transaction in the transactionsMap. - responseTime int32 // Elapsed time in milliseconds between the request and response. - src common.Endpoint - dst common.Endpoint - transport transport - notes []string + ts time.Time // Time when the request was received. + tuple dnsTuple // Key used to track this transaction in the transactionsMap. + src common.Endpoint + dst common.Endpoint + transport transport + notes []string request *dnsMessage response *dnsMessage diff --git a/packetbeat/protos/dns/dns_tcp.go b/packetbeat/protos/dns/dns_tcp.go index bbf7e7369260..8addcdd68968 100644 --- a/packetbeat/protos/dns/dns_tcp.go +++ b/packetbeat/protos/dns/dns_tcp.go @@ -107,7 +107,6 @@ func (dns *dnsPlugin) doParse(conn *dnsConnectionData, pkt *protos.Packet, tcpTu } } decodedData, err := stream.handleTCPRawData() - if err != nil { if err == incompleteMsg { @@ -259,8 +258,8 @@ func (dns *dnsPlugin) publishResponseError(conn *dnsConnectionData, err error) { trans.notes = append(trans.notes, errDNS.responseError()) // Should we publish the length (bytes_out) of the failed Response? - //streamReverse.message.Length = len(streamReverse.rawData) - //trans.Response = streamReverse.message + // streamReverse.message.Length = len(streamReverse.rawData) + // trans.Response = streamReverse.message dns.publishTransaction(trans) dns.deleteTransaction(hashDNSTupleOrigin) @@ -296,7 +295,6 @@ func (stream *dnsStream) handleTCPRawData() (*mkdns.Msg, error) { } decodedData, err := decodeDNSData(transportTCP, rawData[:stream.parseOffset]) - if err != nil { return nil, err } diff --git a/packetbeat/protos/dns/dns_test.go b/packetbeat/protos/dns/dns_test.go index 9427ebeaecf5..1ba03b2bd610 100644 --- a/packetbeat/protos/dns/dns_test.go +++ b/packetbeat/protos/dns/dns_test.go @@ -316,8 +316,10 @@ func TestRRsToMapStrsWithOPTRecord(t *testing.T) { o.Hdr.Rrtype = mkdns.TypeOPT r := new(mkdns.MX) - r.Hdr = mkdns.RR_Header{Name: "miek.nl", Rrtype: mkdns.TypeMX, - Class: mkdns.ClassINET, Ttl: 3600} + r.Hdr = mkdns.RR_Header{ + Name: "miek.nl", Rrtype: mkdns.TypeMX, + Class: mkdns.ClassINET, Ttl: 3600, + } r.Preference = 10 r.Mx = "mx.miek.nl" diff --git a/packetbeat/protos/dns/dns_udp_test.go b/packetbeat/protos/dns/dns_udp_test.go index 3711fb50e007..62713502e0a6 100644 --- a/packetbeat/protos/dns/dns_udp_test.go +++ b/packetbeat/protos/dns/dns_udp_test.go @@ -155,10 +155,12 @@ var ( qSubdomain: "131.252.30", qTLD: "in-addr.arpa", answers: []string{"github.com"}, - authorities: []string{"a.root-servers.net", "b.root-servers.net", "c.root-servers.net", + authorities: []string{ + "a.root-servers.net", "b.root-servers.net", "c.root-servers.net", "d.root-servers.net", "e.root-servers.net", "f.root-servers.net", "g.root-servers.net", "h.root-servers.net", "i.root-servers.net", "j.root-servers.net", "k.root-servers.net", - "l.root-servers.net", "m.root-servers.net"}, + "l.root-servers.net", "m.root-servers.net", + }, request: []byte{ 0x01, 0x58, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x31, 0x33, 0x31, 0x03, 0x32, 0x35, 0x32, 0x02, 0x33, 0x30, 0x03, 0x31, 0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, diff --git a/packetbeat/protos/http/config.go b/packetbeat/protos/http/config.go index 86f59fb36b1f..45878934b0c4 100644 --- a/packetbeat/protos/http/config.go +++ b/packetbeat/protos/http/config.go @@ -39,12 +39,10 @@ type httpConfig struct { RedactHeaders []string `config:"redact_headers"` } -var ( - defaultConfig = httpConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - MaxMessageSize: tcp.TCPMaxDataInStream, - DecodeBody: true, - } -) +var defaultConfig = httpConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + MaxMessageSize: tcp.TCPMaxDataInStream, + DecodeBody: true, +} diff --git a/packetbeat/protos/http/http.go b/packetbeat/protos/http/http.go index e86cb665587b..9cc436f84f0e 100644 --- a/packetbeat/protos/http/http.go +++ b/packetbeat/protos/http/http.go @@ -39,8 +39,10 @@ import ( "github.com/elastic/beats/v7/packetbeat/protos" ) -var debugf = logp.MakeDebug("http") -var detailedf = logp.MakeDebug("httpdetailed") +var ( + debugf = logp.MakeDebug("http") + detailedf = logp.MakeDebug("httpdetailed") +) type parserState uint8 @@ -300,7 +302,6 @@ func (http *httpPlugin) doParse( tcptuple *common.TCPTuple, dir uint8, ) *httpConnectionData { - if isDetailed { detailedf("Payload received: [%s]", pkt.Payload) } @@ -368,8 +369,8 @@ func newStream(pkt *protos.Packet, tcptuple *common.TCPTuple) *stream { // ReceivedFin will be called when TCP transaction is terminating. func (http *httpPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { debugf("Received FIN") conn := getHTTPConnection(private) if conn == nil { @@ -396,8 +397,8 @@ func (http *httpPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, // GapInStream is called when a gap of nbytes bytes is found in the stream (due // to packet loss). func (http *httpPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { defer logp.Recover("GapInStream(http) exception") conn := getHTTPConnection(private) @@ -436,7 +437,6 @@ func (http *httpPlugin) handleHTTP( tcptuple *common.TCPTuple, dir uint8, ) { - m.tcpTuple = *tcptuple m.direction = dir m.cmdlineTuple = http.watcher.FindProcessesTupleTCP(tcptuple.IPPort()) @@ -488,7 +488,6 @@ func (http *httpPlugin) flushRequests(conn *httpConnectionData) { } func (http *httpPlugin) correlate(conn *httpConnectionData) { - // drop responses with missing requests if conn.requests.empty() { http.flushResponses(conn) @@ -724,8 +723,7 @@ func splitCookiesHeader(headerVal string) map[string]string { for _, cval := range cstring { cookie := strings.SplitN(cval, "=", 2) if len(cookie) == 2 { - cookies[strings.ToLower(strings.TrimSpace(cookie[0]))] = - parseCookieValue(strings.TrimSpace(cookie[1])) + cookies[strings.ToLower(strings.TrimSpace(cookie[0]))] = parseCookieValue(strings.TrimSpace(cookie[1])) } } @@ -928,10 +926,6 @@ func (ml *messageList) pop() *message { return msg } -func (ml *messageList) last() *message { - return ml.tail -} - func extractBasicAuthUser(headers map[string]common.NetString) string { const prefix = "Basic " diff --git a/packetbeat/protos/http/http_parser.go b/packetbeat/protos/http/http_parser.go index be4343ea1207..a903460f7728 100644 --- a/packetbeat/protos/http/http_parser.go +++ b/packetbeat/protos/http/http_parser.go @@ -45,7 +45,7 @@ type message struct { cmdlineTuple *common.ProcessTuple direction uint8 - //Request Info + // Request Info requestURI common.NetString method common.NetString statusCode uint16 @@ -187,7 +187,7 @@ func (*parser) parseHTTPLine(s *stream, m *message) (cont, ok, complete bool) { return false, false, false } if bytes.Equal(fline[0:5], constHTTPVersion) { - //RESPONSE + // RESPONSE m.isRequest = false version = fline[5:8] m.statusCode, m.statusPhrase, err = parseResponseStatus(fline[9:]) @@ -289,7 +289,7 @@ func (parser *parser) parseHeaders(s *stream, m *message) (cont, ok, complete bo s.parseOffset = 0 if !m.isRequest && ((100 <= m.statusCode && m.statusCode < 200) || m.statusCode == 204 || m.statusCode == 304) { - //response with a 1xx, 204 , or 304 status code is always terminated + // response with a 1xx, 204 , or 304 status code is always terminated // by the first empty line after the header fields if isDebug { debugf("Terminate response, status code %d", m.statusCode) diff --git a/packetbeat/protos/http/http_test.go b/packetbeat/protos/http/http_test.go index 0fa9077a5ed5..4179a047d562 100644 --- a/packetbeat/protos/http/http_test.go +++ b/packetbeat/protos/http/http_test.go @@ -56,10 +56,6 @@ func (e *eventStore) publish(event beat.Event) { e.events = append(e.events, event) } -func (e *eventStore) empty() bool { - return len(e.events) == 0 -} - func newTestParser(http *httpPlugin, payloads ...string) *testParser { if http == nil { http = httpModForTests(nil) @@ -538,7 +534,7 @@ func TestHttpParser_RequestResponseBody(t *testing.T) { tp.stream.PrepareForNewMessage() tp.stream.message = &message{ts: time.Now()} - msg, ok, complete = tp.parse() + _, ok, complete = tp.parse() assert.True(t, ok) assert.True(t, complete) } @@ -646,17 +642,23 @@ func TestEatBodyChunked(t *testing.T) { st.data = append(st.data, msgs[1]...) cont, ok, complete = parser.parseBodyChunkedStart(st, msg) assert.True(t, cont) + assert.True(t, ok) + assert.False(t, complete) assert.Equal(t, 3, msg.chunkedLength) assert.Equal(t, 0, len(msg.body)) assert.Equal(t, stateBodyChunked, st.parseState) cont, ok, complete = parser.parseBodyChunked(st, msg) assert.True(t, cont) + assert.True(t, ok) + assert.False(t, complete) assert.Equal(t, stateBodyChunkedStart, st.parseState) assert.Equal(t, 3, msg.contentLength) cont, ok, complete = parser.parseBodyChunkedStart(st, msg) assert.True(t, cont) + assert.True(t, ok) + assert.False(t, complete) assert.Equal(t, 3, msg.chunkedLength) assert.Equal(t, 3, msg.contentLength) assert.Equal(t, stateBodyChunked, st.parseState) @@ -672,6 +674,8 @@ func TestEatBodyChunked(t *testing.T) { st.data = append(st.data, msgs[2]...) cont, ok, complete = parser.parseBodyChunked(st, msg) assert.True(t, cont) + assert.True(t, ok) + assert.False(t, complete) assert.Equal(t, 6, msg.contentLength) assert.Equal(t, stateBodyChunkedStart, st.parseState) @@ -729,7 +733,6 @@ func TestEatBodyChunkedWaitCRLF(t *testing.T) { ok, complete = parser.parseBodyChunkedWaitFinalCRLF(st, msg) if ok != true || complete != false { t.Error("Wrong return values", ok, complete) - } st.data = append(st.data, msgs[1]...) @@ -817,13 +820,12 @@ func TestHttpParser_censorPasswordPOST(t *testing.T) { http.parserConfig.sendHeaders = true http.parserConfig.sendAllHeaders = true - data1 := - "POST /users/login HTTP/1.1\r\n" + - "HOST: www.example.com\r\n" + - "Content-Type: application/x-www-form-urlencoded\r\n" + - "Content-Length: 28\r\n" + - "\r\n" + - "username=ME&password=secret\r\n" + data1 := "POST /users/login HTTP/1.1\r\n" + + "HOST: www.example.com\r\n" + + "Content-Type: application/x-www-form-urlencoded\r\n" + + "Content-Length: 28\r\n" + + "\r\n" + + "username=ME&password=secret\r\n" tp := newTestParser(http, data1) msg, ok, complete := tp.parse() @@ -1511,7 +1513,8 @@ func TestHTTP_Encodings(t *testing.T) { gzipDeflateBody := string([]byte{ 0x1f, 0x8b, 0x08, 0x00, 0x65, 0xdb, 0x6a, 0x5b, 0x00, 0x03, 0x3b, 0x7d, 0xe2, 0xbc, 0xe7, 0x13, 0x26, 0x06, 0x00, 0x95, 0xfa, 0x49, 0xbf, 0x07, - 0x00, 0x00, 0x00}) + 0x00, 0x00, 0x00, + }) var store eventStore http := httpModForTests(&store) diff --git a/packetbeat/protos/icmp/config.go b/packetbeat/protos/icmp/config.go index cb3ee28d7f92..4fcdb6667e50 100644 --- a/packetbeat/protos/icmp/config.go +++ b/packetbeat/protos/icmp/config.go @@ -29,8 +29,6 @@ type icmpConfig struct { TransactionTimeout time.Duration `config:"transaction_timeout"` } -var ( - defaultConfig = icmpConfig{ - TransactionTimeout: protos.DefaultTransactionExpiration, - } -) +var defaultConfig = icmpConfig{ + TransactionTimeout: protos.DefaultTransactionExpiration, +} diff --git a/packetbeat/protos/icmp/icmp.go b/packetbeat/protos/icmp/icmp.go index 521bb019ce62..c204b819adbc 100644 --- a/packetbeat/protos/icmp/icmp.go +++ b/packetbeat/protos/icmp/icmp.go @@ -102,7 +102,7 @@ func (icmp *icmpPlugin) init(results protos.Reporter, watcher procs.ProcessesWat } logp.Debug("icmp", "Local IP addresses: %s", icmp.localIps) - var removalListener = func(k common.Key, v common.Value) { + removalListener := func(k common.Key, v common.Value) { icmp.expireTransaction(k.(hashableIcmpTuple), v.(*icmpTransaction)) } @@ -145,7 +145,7 @@ func (icmp *icmpPlugin) ProcessICMPv4( ts: pkt.Ts, Type: typ, code: code, - length: len(icmp4.BaseLayer.Payload), + length: len(icmp4.Payload), } if isRequest(tuple, msg) { @@ -180,7 +180,7 @@ func (icmp *icmpPlugin) ProcessICMPv6( ts: pkt.Ts, Type: typ, code: code, - length: len(icmp6.BaseLayer.Payload), + length: len(icmp6.Payload), } if isRequest(tuple, msg) { @@ -257,14 +257,6 @@ func (icmp *icmpPlugin) isLocalIP(ip net.IP) bool { return false } -func (icmp *icmpPlugin) getTransaction(k hashableIcmpTuple) *icmpTransaction { - v := icmp.transactions.Get(k) - if v != nil { - return v.(*icmpTransaction) - } - return nil -} - func (icmp *icmpPlugin) deleteTransaction(k hashableIcmpTuple) *icmpTransaction { v := icmp.transactions.Delete(k) if v != nil { diff --git a/packetbeat/protos/icmp/tuple_test.go b/packetbeat/protos/icmp/tuple_test.go index 7c9112decb10..b8d09e6753f6 100644 --- a/packetbeat/protos/icmp/tuple_test.go +++ b/packetbeat/protos/icmp/tuple_test.go @@ -79,7 +79,8 @@ func TestIcmpTupleHashable(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 192, 168, 0, 2, 1, 0, 0, 1, - 4} + 4, + } assert.Equal(t, expectedHashable, actualHashable) } diff --git a/packetbeat/protos/memcache/binary.go b/packetbeat/protos/memcache/binary.go index f9db915ce8a9..ee831055317f 100644 --- a/packetbeat/protos/memcache/binary.go +++ b/packetbeat/protos/memcache/binary.go @@ -28,8 +28,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/streambuf" ) -type memcacheMagic uint8 - const ( memcacheMagicRequest = 0x80 memcacheMagicResponse = 0x81 @@ -56,10 +54,11 @@ var binStatsValue = argDef{ serialize: serializeStats, } -var extraValue = makeValueExtra("value") -var extraDelta = makeValueExtra("delta") -var extraInitial = makeValue2Extra("initial") -var extraVerbosity = make32ValueExtra("verbosity") +var ( + extraDelta = makeValueExtra("delta") + extraInitial = makeValue2Extra("initial") + extraVerbosity = make32ValueExtra("verbosity") +) func init() { // define all memcache opcode commands: diff --git a/packetbeat/protos/memcache/config.go b/packetbeat/protos/memcache/config.go index e558c84153dd..dfe01e86e3b0 100644 --- a/packetbeat/protos/memcache/config.go +++ b/packetbeat/protos/memcache/config.go @@ -32,11 +32,9 @@ type memcacheConfig struct { ParseUnknown bool } -var ( - defaultConfig = memcacheConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - UDPTransactionTimeout: protos.DefaultTransactionExpiration, - } -) +var defaultConfig = memcacheConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + UDPTransactionTimeout: protos.DefaultTransactionExpiration, +} diff --git a/packetbeat/protos/memcache/errors.go b/packetbeat/protos/memcache/errors.go index 3b6b5b9ae454..282812a3492d 100644 --- a/packetbeat/protos/memcache/errors.go +++ b/packetbeat/protos/memcache/errors.go @@ -23,9 +23,7 @@ import ( "errors" ) -var ( - errNotImplemented = errors.New("not implemented") -) +var errNotImplemented = errors.New("not implemented") // memcache text parser errors var ( diff --git a/packetbeat/protos/memcache/parse.go b/packetbeat/protos/memcache/parse.go index 2fe774c19e5c..01ce9a05acba 100644 --- a/packetbeat/protos/memcache/parse.go +++ b/packetbeat/protos/memcache/parse.go @@ -25,11 +25,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/streambuf" ) -const ( - codeSpace byte = ' ' - codeTab = '\t' -) - type parserConfig struct { maxValues int maxBytesPerValue int diff --git a/packetbeat/protos/memcache/parse_test.go b/packetbeat/protos/memcache/parse_test.go index 95fdac5bad32..e1ac77160f59 100644 --- a/packetbeat/protos/memcache/parse_test.go +++ b/packetbeat/protos/memcache/parse_test.go @@ -56,8 +56,10 @@ type binValueWriter interface { WriteNetUint64At(uint64, int) error } -type extraFn func(binValueWriter) int -type valueFn func(*streambuf.Buffer, int) int +type ( + extraFn func(binValueWriter) int + valueFn func(*streambuf.Buffer, int) int +) type offsetBinWriter struct { w binValueWriter diff --git a/packetbeat/protos/memcache/plugin_tcp.go b/packetbeat/protos/memcache/plugin_tcp.go index 830a0cd64a55..c16abb3c7128 100644 --- a/packetbeat/protos/memcache/plugin_tcp.go +++ b/packetbeat/protos/memcache/plugin_tcp.go @@ -60,8 +60,6 @@ type messageList struct { tail *message } -const defaultTCPTransDuration uint = 200 - func ensureMemcacheConnection(private protos.ProtocolData) *tcpConnectionData { if private == nil { return &tcpConnectionData{} diff --git a/packetbeat/protos/memcache/text.go b/packetbeat/protos/memcache/text.go index 72b36442c9a5..86baa8d06275 100644 --- a/packetbeat/protos/memcache/text.go +++ b/packetbeat/protos/memcache/text.go @@ -109,12 +109,14 @@ var argStat = argDef{ serialize: serializeStats, } -var argDelta = makeValueArg("delta") -var argSleepUs = makeValueArg("sleep_us") -var argValue = makeValueArg("value") -var argVerbosity = makeValueArg("verbosity") -var argSourceClass = makeIValueArg("source_class") -var argDestClass = makeIValue2Arg("dest_class") +var ( + argDelta = makeValueArg("delta") + argSleepUs = makeValueArg("sleep_us") + argValue = makeValueArg("value") + argVerbosity = makeValueArg("verbosity") + argSourceClass = makeIValueArg("source_class") + argDestClass = makeIValue2Arg("dest_class") +) var argNoReply = argDef{ parse: func(parser *parser, hdr, buf *streambuf.Buffer) error { @@ -297,8 +299,10 @@ func makeDefTextDataMessage( } } -var defTextDataRequest = makeDefTextDataMessage(true) -var defTextDataResponse = makeDefTextDataMessage(false) +var ( + defTextDataRequest = makeDefTextDataMessage(true) + defTextDataResponse = makeDefTextDataMessage(false) +) func loadCommand(name string, code commandCode) textCommandType { return defTextMessage(name, memcacheLoadMsg, code, argMultiKeys) @@ -403,13 +407,6 @@ func makeValueArg(name string) argDef { } } -func makeValue2Arg(name string) argDef { - return argDef{ - parse: textUint64Arg(setValue2), - serialize: serializeValue2(name), - } -} - func makeIValueArg(name string) argDef { return argDef{ parse: func(parser *parser, hdr, buf *streambuf.Buffer) error { @@ -592,7 +589,7 @@ func parseNoReplyArg(buf *streambuf.Buffer) (bool, error) { return false, textArgError(err) } - var noreplyArg = []byte("noreply") + noreplyArg := []byte("noreply") noreply := bytes.HasPrefix(buf.Bytes(), noreplyArg) if !noreply { return false, errExpectedNoReply diff --git a/packetbeat/protos/mongodb/config.go b/packetbeat/protos/mongodb/config.go index e7e2143b6474..c90aeb672909 100644 --- a/packetbeat/protos/mongodb/config.go +++ b/packetbeat/protos/mongodb/config.go @@ -28,12 +28,10 @@ type mongodbConfig struct { MaxDocs int `config:"max_docs"` } -var ( - defaultConfig = mongodbConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - MaxDocLength: 5000, - MaxDocs: 10, - } -) +var defaultConfig = mongodbConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + MaxDocLength: 5000, + MaxDocs: 10, +} diff --git a/packetbeat/protos/mongodb/mongodb.go b/packetbeat/protos/mongodb/mongodb.go index b05ebce91508..0fcc5464b455 100644 --- a/packetbeat/protos/mongodb/mongodb.go +++ b/packetbeat/protos/mongodb/mongodb.go @@ -55,9 +55,7 @@ type transactionKey struct { id int } -var ( - unmatchedRequests = monitoring.NewInt(nil, "mongodb.unmatched_requests") -) +var unmatchedRequests = monitoring.NewInt(nil, "mongodb.unmatched_requests") func init() { protos.Register("mongodb", New) @@ -218,7 +216,6 @@ func (mongodb *mongodbPlugin) handleMongodb( tcptuple *common.TCPTuple, dir uint8, ) { - m.tcpTuple = *tcptuple m.direction = dir m.cmdlineTuple = mongodb.watcher.FindProcessesTupleTCP(tcptuple.IPPort()) @@ -345,11 +342,12 @@ func reconstructQuery(t *transaction, full bool) (query string) { if !full { // remove the actual data. // TODO: review if we need to add other commands here - if t.method == "insert" { + switch t.method { + case "insert": params, err = doc2str(copyMapWithoutKey(t.params, "documents")) - } else if t.method == "update" { + case "update": params, err = doc2str(copyMapWithoutKey(t.params, "updates")) - } else if t.method == "findandmodify" { + case "findandmodify": params, err = doc2str(copyMapWithoutKey(t.params, "update")) } } else { diff --git a/packetbeat/protos/mongodb/mongodb_parser.go b/packetbeat/protos/mongodb/mongodb_parser.go index a5ff5fa06253..1abc6f890f28 100644 --- a/packetbeat/protos/mongodb/mongodb_parser.go +++ b/packetbeat/protos/mongodb/mongodb_parser.go @@ -116,10 +116,26 @@ func mongodbMessageParser(s *stream) (bool, bool) { // see http://docs.mongodb.org/meta-driver/latest/legacy/mongodb-wire-protocol/#op-reply func opReplyParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // ignore flags for now + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } m.event["cursorId"], err = d.readInt64() + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } m.event["startingFrom"], err = d.readInt32() + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } numberReturned, err := d.readInt32() + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } m.event["numberReturned"] = numberReturned debugf("Prepare to read %d document from reply", m.event["numberReturned"]) @@ -128,15 +144,27 @@ func opReplyParse(d *decoder, m *mongodbMessage) (bool, bool) { for i := 0; i < numberReturned; i++ { var document bson.M document, err = d.readDocument() + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } // Check if the result is actually an error if i == 0 { if mongoError, present := document["$err"]; present { m.error, err = doc2str(mongoError) + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } } if writeErrors, present := document["writeErrors"]; present { m.error, err = doc2str(writeErrors) + if err != nil { + logp.Err("An error occurred while parsing OP_REPLY message: %s", err) + return false, false + } } } @@ -144,10 +172,6 @@ func opReplyParse(d *decoder, m *mongodbMessage) (bool, bool) { } m.documents = documents - if err != nil { - logp.Err("An error occurred while parsing OP_REPLY message: %s", err) - return false, false - } return true, true } @@ -163,12 +187,26 @@ func opMsgLegacyParse(d *decoder, m *mongodbMessage) (bool, bool) { func opUpdateParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // always ZERO, a slot reserved in the protocol for future use + if err != nil { + logp.Err("An error occurred while parsing OP_UPDATE message: %s", err) + return false, false + } m.event["fullCollectionName"], err = d.readCStr() + if err != nil { + logp.Err("An error occurred while parsing OP_UPDATE message: %s", err) + return false, false + } _, err = d.readInt32() // ignore flags for now - + if err != nil { + logp.Err("An error occurred while parsing OP_UPDATE message: %s", err) + return false, false + } m.event["selector"], err = d.readDocumentStr() + if err != nil { + logp.Err("An error occurred while parsing OP_UPDATE message: %s", err) + return false, false + } m.event["update"], err = d.readDocumentStr() - if err != nil { logp.Err("An error occurred while parsing OP_UPDATE message: %s", err) return false, false @@ -179,6 +217,10 @@ func opUpdateParse(d *decoder, m *mongodbMessage) (bool, bool) { func opInsertParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // ignore flags for now + if err != nil { + logp.Err("An error occurred while parsing OP_INSERT message: %s", err) + return false, false + } m.event["fullCollectionName"], err = d.readCStr() // TODO parse bson documents @@ -230,11 +272,27 @@ func isDatabaseCommand(key string, val interface{}) bool { func opQueryParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // ignore flags for now + if err != nil { + logp.Err("An error occurred while parsing OP_QUERY message: %s", err) + return false, false + } fullCollectionName, err := d.readCStr() + if err != nil { + logp.Err("An error occurred while parsing OP_QUERY message: %s", err) + return false, false + } m.event["fullCollectionName"] = fullCollectionName m.event["numberToSkip"], err = d.readInt32() + if err != nil { + logp.Err("An error occurred while parsing OP_QUERY message: %s", err) + return false, false + } m.event["numberToReturn"], err = d.readInt32() + if err != nil { + logp.Err("An error occurred while parsing OP_QUERY message: %s", err) + return false, false + } query, err := d.readDocument() if d.i < len(d.in) { @@ -275,10 +333,21 @@ func opQueryParse(d *decoder, m *mongodbMessage) (bool, bool) { func opGetMoreParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // always ZERO, a slot reserved in the protocol for future use + if err != nil { + logp.Err("An error occurred while parsing OP_GET_MORE message: %s", err) + return false, false + } m.event["fullCollectionName"], err = d.readCStr() + if err != nil { + logp.Err("An error occurred while parsing OP_GET_MORE message: %s", err) + return false, false + } m.event["numberToReturn"], err = d.readInt32() + if err != nil { + logp.Err("An error occurred while parsing OP_GET_MORE message: %s", err) + return false, false + } m.event["cursorId"], err = d.readInt64() - if err != nil { logp.Err("An error occurred while parsing OP_GET_MORE message: %s", err) return false, false @@ -288,11 +357,21 @@ func opGetMoreParse(d *decoder, m *mongodbMessage) (bool, bool) { func opDeleteParse(d *decoder, m *mongodbMessage) (bool, bool) { _, err := d.readInt32() // always ZERO, a slot reserved in the protocol for future use + if err != nil { + logp.Err("An error occurred while parsing OP_DELETE message: %s", err) + return false, false + } m.event["fullCollectionName"], err = d.readCStr() + if err != nil { + logp.Err("An error occurred while parsing OP_DELETE message: %s", err) + return false, false + } _, err = d.readInt32() // ignore flags for now - + if err != nil { + logp.Err("An error occurred while parsing OP_DELETE message: %s", err) + return false, false + } m.event["selector"], err = d.readDocumentStr() - if err != nil { logp.Err("An error occurred while parsing OP_DELETE message: %s", err) return false, false @@ -405,7 +484,6 @@ func (d *decoder) readByte() (byte, error) { func (d *decoder) readInt32() (int, error) { b, err := d.readBytes(4) - if err != nil { return 0, err } @@ -418,7 +496,6 @@ func (d *decoder) readInt32() (int, error) { func (d *decoder) readInt64() (int, error) { b, err := d.readBytes(8) - if err != nil { return 0, err } @@ -436,6 +513,9 @@ func (d *decoder) readInt64() (int, error) { func (d *decoder) readDocument() (bson.M, error) { start := d.i documentLength, err := d.readInt32() + if err != nil { + return nil, err + } d.i = start + documentLength if len(d.in) < d.i { return nil, errors.New("document out of bounds") @@ -461,6 +541,9 @@ func doc2str(documentMap interface{}) (string, error) { func (d *decoder) readDocumentStr() (string, error) { documentMap, err := d.readDocument() + if err != nil { + return "", err + } document, err := doc2str(documentMap) return document, err } diff --git a/packetbeat/protos/mongodb/mongodb_test.go b/packetbeat/protos/mongodb/mongodb_test.go index ece0e1cf4aa3..a1415dfa0a25 100644 --- a/packetbeat/protos/mongodb/mongodb_test.go +++ b/packetbeat/protos/mongodb/mongodb_test.go @@ -170,6 +170,7 @@ func TestSimpleFindLimit1_split(t *testing.T) { "1b000000013000e6762ff7c97652c001" + "3100d5b14ae9996c4440000273747265" + "657400100000004d6f72726973205061") + assert.NoError(t, err) respData2, err := hex.DecodeString( "726b2041766500027a6970636f646500" + @@ -183,6 +184,7 @@ func TestSimpleFindLimit1_split(t *testing.T) { "0000000964617465000044510a410100" + "00026772616465000200000041001073" + "636f72650006000000000332002b0000") + assert.NoError(t, err) respData3, err := hex.DecodeString( "00096461746500009cda693c01000002" + diff --git a/packetbeat/protos/mysql/config.go b/packetbeat/protos/mysql/config.go index d53429c3a2cd..0c634b982913 100644 --- a/packetbeat/protos/mysql/config.go +++ b/packetbeat/protos/mysql/config.go @@ -31,13 +31,11 @@ type mysqlConfig struct { StatementTimeout time.Duration `config:"statement_timeout"` } -var ( - defaultConfig = mysqlConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - MaxRowLength: 1024, - MaxRows: 10, - StatementTimeout: 3600 * time.Second, - } -) +var defaultConfig = mysqlConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + MaxRowLength: 1024, + MaxRows: 10, + StatementTimeout: 3600 * time.Second, +} diff --git a/packetbeat/protos/mysql/mysql.go b/packetbeat/protos/mysql/mysql.go index 1553bdf9901e..49ca17ece858 100644 --- a/packetbeat/protos/mysql/mysql.go +++ b/packetbeat/protos/mysql/mysql.go @@ -62,8 +62,6 @@ type mysqlMessage struct { numberOfRows int numberOfFields int size uint64 - fields []string - rows [][]string tables string isOK bool affectedRows uint64 @@ -83,7 +81,6 @@ type mysqlMessage struct { statementID int numberOfParams int - params []string } type mysqlTransaction struct { @@ -337,7 +334,7 @@ func mysqlMessageParser(s *mysqlStream) (bool, bool) { return true, false } - s.parseOffset += 4 //header + s.parseOffset += 4 // header s.parseOffset += int(m.packetLength) m.end = s.parseOffset if m.isRequest { @@ -347,7 +344,6 @@ func mysqlMessageParser(s *mysqlStream) (bool, bool) { } else { m.query = string(s.data[m.start+5 : m.end]) } - } else if m.isOK { // affected rows affectedRows, off, complete, err := readLinteger(s.data, m.start+5) @@ -475,7 +471,7 @@ func mysqlMessageParser(s *mysqlStream) (bool, bool) { return true, false } - s.parseOffset += 4 //header + s.parseOffset += 4 // header if s.data[s.parseOffset] == 0xfe { logp.Debug("mysqldetailed", "Received EOF packet") @@ -553,8 +549,8 @@ func (mysql *mysqlPlugin) ConnectionTimeout() time.Duration { } func (mysql *mysqlPlugin) Parse(pkt *protos.Packet, tcptuple *common.TCPTuple, - dir uint8, private protos.ProtocolData) protos.ProtocolData { - + dir uint8, private protos.ProtocolData, +) protos.ProtocolData { defer logp.Recover("ParseMysql exception") priv := mysqlPrivateData{} @@ -613,8 +609,8 @@ func (mysql *mysqlPlugin) Parse(pkt *protos.Packet, tcptuple *common.TCPTuple, } func (mysql *mysqlPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { defer logp.Recover("GapInStream(mysql) exception") if private == nil { @@ -642,16 +638,16 @@ func (mysql *mysqlPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, } func (mysql *mysqlPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { // TODO: check if we have data pending and either drop it to free // memory or send it up the stack. return private } func handleMysql(mysql *mysqlPlugin, m *mysqlMessage, tcptuple *common.TCPTuple, - dir uint8, rawMsg []byte) { - + dir uint8, rawMsg []byte, +) { m.tcpTuple = *tcptuple m.direction = dir m.cmdlineTuple = mysql.watcher.FindProcessesTupleTCP(tcptuple.IPPort()) @@ -689,9 +685,10 @@ func (mysql *mysqlPlugin) receivedMysqlRequest(msg *mysqlMessage) { trans.statementID = msg.statementID stmts := mysql.getStmtsMap(msg.tcpTuple.Hashable()) if stmts == nil { - if msg.typ == mysqlCmdStmtExecute { + switch msg.typ { + case mysqlCmdStmtExecute: trans.query = "Request Execute Statement" - } else if msg.typ == mysqlCmdStmtClose { + case mysqlCmdStmtClose: trans.query = "Request Close Statement" } trans.notes = append(trans.notes, "The actual query being used is unknown") @@ -699,7 +696,8 @@ func (mysql *mysqlPlugin) receivedMysqlRequest(msg *mysqlMessage) { trans.bytesIn = msg.size return } - if msg.typ == mysqlCmdStmtExecute { + switch msg.typ { + case mysqlCmdStmtExecute: if value, ok := stmts[trans.statementID]; ok { trans.query = value.query // parse parameters @@ -711,7 +709,7 @@ func (mysql *mysqlPlugin) receivedMysqlRequest(msg *mysqlMessage) { trans.bytesIn = msg.size return } - } else if msg.typ == mysqlCmdStmtClose { + case mysqlCmdStmtClose: delete(stmts, trans.statementID) trans.query = "CmdStmtClose" mysql.transactions.Delete(tuple.Hashable()) @@ -899,7 +897,7 @@ func (mysql *mysqlPlugin) parseMysqlExecuteStatement(data []byte, stmtdata *mysq valueString := strconv.Itoa(int(binary.LittleEndian.Uint32(data[paramOffset:]))) paramString = append(paramString, valueString) paramOffset += 4 - //FIELD_TYPE_FLOAT + // FIELD_TYPE_FLOAT case 0x04: paramString = append(paramString, "TYPE_FLOAT") paramOffset += 4 @@ -1012,19 +1010,19 @@ func (mysql *mysqlPlugin) parseMysqlResponse(data []byte) ([]string, [][]string) return []string{}, [][]string{} } - fields := []string{} - rows := [][]string{} - if len(data) < 5 { - logp.Warn("Invalid response: data less than 4 bytes") + logp.Warn("Invalid response: data less than 5 bytes") return []string{}, [][]string{} } - if data[4] == 0x00 { + fields := []string{} + rows := [][]string{} + switch data[4] { + case 0x00: // OK response - } else if data[4] == 0xff { + case 0xff: // Error response - } else { + default: offset := 5 logp.Debug("mysql", "Data len: %d", len(data)) @@ -1100,7 +1098,7 @@ func (mysql *mysqlPlugin) parseMysqlResponse(data []byte) ([]string, [][]string) if data[offset+4] == 0xfe { // EOF - offset += length + 4 + offset += length + 4 // ineffassign break } diff --git a/packetbeat/protos/mysql/mysql_test.go b/packetbeat/protos/mysql/mysql_test.go index 309fd45cb0f6..dd9423990738 100644 --- a/packetbeat/protos/mysql/mysql_test.go +++ b/packetbeat/protos/mysql/mysql_test.go @@ -49,10 +49,6 @@ func (e *eventStore) publish(event beat.Event) { e.events = append(e.events, event) } -func (e *eventStore) empty() bool { - return len(e.events) == 0 -} - func mysqlModForTests(store *eventStore) *mysqlPlugin { callback := func(beat.Event) {} if store != nil { @@ -110,6 +106,7 @@ func TestMySQLParser_simpleRequest(t *testing.T) { t.Errorf("Wrong message size %d", stream.message.size) } } + func TestMySQLParser_OKResponse(t *testing.T) { data := []byte( "0700000100010401000000") @@ -363,11 +360,11 @@ func TestParseMySQL_simpleUpdateResponse(t *testing.T) { var tuple common.TCPTuple var private mysqlPrivateData - var countHandleMysql = 0 + countHandleMysql := 0 mysql.handleMysql = func(mysql *mysqlPlugin, m *mysqlMessage, tcp *common.TCPTuple, - dir uint8, raw_msg []byte) { - + dir uint8, raw_msg []byte, + ) { countHandleMysql++ } @@ -404,11 +401,11 @@ func TestParseMySQL_threeResponses(t *testing.T) { var tuple common.TCPTuple var private mysqlPrivateData - var countHandleMysql = 0 + countHandleMysql := 0 mysql.handleMysql = func(mysql *mysqlPlugin, m *mysqlMessage, tcptuple *common.TCPTuple, - dir uint8, raw_msg []byte) { - + dir uint8, raw_msg []byte, + ) { countHandleMysql++ } @@ -431,7 +428,6 @@ func TestParseMySQL_splitResponse(t *testing.T) { "3b00000303646566086d696e697477697404706f737404706f73740d706f73745f757365726e616d6508757365726e616d650c2100f0000000fd0000000000" + "3500000403646566086d696e697477697404706f737404706f73740a706f73745f7469746c65057469746c650c2100f0000000fd0000000000" + "3300000503646566086d696e697477697404706f737404706f737409706f73745f626f647904626f64790c2100fdff0200fc1000000000") - if err != nil { t.Errorf("Failed to decode string") } @@ -446,11 +442,11 @@ func TestParseMySQL_splitResponse(t *testing.T) { var tuple common.TCPTuple var private mysqlPrivateData - var countHandleMysql = 0 + countHandleMysql := 0 mysql.handleMysql = func(mysql *mysqlPlugin, m *mysqlMessage, tcptuple *common.TCPTuple, - dir uint8, raw_msg []byte) { - + dir uint8, raw_msg []byte, + ) { countHandleMysql++ } @@ -623,12 +619,18 @@ func Test_parseMysqlResponse_invalid(t *testing.T) { {0x05, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00}, {0x05, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}, {0x05, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}, - {0x05, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0x00}, - {0x15, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x01}, - {0x15, 0x00, 0x00, 0x01, 0x01, 0x05, 0x15, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x01, 0x00}, + { + 0x05, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, + }, + { + 0x15, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, + }, + { + 0x15, 0x00, 0x00, 0x01, 0x01, 0x05, 0x15, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, + }, } for _, input := range tests { @@ -638,12 +640,14 @@ func Test_parseMysqlResponse_invalid(t *testing.T) { } tests = [][]byte{ - {0x15, 0x00, 0x00, 0x01, 0x01, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xfe, 0x00, 0x01, //field + { + 0x15, 0x00, 0x00, 0x01, 0x01, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xfe, 0x00, 0x01, // field 0x01, 0x00, 0x00, 0x00, 0xfe, // EOF }, - {0x15, 0x00, 0x00, 0x01, 0x01, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xfe, 0x00, 0x01, //field + { + 0x15, 0x00, 0x00, 0x01, 0x01, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xfe, 0x00, 0x01, // field 0x01, 0x00, 0x00, 0x00, 0xfe, // EOF 0x00, 0x00, }, @@ -668,7 +672,7 @@ func Test_PreparedStatement(t *testing.T) { packet := protos.Packet{Payload: rawData} var private protos.ProtocolData - private = mysql.Parse(&packet, tcpTuple, dir, private) + mysql.Parse(&packet, tcpTuple, dir, private) } send(tcp.TCPDirectionOriginal, "c00000001673656c6563742064697374696e637420636f756e742864697374696e63742070757263686173656465305f2e69642920617320636f6c5f305f305f2066726f6d2070757263686173655f64656d616e642070757263686173656465305f2077686572652070757263686173656465305f2e636861696e5f6d61737465723d3f20616e642070757263686173656465305f2e6372656174655f74696d653e3d3f20616e642070757263686173656465305f2e6372656174655f74696d653c3d3f") diff --git a/packetbeat/protos/nfs/config.go b/packetbeat/protos/nfs/config.go index 639bdad525d6..e23672024c87 100644 --- a/packetbeat/protos/nfs/config.go +++ b/packetbeat/protos/nfs/config.go @@ -27,10 +27,8 @@ type rpcConfig struct { config.ProtocolCommon `config:",inline"` } -var ( - defaultConfig = rpcConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: 1 * time.Minute, - }, - } -) +var defaultConfig = rpcConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: 1 * time.Minute, + }, +} diff --git a/packetbeat/protos/nfs/request_handler.go b/packetbeat/protos/nfs/request_handler.go index fea417f4dc13..1225f9f6012f 100644 --- a/packetbeat/protos/nfs/request_handler.go +++ b/packetbeat/protos/nfs/request_handler.go @@ -41,9 +41,7 @@ var acceptStatus = [...]string{ "system_err", } -var ( - unmatchedRequests = monitoring.NewInt(nil, "nfs.unmatched_requests") -) +var unmatchedRequests = monitoring.NewInt(nil, "nfs.unmatched_requests") // called by Cache, when re reply seen within expected time window func (r *rpc) handleExpiredPacket(nfs *nfs) { diff --git a/packetbeat/protos/nfs/rpc.go b/packetbeat/protos/nfs/rpc.go index 9cde7ab5aac8..64fffe476060 100644 --- a/packetbeat/protos/nfs/rpc.go +++ b/packetbeat/protos/nfs/rpc.go @@ -126,7 +126,6 @@ func (r *rpc) Parse( dir uint8, private protos.ProtocolData, ) protos.ProtocolData { - defer logp.Recover("ParseRPC exception") conn := ensureRPCConnection(private) @@ -140,8 +139,8 @@ func (r *rpc) Parse( // Called when the FIN flag is seen in the TCP stream. func (r *rpc) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { defer logp.Recover("ReceivedFinRpc exception") // forced by TCP interface @@ -151,8 +150,8 @@ func (r *rpc) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, // Called when a packets are missing from the tcp // stream. func (r *rpc) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { defer logp.Recover("GapInRpcStream exception") // forced by TCP interface @@ -199,7 +198,6 @@ func (r *rpc) handleRPCFragment( tcptuple *common.TCPTuple, dir uint8, ) *rpcConnectionData { - st := conn.streams[dir] if st == nil { st = newStream(pkt, tcptuple) diff --git a/packetbeat/protos/nfs/xdr.go b/packetbeat/protos/nfs/xdr.go index de63fc755a26..168fb274cfda 100644 --- a/packetbeat/protos/nfs/xdr.go +++ b/packetbeat/protos/nfs/xdr.go @@ -40,24 +40,12 @@ func (r *xdr) size() int { return len(r.data) } -func (r *xdr) getInt() int32 { - i := int32(binary.BigEndian.Uint32(r.data[r.offset : r.offset+4])) - r.offset += 4 - return int32(i) -} - func (r *xdr) getUInt() uint32 { i := uint32(binary.BigEndian.Uint32(r.data[r.offset : r.offset+4])) r.offset += 4 return i } -func (r *xdr) getHyper() int64 { - i := int64(binary.BigEndian.Uint64(r.data[r.offset : r.offset+8])) - r.offset += 8 - return i -} - func (r *xdr) getUHyper() uint64 { i := uint64(binary.BigEndian.Uint64(r.data[r.offset : r.offset+8])) r.offset += 8 diff --git a/packetbeat/protos/pgsql/config.go b/packetbeat/protos/pgsql/config.go index 54a9a1b9e2eb..13c115314093 100644 --- a/packetbeat/protos/pgsql/config.go +++ b/packetbeat/protos/pgsql/config.go @@ -28,12 +28,10 @@ type pgsqlConfig struct { MaxRows int `config:"max_rows"` } -var ( - defaultConfig = pgsqlConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - MaxRowLength: 1024, - MaxRows: 10, - } -) +var defaultConfig = pgsqlConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + MaxRowLength: 1024, + MaxRows: 10, +} diff --git a/packetbeat/protos/pgsql/parse.go b/packetbeat/protos/pgsql/parse.go index a7bcdb44770a..9a302f99a18b 100644 --- a/packetbeat/protos/pgsql/parse.go +++ b/packetbeat/protos/pgsql/parse.go @@ -158,7 +158,7 @@ func (pgsql *pgsqlPlugin) parseSimpleQuery(s *pgsqlStream, length int) (bool, bo m.start = s.parseOffset m.isRequest = true - s.parseOffset++ //type + s.parseOffset++ // type s.parseOffset += length m.end = s.parseOffset m.size = uint64(m.end - m.start) @@ -190,8 +190,8 @@ func (pgsql *pgsqlPlugin) parseRowDescription(s *pgsqlStream, length int) (bool, } pgsql.detailf("Fields: %s", m.fields) - s.parseOffset++ //type - s.parseOffset += length //length + s.parseOffset++ // type + s.parseOffset += length // length s.parseState = pgsqlGetDataState return pgsql.parseMessageData(s) } @@ -238,7 +238,7 @@ func (pgsql *pgsqlPlugin) parseCommandComplete(s *pgsqlStream, length int) (bool m.isOK = true m.toExport = true - s.parseOffset++ //type + s.parseOffset++ // type name, err := pgsqlString(s.data[s.parseOffset+4:], length-4) if err != nil { return false, false @@ -276,10 +276,10 @@ func (pgsql *pgsqlPlugin) parseErrorResponse(s *pgsqlStream, length int) (bool, m.isError = true m.toExport = true - s.parseOffset++ //type + s.parseOffset++ // type pgsql.parseError(s, s.data[s.parseOffset+4:s.parseOffset+length]) - s.parseOffset += length //length + s.parseOffset += length // length m.end = s.parseOffset m.size = uint64(m.end - m.start) @@ -294,7 +294,7 @@ func (pgsql *pgsqlPlugin) parseExtReq(s *pgsqlStream, length int) (bool, bool) { m.start = s.parseOffset m.isRequest = true - s.parseOffset++ //type + s.parseOffset++ // type s.parseOffset += length m.end = s.parseOffset m.size = uint64(m.end - m.start) @@ -326,7 +326,7 @@ func (pgsql *pgsqlPlugin) parseExtResp(s *pgsqlStream, length int) (bool, bool) m.isOK = true m.toExport = true - s.parseOffset++ //type + s.parseOffset++ // type s.parseOffset += length pgsql.detailf("Parse completion in an extended query response") s.parseState = pgsqlGetDataState @@ -336,7 +336,7 @@ func (pgsql *pgsqlPlugin) parseExtResp(s *pgsqlStream, length int) (bool, bool) func (pgsql *pgsqlPlugin) parseSkipMessage(s *pgsqlStream, length int) (bool, bool) { // TODO: add info from NoticeResponse in case there are warning messages for a query // ignore command - s.parseOffset++ //type + s.parseOffset++ // type s.parseOffset += length m := s.message @@ -615,21 +615,21 @@ func (pgsql *pgsqlPlugin) parseMessageExtendedQuery(s *pgsqlStream) (bool, bool) // skip type s.parseOffset++ s.parseOffset += length - //TODO: pgsql.parseBind(s) + // TODO: pgsql.parseBind(s) case 'D': // Bind -> Describe // skip type s.parseOffset++ s.parseOffset += length - //TODO: pgsql.parseDescribe(s) + // TODO: pgsql.parseDescribe(s) case 'E': // Bind(or Describe) -> Execute // skip type s.parseOffset++ s.parseOffset += length - //TODO: pgsql.parseExecute(s) + // TODO: pgsql.parseExecute(s) case 'S': // Execute -> Sync diff --git a/packetbeat/protos/pgsql/pgsql.go b/packetbeat/protos/pgsql/pgsql.go index 5ad6f6e305a8..20ad2fc5461a 100644 --- a/packetbeat/protos/pgsql/pgsql.go +++ b/packetbeat/protos/pgsql/pgsql.go @@ -126,13 +126,9 @@ const ( cancelRequest ) -var ( - errInvalidLength = errors.New("invalid length") -) +var errInvalidLength = errors.New("invalid length") -var ( - unmatchedResponses = monitoring.NewInt(nil, "pgsql.unmatched_responses") -) +var unmatchedResponses = monitoring.NewInt(nil, "pgsql.unmatched_responses") func init() { protos.Register("pgsql", New) @@ -240,8 +236,8 @@ func (pgsql *pgsqlPlugin) ConnectionTimeout() time.Duration { } func (pgsql *pgsqlPlugin) Parse(pkt *protos.Packet, tcptuple *common.TCPTuple, - dir uint8, private protos.ProtocolData) protos.ProtocolData { - + dir uint8, private protos.ProtocolData, +) protos.ProtocolData { defer logp.Recover("ParsePgsql exception") priv := pgsqlPrivateData{} @@ -334,8 +330,8 @@ func messageHasEnoughData(msg *pgsqlMessage) bool { // Called when there's a drop packet func (pgsql *pgsqlPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { defer logp.Recover("GapInPgsqlStream exception") if private == nil { @@ -378,8 +374,8 @@ func (pgsql *pgsqlPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, } var handlePgsql = func(pgsql *pgsqlPlugin, m *pgsqlMessage, tcptuple *common.TCPTuple, - dir uint8, raw_msg []byte) { - + dir uint8, raw_msg []byte, +) { m.tcpTuple = *tcptuple m.direction = dir m.cmdlineTuple = pgsql.watcher.FindProcessesTupleTCP(tcptuple.IPPort()) @@ -433,7 +429,7 @@ func (pgsql *pgsqlPlugin) receivedPgsqlRequest(msg *pgsqlMessage) { func (pgsql *pgsqlPlugin) receivedPgsqlResponse(msg *pgsqlMessage) { tuple := msg.tcpTuple transList := pgsql.getTransaction(tuple.Hashable()) - if transList == nil || len(transList) == 0 { + if len(transList) == 0 { pgsql.debugf("Response from unknown transaction. Ignoring.") unmatchedResponses.Add(1) return @@ -511,8 +507,8 @@ func (pgsql *pgsqlPlugin) publishTransaction(t *pgsqlTransaction) { } func (pgsql *pgsqlPlugin) removeTransaction(transList []*pgsqlTransaction, - tuple common.TCPTuple, index int) *pgsqlTransaction { - + tuple common.TCPTuple, index int, +) *pgsqlTransaction { trans := transList[index] transList = append(transList[:index], transList[index+1:]...) if len(transList) == 0 { diff --git a/packetbeat/protos/pgsql/pgsql_test.go b/packetbeat/protos/pgsql/pgsql_test.go index 328b31e28c26..82075eaacae1 100644 --- a/packetbeat/protos/pgsql/pgsql_test.go +++ b/packetbeat/protos/pgsql/pgsql_test.go @@ -46,10 +46,6 @@ func (e *eventStore) publish(event beat.Event) { e.events = append(e.events, event) } -func (e *eventStore) empty() bool { - return len(e.events) == 0 -} - func pgsqlModForTests(store *eventStore) *pgsqlPlugin { callback := func(beat.Event) {} if store != nil { @@ -234,11 +230,11 @@ func TestPgsqlParser_threeResponses(t *testing.T) { } var tuple common.TCPTuple var private pgsqlPrivateData - var countHandlePgsql = 0 + countHandlePgsql := 0 pgsql.handlePgsql = func(pgsql *pgsqlPlugin, m *pgsqlMessage, tcptuple *common.TCPTuple, - dir uint8, raw_msg []byte) { - + dir uint8, raw_msg []byte, + ) { countHandlePgsql++ } diff --git a/packetbeat/protos/protos.go b/packetbeat/protos/protos.go index e0343a0ee87c..39dc09d8b7d7 100644 --- a/packetbeat/protos/protos.go +++ b/packetbeat/protos/protos.go @@ -79,7 +79,6 @@ type Protocols interface { BpfFilter(withVlans bool, withICMP bool) string GetTCP(proto Protocol) TCPPlugin GetUDP(proto Protocol) UDPPlugin - GetAllTCP() map[Protocol]TCPPlugin GetAllUDP() map[Protocol]UDPPlugin diff --git a/packetbeat/protos/protos_test.go b/packetbeat/protos/protos_test.go index 22269a192d2d..b3c1a912069f 100644 --- a/packetbeat/protos/protos_test.go +++ b/packetbeat/protos/protos_test.go @@ -70,9 +70,7 @@ func (proto *UDPProtocol) GetPorts() []int { return proto.Ports } -func (proto *UDPProtocol) ParseUDP(pkt *Packet) { - return -} +func (proto *UDPProtocol) ParseUDP(pkt *Packet) {} type TCPUDPProtocol TestProtocol @@ -99,9 +97,7 @@ func (proto *TCPUDPProtocol) GapInStream(tcptuple *common.TCPTuple, dir uint8, return private, true } -func (proto *TCPUDPProtocol) ParseUDP(pkt *Packet) { - return -} +func (proto *TCPUDPProtocol) ParseUDP(pkt *Packet) {} func (proto *TCPUDPProtocol) ConnectionTimeout() time.Duration { return 0 } diff --git a/packetbeat/protos/redis/config.go b/packetbeat/protos/redis/config.go index beb1caed2e2f..a1fd48f4149c 100644 --- a/packetbeat/protos/redis/config.go +++ b/packetbeat/protos/redis/config.go @@ -27,14 +27,12 @@ type redisConfig struct { QueueLimits MessageQueueConfig `config:",inline"` } -var ( - defaultConfig = redisConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - QueueLimits: MessageQueueConfig{ - MaxBytes: 1024 * 1024, - MaxMessages: 20000, - }, - } -) +var defaultConfig = redisConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + QueueLimits: MessageQueueConfig{ + MaxBytes: 1024 * 1024, + MaxMessages: 20000, + }, +} diff --git a/packetbeat/protos/redis/redis.go b/packetbeat/protos/redis/redis.go index 23dd1ad86966..a219e8a14f95 100644 --- a/packetbeat/protos/redis/redis.go +++ b/packetbeat/protos/redis/redis.go @@ -140,6 +140,7 @@ func (redis *redisPlugin) Parse( } return conn } + func (redis *redisPlugin) newConnectionData() *redisConnectionData { return &redisConnectionData{ requests: NewMessageQueue(redis.queueConfig), @@ -171,7 +172,6 @@ func (redis *redisPlugin) doParse( tcptuple *common.TCPTuple, dir uint8, ) *redisConnectionData { - st := conn.streams[dir] if st == nil { st = newStream(pkt.Ts, tcptuple) @@ -339,8 +339,8 @@ func (redis *redisPlugin) newTransaction(requ, resp *redisMessage) beat.Event { } func (redis *redisPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { // tsg: being packet loss tolerant is probably not very useful for Redis, // because most requests/response tend to fit in a single packet. @@ -348,8 +348,8 @@ func (redis *redisPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, } func (redis *redisPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { // TODO: check if we have pending data that we can send up the stack return private diff --git a/packetbeat/protos/sip/config.go b/packetbeat/protos/sip/config.go index 58a92606e80d..309558a225ff 100644 --- a/packetbeat/protos/sip/config.go +++ b/packetbeat/protos/sip/config.go @@ -29,13 +29,11 @@ type config struct { KeepOriginal bool `config:"keep_original"` } -var ( - defaultConfig = config{ - ProtocolCommon: cfg.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - ParseAuthorization: true, - ParseBody: true, - KeepOriginal: true, - } -) +var defaultConfig = config{ + ProtocolCommon: cfg.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + ParseAuthorization: true, + ParseBody: true, + KeepOriginal: true, +} diff --git a/packetbeat/protos/sip/parser.go b/packetbeat/protos/sip/parser.go index 8d49ad617427..db63f05b4292 100644 --- a/packetbeat/protos/sip/parser.go +++ b/packetbeat/protos/sip/parser.go @@ -269,8 +269,7 @@ func parseVersion(s []byte) (uint8, uint8, error) { func (parser *parser) parseHeaders(pi *parsingInfo, m *message) error { // check if it isn't headers end yet with /r/n/r/n - if !(len(pi.data)-pi.parseOffset >= 2 && - bytes.Equal(pi.data[pi.parseOffset:pi.parseOffset+2], constCRLF)) { + if len(pi.data)-pi.parseOffset < 2 || !bytes.Equal(pi.data[pi.parseOffset:pi.parseOffset+2], constCRLF) { offset, err := parser.parseHeader(m, pi.data[pi.parseOffset:]) if err != nil { return err diff --git a/packetbeat/protos/tcp/tcp.go b/packetbeat/protos/tcp/tcp.go index e9db7b948972..51ac46346a08 100644 --- a/packetbeat/protos/tcp/tcp.go +++ b/packetbeat/protos/tcp/tcp.go @@ -61,9 +61,7 @@ type Processor interface { Process(flow *flows.FlowID, hdr *layers.TCP, pkt *protos.Packet) } -var ( - droppedBecauseOfGaps = monitoring.NewInt(nil, "tcp.dropped_because_of_gaps") -) +var droppedBecauseOfGaps = monitoring.NewInt(nil, "tcp.dropped_because_of_gaps") type seqCompare int @@ -271,7 +269,8 @@ func (tcp *TCP) getStream(pkt *protos.Packet) (stream TCPStream, created bool) { id: tcp.getID(), tuple: &pkt.Tuple, protocol: protocol, - tcp: tcp} + tcp: tcp, + } conn.tcptuple = common.TCPTupleFromIPPort(conn.tuple, conn.id) tcp.streams.PutWithTimeout(pkt.Tuple.Hashable(), conn, timeout) return TCPStream{conn: conn, dir: TCPDirectionOriginal}, true @@ -289,16 +288,12 @@ func tcpSeqCompare(seq1, seq2 uint32) seqCompare { } } -func tcpSeqBefore(seq1 uint32, seq2 uint32) bool { - return int32(seq1-seq2) < 0 -} - func tcpSeqBeforeEq(seq1 uint32, seq2 uint32) bool { return int32(seq1-seq2) <= 0 } func buildPortsMap(plugins map[protos.Protocol]protos.TCPPlugin) (map[uint16]protos.Protocol, error) { - var res = map[uint16]protos.Protocol{} + res := map[uint16]protos.Protocol{} for proto, protoPlugin := range plugins { for _, port := range protoPlugin.GetPorts() { diff --git a/packetbeat/protos/tcp/tcp_test.go b/packetbeat/protos/tcp/tcp_test.go index 9dd910799b63..5678924a7d6a 100644 --- a/packetbeat/protos/tcp/tcp_test.go +++ b/packetbeat/protos/tcp/tcp_test.go @@ -41,9 +41,7 @@ const ( ClientIP = "10.0.0.1" ) -var ( - httpProtocol, mysqlProtocol, redisProtocol protos.Protocol -) +var httpProtocol, mysqlProtocol, redisProtocol protos.Protocol func init() { new := func(_ bool, _ protos.Reporter, _ procs.ProcessesWatcher, _ *common.Config) (protos.Plugin, error) { @@ -199,7 +197,7 @@ func (p protocols) GetUDP(proto protos.Protocol) protos.UDPPlugin { retur func (p protocols) GetAll() map[protos.Protocol]protos.Plugin { return nil } func (p protocols) GetAllTCP() map[protos.Protocol]protos.TCPPlugin { return p.tcp } func (p protocols) GetAllUDP() map[protos.Protocol]protos.UDPPlugin { return nil } -func (p protocols) Register(proto protos.Protocol, plugin protos.Plugin) { return } +func (p protocols) Register(proto protos.Protocol, plugin protos.Plugin) {} func TestTCSeqPayload(t *testing.T) { type segment struct { @@ -213,7 +211,8 @@ func TestTCSeqPayload(t *testing.T) { expectedGaps int expectedState []byte }{ - {"No overlap", + { + "No overlap", []segment{ {1, []byte{1, 2, 3, 4, 5}}, {6, []byte{6, 7, 8, 9, 10}}, @@ -221,7 +220,8 @@ func TestTCSeqPayload(t *testing.T) { 0, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, }, - {"Gap drop state", + { + "Gap drop state", []segment{ {1, []byte{1, 2, 3, 4}}, {15, []byte{5, 6, 7, 8}}, @@ -229,7 +229,8 @@ func TestTCSeqPayload(t *testing.T) { 10, []byte{5, 6, 7, 8}, }, - {"ACK same sequence number", + { + "ACK same sequence number", []segment{ {1, []byte{1, 2}}, {3, nil}, @@ -239,7 +240,8 @@ func TestTCSeqPayload(t *testing.T) { 0, []byte{1, 2, 3, 4, 5, 6}, }, - {"ACK same sequence number 2", + { + "ACK same sequence number 2", []segment{ {1, nil}, {2, nil}, @@ -253,7 +255,8 @@ func TestTCSeqPayload(t *testing.T) { 0, []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, - {"Overlap, first segment bigger", + { + "Overlap, first segment bigger", []segment{ {1, []byte{1, 2}}, {3, []byte{3, 4}}, @@ -263,7 +266,8 @@ func TestTCSeqPayload(t *testing.T) { 0, []byte{1, 2, 3, 4, 5, 6}, }, - {"Overlap, second segment bigger", + { + "Overlap, second segment bigger", []segment{ {1, []byte{1, 2}}, {3, []byte{3}}, @@ -273,7 +277,8 @@ func TestTCSeqPayload(t *testing.T) { 0, []byte{1, 2, 3, 4, 5, 6}, }, - {"Overlap, covered", + { + "Overlap, covered", []segment{ {1, []byte{1, 2, 3, 4}}, {2, []byte{2, 3}}, diff --git a/packetbeat/protos/thrift/config.go b/packetbeat/protos/thrift/config.go index f687da9ac0c1..0d946a02438f 100644 --- a/packetbeat/protos/thrift/config.go +++ b/packetbeat/protos/thrift/config.go @@ -34,16 +34,14 @@ type thriftConfig struct { IdlFiles []string `config:"idl_files"` } -var ( - defaultConfig = thriftConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - StringMaxSize: 200, - CollectionMaxSize: 15, - DropAfterNStructFields: 500, - TransportType: "socket", - ProtocolType: "binary", - CaptureReply: true, - } -) +var defaultConfig = thriftConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + StringMaxSize: 200, + CollectionMaxSize: 15, + DropAfterNStructFields: 500, + TransportType: "socket", + ProtocolType: "binary", + CaptureReply: true, +} diff --git a/packetbeat/protos/thrift/thrift.go b/packetbeat/protos/thrift/thrift.go index d9778031d766..04c73747f7fe 100644 --- a/packetbeat/protos/thrift/thrift.go +++ b/packetbeat/protos/thrift/thrift.go @@ -656,8 +656,8 @@ func (thrift *thriftPlugin) readStruct(data []byte) (value string, ok bool, comp } func (thrift *thriftPlugin) formatStruct(fields []thriftField, resolveNames bool, - fieldnames []*string) string { - + fieldnames []*string, +) string { toJoin := []string{} for i, field := range fields { if i == thrift.collectionMaxSize { @@ -746,7 +746,7 @@ func (thrift *thriftPlugin) readField(s *thriftStream) (ok bool, complete bool, func (thrift *thriftPlugin) messageParser(s *thriftStream) (bool, bool) { var ok, complete bool - var m = s.message + m := s.message logp.Debug("thriftdetailed", "messageParser called parseState=%v offset=%v", s.parseState, s.parseOffset) @@ -860,7 +860,7 @@ func (stream *thriftStream) prepareForNewMessage(flush bool) { } else { stream.data = stream.data[stream.parseOffset:] } - //logp.Debug("thrift", "remaining data: [%s]", stream.data) + // logp.Debug("thrift", "remaining data: [%s]", stream.data) stream.parseOffset = 0 stream.message = nil stream.parseState = thriftStartState @@ -871,8 +871,8 @@ type thriftPrivateData struct { } func (thrift *thriftPlugin) messageComplete(tcptuple *common.TCPTuple, dir uint8, - stream *thriftStream, priv *thriftPrivateData) { - + stream *thriftStream, priv *thriftPrivateData, +) { flush := false if stream.message.isRequest { @@ -906,7 +906,6 @@ func (thrift *thriftPlugin) messageComplete(tcptuple *common.TCPTuple, dir uint8 // and reset message stream.prepareForNewMessage(flush) - } func (thrift *thriftPlugin) ConnectionTimeout() time.Duration { @@ -914,8 +913,8 @@ func (thrift *thriftPlugin) ConnectionTimeout() time.Duration { } func (thrift *thriftPlugin) Parse(pkt *protos.Packet, tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { defer logp.Recover("ParseThrift exception") priv := thriftPrivateData{} @@ -1040,8 +1039,8 @@ func (thrift *thriftPlugin) receivedReply(msg *thriftMessage) { } func (thrift *thriftPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, - private protos.ProtocolData) protos.ProtocolData { - + private protos.ProtocolData, +) protos.ProtocolData { trans := thrift.getTransaction(tcptuple.Hashable()) if trans != nil { if trans.request != nil && trans.reply == nil { @@ -1055,8 +1054,8 @@ func (thrift *thriftPlugin) ReceivedFin(tcptuple *common.TCPTuple, dir uint8, } func (thrift *thriftPlugin) GapInStream(tcptuple *common.TCPTuple, dir uint8, - nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { - + nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool, +) { defer logp.Recover("GapInStream(thrift) exception") logp.Debug("thriftdetailed", "GapInStream called") diff --git a/packetbeat/protos/thrift/thrift_idl.go b/packetbeat/protos/thrift/thrift_idl.go index 82d8dedbe939..8bc8bec5b3b0 100644 --- a/packetbeat/protos/thrift/thrift_idl.go +++ b/packetbeat/protos/thrift/thrift_idl.go @@ -49,7 +49,7 @@ func fieldsToArrayByID(fields []*parser.Field) []*string { } } - output := make([]*string, max+1, max+1) + output := make([]*string, max+1) for _, field := range fields { if len(field.Name) > 0 { diff --git a/packetbeat/protos/thrift/thrift_test.go b/packetbeat/protos/thrift/thrift_test.go index b5377eb46654..0938c60a3be5 100644 --- a/packetbeat/protos/thrift/thrift_test.go +++ b/packetbeat/protos/thrift/thrift_test.go @@ -122,7 +122,6 @@ func TestThrift_readMessageBegin(t *testing.T) { data, _ = hex.DecodeString("800100010000000570696e6700000001") stream = thriftStream{data: data, message: new(thriftMessage)} - m = stream.message ok, complete = thrift.readMessageBegin(&stream) if !ok || complete { t.Errorf("Bad result: %v %v", ok, complete) @@ -130,7 +129,6 @@ func TestThrift_readMessageBegin(t *testing.T) { data, _ = hex.DecodeString("800100010000000570696e6700000001") stream = thriftStream{data: data, message: new(thriftMessage)} - m = stream.message ok, complete = thrift.readMessageBegin(&stream) if !ok || complete { t.Errorf("Bad result: %v %v", ok, complete) @@ -150,7 +148,6 @@ func TestThrift_readMessageBegin(t *testing.T) { data, _ = hex.DecodeString("0000000570696e670100000000") stream = thriftStream{data: data, message: new(thriftMessage)} - m = stream.message ok, complete = thrift.readMessageBegin(&stream) if !ok || complete { t.Error("Bad result:", ok, complete) diff --git a/packetbeat/protos/tls/alerts.go b/packetbeat/protos/tls/alerts.go index 4713e7e81f60..4da5c7d5b759 100644 --- a/packetbeat/protos/tls/alerts.go +++ b/packetbeat/protos/tls/alerts.go @@ -25,8 +25,10 @@ import ( "github.com/elastic/beats/v7/libbeat/logp" ) -type alertSeverity uint8 -type alertCode uint8 +type ( + alertSeverity uint8 + alertCode uint8 +) type alert struct { severity alertSeverity @@ -67,9 +69,7 @@ var alertNames = map[alertCode]string{ 115: "unknown_psk_identity", } -var ( - errRead = errors.New("Buffer read error") -) +var errRead = errors.New("Buffer read error") func (severity alertSeverity) String() string { switch severity { diff --git a/packetbeat/protos/tls/algos.go b/packetbeat/protos/tls/algos.go index b3ba6ea18672..8abd7021b674 100644 --- a/packetbeat/protos/tls/algos.go +++ b/packetbeat/protos/tls/algos.go @@ -22,11 +22,13 @@ import ( "fmt" ) -type cipherSuite uint16 -type signatureScheme uint16 -type pointsGroup uint16 -type compressionMethod uint8 -type ecPointsFormat uint8 +type ( + cipherSuite uint16 + signatureScheme uint16 + pointsGroup uint16 + compressionMethod uint8 + ecPointsFormat uint8 +) // from https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 var cipherSuites = map[cipherSuite]string{ @@ -440,26 +442,26 @@ var supportedGroups = map[pointsGroup]string{ } var signatureSchemes = map[signatureScheme]string{ - /* RSASSA-PKCS1-v1_5 algorithms */ + // RSASSA-PKCS1-v1_5 algorithms 0x0401: "rsa_pkcs1_sha256", 0x0501: "rsa_pkcs1_sha384", 0x0601: "rsa_pkcs1_sha512", - /* ECDSA algorithms */ + // ECDSA algorithms 0x0403: "ecdsa_secp256r1_sha256", 0x0503: "ecdsa_secp384r1_sha384", 0x0603: "ecdsa_secp521r1_sha512", - /* RSASSA-PSS algorithms */ + // RSASSA-PSS algorithms 0x0804: "rsa_pss_sha256", 0x0805: "rsa_pss_sha384", 0x0806: "rsa_pss_sha512", - /* EdDSA algorithms */ + // EdDSA algorithms 0x0807: "ed25519", 0x0808: "ed448", - /* Legacy algorithms */ + // Legacy algorithms 0x0201: "rsa_pkcs1_sha1", 0x0203: "ecdsa_sha1", } diff --git a/packetbeat/protos/tls/config.go b/packetbeat/protos/tls/config.go index 775a8f69cc10..2190ccc18dd7 100644 --- a/packetbeat/protos/tls/config.go +++ b/packetbeat/protos/tls/config.go @@ -30,13 +30,11 @@ type tlsConfig struct { Fingerprints []string `config:"fingerprints"` } -var ( - defaultConfig = tlsConfig{ - ProtocolCommon: config.ProtocolCommon{ - TransactionTimeout: protos.DefaultTransactionExpiration, - }, - SendCertificates: true, - IncludeDetailedFields: true, - Fingerprints: []string{"sha1"}, - } -) +var defaultConfig = tlsConfig{ + ProtocolCommon: config.ProtocolCommon{ + TransactionTimeout: protos.DefaultTransactionExpiration, + }, + SendCertificates: true, + IncludeDetailedFields: true, + Fingerprints: []string{"sha1"}, +} diff --git a/packetbeat/protos/tls/extensions.go b/packetbeat/protos/tls/extensions.go index 0021705c7f7f..1ffceb3c2350 100644 --- a/packetbeat/protos/tls/extensions.go +++ b/packetbeat/protos/tls/extensions.go @@ -35,12 +35,14 @@ type Extensions struct { InOrder []ExtensionID } -type extensionParser func(reader bufferView) interface{} -type extension struct { - label string - parser extensionParser - saveRaw bool -} +type ( + extensionParser func(reader bufferView) interface{} + extension struct { + label string + parser extensionParser + saveRaw bool + } +) const ( // ExtensionSupportedGroups identifies the supported group extension @@ -72,7 +74,6 @@ var extensionMap = map[uint16]extension{ // ParseExtensions returns an Extensions object parsed from the supplied buffer func ParseExtensions(buffer bufferView) Extensions { - var extensionsLength uint16 if !buffer.read16Net(0, &extensionsLength) || extensionsLength == 0 { // No extensions diff --git a/packetbeat/protos/tls/extensions_test.go b/packetbeat/protos/tls/extensions_test.go index 23caec090192..c61937411a97 100644 --- a/packetbeat/protos/tls/extensions_test.go +++ b/packetbeat/protos/tls/extensions_test.go @@ -27,7 +27,6 @@ import ( ) func TestSni(t *testing.T) { - // Single element buf := mkBuf(t, "000d"+ // 13 bytes @@ -126,7 +125,6 @@ func TestSni(t *testing.T) { } func TestParseMaxFragmentLength(t *testing.T) { - r := parseMaxFragmentLen(*mkBuf(t, "01", 1)) assert.Equal(t, "2^9", r.(string)) r = parseMaxFragmentLen(*mkBuf(t, "04", 1)) diff --git a/packetbeat/protos/tls/fingerprint.go b/packetbeat/protos/tls/fingerprint.go index 8768ff448e7b..70489b687f9c 100644 --- a/packetbeat/protos/tls/fingerprint.go +++ b/packetbeat/protos/tls/fingerprint.go @@ -36,8 +36,10 @@ type FingerprintAlgorithm struct { algo AlgorithmFactory } -var hashMap = make(map[string]*FingerprintAlgorithm) -var hashNames []string +var ( + hashMap = make(map[string]*FingerprintAlgorithm) + hashNames []string +) func init() { registerAlgo(func() hash.Hash { return md5.New() }, "md5", "") diff --git a/packetbeat/protos/tls/ja3.go b/packetbeat/protos/tls/ja3.go index 6e6faf5e26c0..09a0aec5ea48 100644 --- a/packetbeat/protos/tls/ja3.go +++ b/packetbeat/protos/tls/ja3.go @@ -25,7 +25,6 @@ import ( ) func getJa3Fingerprint(hello *helloMessage) (hash string, ja3str string) { - // build the array of arrays of numbers data := make([][]uint16, 5) diff --git a/packetbeat/protos/tls/parse.go b/packetbeat/protos/tls/parse.go index d0ec3be75efa..fa4515e2248f 100644 --- a/packetbeat/protos/tls/parse.go +++ b/packetbeat/protos/tls/parse.go @@ -54,9 +54,9 @@ type recordType uint8 const ( recordTypeChangeCipherSpec recordType = 20 - recordTypeAlert = 21 - recordTypeHandshake = 22 - recordTypeApplicationData = 23 + recordTypeAlert recordType = 21 + recordTypeHandshake recordType = 22 + recordTypeApplicationData recordType = 23 ) type handshakeType uint8 @@ -169,8 +169,10 @@ func readHandshakeHeader(buf *streambuf.Buffer) (*handshakeHeader, error) { if len16, err = buf.ReadNetUint16At(2); err != nil { return nil, err } - return &handshakeHeader{handshakeType(typ), - int(len16) | (int(len8) << 16)}, nil + return &handshakeHeader{ + handshakeType(typ), + int(len16) | (int(len8) << 16), + }, nil } func (header *recordHeader) String() string { @@ -215,7 +217,6 @@ func (hello *helloMessage) supportedCiphers() []string { } func (parser *parser) parse(buf *streambuf.Buffer) parserResult { - for buf.Avail(recordHeaderSize) { header, err := readRecordHeader(buf) diff --git a/packetbeat/protos/tls/parse_test.go b/packetbeat/protos/tls/parse_test.go index 37f4a1b19560..f599b30c44c9 100644 --- a/packetbeat/protos/tls/parse_test.go +++ b/packetbeat/protos/tls/parse_test.go @@ -125,12 +125,6 @@ func mapGet(t *testing.T, m common.MapStr, key string) interface{} { return value } -func mapInt(t *testing.T, m common.MapStr, key string) uint32 { - value, err := m.GetValue(key) - assert.NoError(t, err) - return value.(uint32) -} - func TestParseRecordHeader(t *testing.T) { if testing.Verbose() { isDebug = true @@ -173,6 +167,7 @@ func TestParseHandshakeHeader(t *testing.T) { _, err = readHandshakeHeader(sBuf(t, "112233")) assert.Error(t, err) header, err := readHandshakeHeader(sBuf(t, "11223344")) + assert.NoError(t, err) assert.Equal(t, handshakeType(0x11), header.handshakeType) assert.Equal(t, 0x223344, header.length) } @@ -202,7 +197,6 @@ func TestParserParse(t *testing.T) { // Certificate request assert.Equal(t, resultOK, parser.parse(sBuf(t, "16030300040d000000"))) assert.True(t, parser.certRequested) - } func TestParserHello(t *testing.T) { diff --git a/packetbeat/protos/tls/tls.go b/packetbeat/protos/tls/tls.go index 9db2a28f694e..a785d101021f 100644 --- a/packetbeat/protos/tls/tls.go +++ b/packetbeat/protos/tls/tls.go @@ -170,10 +170,9 @@ func (plugin *tlsPlugin) doParse( tcptuple *common.TCPTuple, dir uint8, ) *tlsConnectionData { - // Ignore further traffic after the handshake is completed (encrypted connection) // TODO: request/response analysis - if 0 != conn.handshakeCompleted&(1< 0 { desc = dev.Description } - r += fmt.Sprintf(" (%s)", desc) + fmt.Fprintf(&buf, " (%s)", desc) } if withIP { - ips := "Not assigned ip address" - if len(dev.Addresses) > 0 { - ips = "" - + buf.WriteString(" (") + if len(dev.Addresses) == 0 { + buf.WriteString("Not assigned ip address") + } else { for i, address := range []pcap.InterfaceAddress(dev.Addresses) { - // Add a space between the IP address. - if i > 0 { - ips += " " + if i != 0 { + buf.WriteByte(' ') } - - ips += fmt.Sprintf("%s", address.IP.String()) + fmt.Fprint(&buf, address.IP) } } - r += fmt.Sprintf(" (%s)", ips) - + buf.WriteByte(')') } - ret = append(ret, r) + names = append(names, buf.String()) } - return ret, nil + return names } func resolveDeviceName(name string) (string, error) { diff --git a/packetbeat/sniffer/device_test.go b/packetbeat/sniffer/device_test.go new file mode 100644 index 000000000000..189bc92a9cd7 --- /dev/null +++ b/packetbeat/sniffer/device_test.go @@ -0,0 +1,136 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package sniffer + +import ( + "net" + "reflect" + "testing" + + "github.com/tsg/gopacket/pcap" +) + +var formatDeviceNamesTests = []struct { + name string + interfaces []pcap.Interface + withDesc bool + withIP bool + want []string +}{ + {name: "empty"}, + { + name: "loopback no withs", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + Addresses: []pcap.InterfaceAddress{ + {IP: net.IP{127, 0, 0, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + }, + }, + }, + want: []string{ + "lo", + }, + }, + { + name: "loopback with desc", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + Addresses: []pcap.InterfaceAddress{ + {IP: net.IP{127, 0, 0, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + }, + }, + }, + withDesc: true, + want: []string{ + "lo (loopback)", + }, + }, + { + name: "loopback with IPs", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + Addresses: []pcap.InterfaceAddress{ + {IP: net.IP{127, 0, 0, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + }, + }, + }, + withIP: true, + want: []string{ + "lo (127.0.0.1)", + }, + }, + { + name: "loopback with the lot", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + Addresses: []pcap.InterfaceAddress{ + {IP: net.IP{127, 0, 0, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + }, + }, + }, + withDesc: true, + withIP: true, + want: []string{ + "lo (loopback) (127.0.0.1)", + }, + }, + { + name: "two addr loopback with the lot", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + Addresses: []pcap.InterfaceAddress{ + {IP: net.IP{127, 0, 0, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + {IP: net.IP{127, 0, 1, 1}, Netmask: net.IPMask{255, 0, 0, 0}}, + }, + }, + }, + withDesc: true, + withIP: true, + want: []string{ + "lo (loopback) (127.0.0.1 127.0.1.1)", + }, + }, + { + name: "no IP loopback with the lot", + interfaces: []pcap.Interface{ + { + Name: "lo", Description: "loopback", + }, + }, + withDesc: true, + withIP: true, + want: []string{ + "lo (loopback) (Not assigned ip address)", + }, + }, +} + +func TestFormatDevices(t *testing.T) { + for _, test := range formatDeviceNamesTests { + got := formatDeviceNames(test.interfaces, test.withDesc, test.withIP) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected result for test %s:\ngot: %v\nwant:%v", + test.name, got, test.want) + } + } +} diff --git a/packetbeat/sniffer/sniffer.go b/packetbeat/sniffer/sniffer.go index bfe720c7b985..07a7e3096a9b 100644 --- a/packetbeat/sniffer/sniffer.go +++ b/packetbeat/sniffer/sniffer.go @@ -39,7 +39,6 @@ import ( // to a Worker. type Sniffer struct { config config.InterfacesConfig - dumper *pcap.Dumper state atomic.Int32 // store snifferState @@ -60,7 +59,6 @@ type Worker interface { type snifferHandle interface { gopacket.PacketDataSource - LinkType() layers.LinkType Close() } diff --git a/packetbeat/sniffer/sniffer_test.go b/packetbeat/sniffer/sniffer_test.go index eea7821d8896..52b0b57fb330 100644 --- a/packetbeat/sniffer/sniffer_test.go +++ b/packetbeat/sniffer/sniffer_test.go @@ -52,13 +52,16 @@ func TestSniffer_afpacketComputeSize(t *testing.T) { t.Error("Value too big", blockSize, numBlocks) } - frameSize, blockSize, numBlocks, err = afpacketComputeSize(0, 1514, 4096) + _, _, _, err = afpacketComputeSize(0, 1514, 4096) if err == nil { t.Error("Expected an error") } // 16436 is the default MTU size of the loopback interface frameSize, blockSize, numBlocks, err = afpacketComputeSize(30, 16436, 4096) + if err != nil { + t.Error(err) + } if frameSize != 4096*5 || blockSize != 4096*5*128 || numBlocks != 12 { t.Error("Bad result", frameSize, blockSize, numBlocks) } From 73a2e5533839a692206272783f5be6652b8a1a5d Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Mon, 29 Nov 2021 17:31:52 -0800 Subject: [PATCH 035/172] Add note that there is no warranty or support for generator code (#28797) * Add note that there is no warranty or support for generator code * Remove tagged region because it's no longer used --- docs/devguide/create-metricset.asciidoc | 2 ++ docs/devguide/generator-support-note.asciidoc | 13 +++++++++++++ docs/devguide/modules-dev-guide.asciidoc | 2 ++ 3 files changed, 17 insertions(+) create mode 100644 docs/devguide/generator-support-note.asciidoc diff --git a/docs/devguide/create-metricset.asciidoc b/docs/devguide/create-metricset.asciidoc index a1540be23841..fd60e25dd3ae 100644 --- a/docs/devguide/create-metricset.asciidoc +++ b/docs/devguide/create-metricset.asciidoc @@ -1,6 +1,8 @@ [[creating-metricsets]] === Creating a Metricset +include::generator-support-note.asciidoc[tag=metricset-generator] + A metricset is the part of a Metricbeat module that fetches and structures the data from the remote service. Each module can have multiple metricsets. In this guide, you learn how to create your own metricset. diff --git a/docs/devguide/generator-support-note.asciidoc b/docs/devguide/generator-support-note.asciidoc new file mode 100644 index 000000000000..25579798ed28 --- /dev/null +++ b/docs/devguide/generator-support-note.asciidoc @@ -0,0 +1,13 @@ +// tag::metricset-generator[] +IMPORTANT: Elastic provides no warranty or support for the code used to generate +metricsets. The generator is mainly offered as guidance for developers who want +to create their own data shippers. + +// end::metricset-generator[] + +// tag::filebeat-generator[] +IMPORTANT: Elastic provides no warranty or support for the code used to generate +modules and filesets. The generator is mainly offered as guidance for developers +who want to create their own data shippers. + +// end::filebeat-generator[] \ No newline at end of file diff --git a/docs/devguide/modules-dev-guide.asciidoc b/docs/devguide/modules-dev-guide.asciidoc index 0936438900e0..03b3179c596e 100644 --- a/docs/devguide/modules-dev-guide.asciidoc +++ b/docs/devguide/modules-dev-guide.asciidoc @@ -1,6 +1,8 @@ [[filebeat-modules-devguide]] == Creating a New Filebeat Module +include::generator-support-note.asciidoc[tag=filebeat-generator] + This guide will walk you through creating a new Filebeat module. All Filebeat modules currently live in the main From af2eb730f71b686f38d2c3483864e7f0a2629373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 30 Nov 2021 10:50:09 +0100 Subject: [PATCH 036/172] Remove Journalbeat (#29131) Use journald input instead. --- .ci/packaging.groovy | 5 - CHANGELOG.next.asciidoc | 13 +- Jenkinsfile | 2 - Makefile | 2 +- README.md | 2 - auditbeat/cmd/root.go | 2 +- deploy/docker/journalbeat.docker.yml | 11 - dev-tools/cmd/update_go/update_go_version.go | 1 - dev-tools/ecs-migration.yml | 14 - filebeat/input/journald/config.go | 4 +- filebeat/input/journald/conv.go | 2 +- filebeat/input/journald/input.go | 4 +- .../input/journald}/pkg/journalfield/conv.go | 0 .../journald}/pkg/journalfield/conv_test.go | 0 .../journald}/pkg/journalfield/default.go | 0 .../pkg/journalfield/default_other.go | 0 .../journald}/pkg/journalfield/matcher.go | 0 .../pkg/journalfield/matcher_test.go | 0 .../input/journald}/pkg/journalread/mode.go | 0 .../journald}/pkg/journalread/mode_test.go | 0 .../input/journald}/pkg/journalread/reader.go | 0 journalbeat/.gitignore | 9 - journalbeat/Dockerfile | 23 - journalbeat/Makefile | 15 - journalbeat/README.md | 5 - journalbeat/_meta/config/beat.docker.yml.tmpl | 3 - .../_meta/config/beat.reference.yml.tmpl | 62 - journalbeat/_meta/config/beat.yml.tmpl | 57 - journalbeat/_meta/fields.common.yml | 329 - .../default/index-pattern/journalbeat.json | 16 - journalbeat/beater/journalbeat.go | 126 - journalbeat/checkpoint/checkpoint.go | 352 - journalbeat/checkpoint/checkpoint_test.go | 223 - journalbeat/checkpoint/file_unix.go | 27 - journalbeat/checkpoint/file_windows.go | 54 - journalbeat/cmd/instance/metrics.go | 69 - journalbeat/cmd/instance/metrics_other.go | 27 - journalbeat/cmd/root.go | 64 - journalbeat/config/config.go | 38 - journalbeat/conftest.py | 4 - journalbeat/docs/config-options.asciidoc | 251 - journalbeat/docs/configuring-howto.asciidoc | 59 - journalbeat/docs/faq.asciidoc | 10 - journalbeat/docs/fields.asciidoc | 16301 ---------------- journalbeat/docs/filtering.asciidoc | 36 - journalbeat/docs/general-options.asciidoc | 64 - journalbeat/docs/getting-started.asciidoc | 175 - journalbeat/docs/howto/howto.asciidoc | 35 - journalbeat/docs/images/coordinate-map.png | Bin 370029 -> 0 bytes journalbeat/docs/images/journald-log-data.png | Bin 215321 -> 0 bytes journalbeat/docs/index.asciidoc | 47 - journalbeat/docs/overview.asciidoc | 11 - journalbeat/docs/page_header.html | 4 - journalbeat/docs/running-on-docker.asciidoc | 1 - journalbeat/docs/setting-up-running.asciidoc | 47 - journalbeat/docs/troubleshooting.asciidoc | 31 - journalbeat/include/fields.go | 36 - journalbeat/input/config.go | 67 - journalbeat/input/input.go | 274 - journalbeat/input/input_test.go | 167 - journalbeat/journalbeat.docker.yml | 12 - journalbeat/journalbeat.reference.yml | 1561 -- journalbeat/journalbeat.yml | 217 - journalbeat/magefile.go | 171 - journalbeat/main.go | 30 - journalbeat/main_test.go | 49 - journalbeat/reader/config.go | 52 - journalbeat/reader/fields.go | 21 - journalbeat/reader/journal.go | 151 - journalbeat/reader/journal_other.go | 56 - .../tests/system/config/journalbeat.yml.j2 | 13 - journalbeat/tests/system/input/test.journal | Bin 8388608 -> 0 bytes journalbeat/tests/system/input/test.registry | 6 - journalbeat/tests/system/journalbeat.py | 12 - journalbeat/tests/system/test_base.py | 210 - libbeat/docs/getting-started.asciidoc | 2 +- libbeat/docs/overview.asciidoc | 2 +- libbeat/docs/shared-docker.asciidoc | 28 - .../docs/decode_csv_fields.asciidoc | 2 +- libbeat/scripts/Makefile | 2 - script/renamed_fields.py | 2 +- .../pkg/agent/program/program_test.go | 4 - .../testdata/journal_config-journalbeat.yml | 15 - .../spec/journalbeat.yml.disabled | 22 - x-pack/journalbeat/cmd/root.go | 21 - x-pack/journalbeat/main.go | 19 - x-pack/journalbeat/main_test.go | 33 - 87 files changed, 12 insertions(+), 21882 deletions(-) delete mode 100644 deploy/docker/journalbeat.docker.yml rename {journalbeat => filebeat/input/journald}/pkg/journalfield/conv.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalfield/conv_test.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalfield/default.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalfield/default_other.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalfield/matcher.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalfield/matcher_test.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalread/mode.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalread/mode_test.go (100%) rename {journalbeat => filebeat/input/journald}/pkg/journalread/reader.go (100%) delete mode 100644 journalbeat/.gitignore delete mode 100644 journalbeat/Dockerfile delete mode 100644 journalbeat/Makefile delete mode 100644 journalbeat/README.md delete mode 100644 journalbeat/_meta/config/beat.docker.yml.tmpl delete mode 100644 journalbeat/_meta/config/beat.reference.yml.tmpl delete mode 100644 journalbeat/_meta/config/beat.yml.tmpl delete mode 100644 journalbeat/_meta/fields.common.yml delete mode 100644 journalbeat/_meta/kibana/default/index-pattern/journalbeat.json delete mode 100644 journalbeat/beater/journalbeat.go delete mode 100644 journalbeat/checkpoint/checkpoint.go delete mode 100644 journalbeat/checkpoint/checkpoint_test.go delete mode 100644 journalbeat/checkpoint/file_unix.go delete mode 100644 journalbeat/checkpoint/file_windows.go delete mode 100644 journalbeat/cmd/instance/metrics.go delete mode 100644 journalbeat/cmd/instance/metrics_other.go delete mode 100644 journalbeat/cmd/root.go delete mode 100644 journalbeat/config/config.go delete mode 100644 journalbeat/conftest.py delete mode 100644 journalbeat/docs/config-options.asciidoc delete mode 100644 journalbeat/docs/configuring-howto.asciidoc delete mode 100644 journalbeat/docs/faq.asciidoc delete mode 100644 journalbeat/docs/fields.asciidoc delete mode 100644 journalbeat/docs/filtering.asciidoc delete mode 100644 journalbeat/docs/general-options.asciidoc delete mode 100644 journalbeat/docs/getting-started.asciidoc delete mode 100644 journalbeat/docs/howto/howto.asciidoc delete mode 100644 journalbeat/docs/images/coordinate-map.png delete mode 100644 journalbeat/docs/images/journald-log-data.png delete mode 100644 journalbeat/docs/index.asciidoc delete mode 100644 journalbeat/docs/overview.asciidoc delete mode 100644 journalbeat/docs/page_header.html delete mode 100644 journalbeat/docs/running-on-docker.asciidoc delete mode 100644 journalbeat/docs/setting-up-running.asciidoc delete mode 100644 journalbeat/docs/troubleshooting.asciidoc delete mode 100644 journalbeat/include/fields.go delete mode 100644 journalbeat/input/config.go delete mode 100644 journalbeat/input/input.go delete mode 100644 journalbeat/input/input_test.go delete mode 100644 journalbeat/journalbeat.docker.yml delete mode 100644 journalbeat/journalbeat.reference.yml delete mode 100644 journalbeat/journalbeat.yml delete mode 100644 journalbeat/magefile.go delete mode 100644 journalbeat/main.go delete mode 100644 journalbeat/main_test.go delete mode 100644 journalbeat/reader/config.go delete mode 100644 journalbeat/reader/fields.go delete mode 100644 journalbeat/reader/journal.go delete mode 100644 journalbeat/reader/journal_other.go delete mode 100644 journalbeat/tests/system/config/journalbeat.yml.j2 delete mode 100644 journalbeat/tests/system/input/test.journal delete mode 100644 journalbeat/tests/system/input/test.registry delete mode 100644 journalbeat/tests/system/journalbeat.py delete mode 100644 journalbeat/tests/system/test_base.py delete mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/journal_config-journalbeat.yml delete mode 100644 x-pack/elastic-agent/spec/journalbeat.yml.disabled delete mode 100644 x-pack/journalbeat/cmd/root.go delete mode 100644 x-pack/journalbeat/main.go delete mode 100644 x-pack/journalbeat/main_test.go diff --git a/.ci/packaging.groovy b/.ci/packaging.groovy index 7c4ce7b5e8fa..7be1628e138b 100644 --- a/.ci/packaging.groovy +++ b/.ci/packaging.groovy @@ -101,7 +101,6 @@ pipeline { 'auditbeat', 'filebeat', 'heartbeat', - 'journalbeat', 'metricbeat', 'packetbeat', 'winlogbeat', @@ -111,7 +110,6 @@ pipeline { 'x-pack/filebeat', 'x-pack/functionbeat', 'x-pack/heartbeat', - // 'x-pack/journalbeat', 'x-pack/metricbeat', 'x-pack/osquerybeat', 'x-pack/packetbeat', @@ -199,7 +197,6 @@ pipeline { 'auditbeat', 'filebeat', 'heartbeat', - 'journalbeat', 'metricbeat', 'packetbeat', 'x-pack/auditbeat', @@ -277,8 +274,6 @@ def pushCIDockerImages(Map args = [:]) { tagAndPush(beatName: 'filebeat', arch: arch) } else if (env?.BEATS_FOLDER?.endsWith('heartbeat')) { tagAndPush(beatName: 'heartbeat', arch: arch) - } else if ("${env.BEATS_FOLDER}" == "journalbeat"){ - tagAndPush(beatName: 'journalbeat', arch: arch) } else if (env?.BEATS_FOLDER?.endsWith('metricbeat')) { tagAndPush(beatName: 'metricbeat', arch: arch) } else if (env?.BEATS_FOLDER?.endsWith('osquerybeat')) { diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 00383fb51cfc..b8bb5c5d5421 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -28,6 +28,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] +- Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131] *Auditbeat* @@ -69,11 +70,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* - Change behavior in case of duplicate monitor IDs in configs to be last monitor wins. {pull}29041[29041] -*Journalbeat* - -- Rename field `journald.process.capabilites` to `journald.process.capabilities` to fix spelling. {pull}28065[28065] -- Rename field `log.syslog.facility.name` to `log.syslog.facility.code` because the value is numeric rather than the facility name. {pull}28065[28065] - *Metricbeat* - Add Linux pressure metricset {pull}27355[27355] @@ -203,9 +199,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove accidentally included cups library in docker images. {pull}28853[pull] - Fix broken monitors with newer versions of image relying on dup3. {pull}28938[pull] -*Journalbeat* - - *Metricbeat* - Fix checking tagsFilter using length in cloudwatch metricset. {pull}14525[14525] @@ -359,8 +352,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Experimental 'run once' mode. {pull}25972[25972] - Add `keyword` multi-field mapping for `synthetics.step.name`. {pull}28452[28452] -*Journalbeat* - *Metricbeat* - Move the windows pdh implementation from perfmon to a shared location in order for future modules/metricsets to make use of. {pull}15503[15503] @@ -405,8 +396,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* -*Journalbeat* - *Metricbeat* diff --git a/Jenkinsfile b/Jenkinsfile index 9d52f95553f8..9d5aca6a4ceb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -431,8 +431,6 @@ def pushCIDockerImages(Map args = [:]) { tagAndPush(beatName: 'filebeat', arch: arch) } else if (beatsFolder.endsWith('heartbeat')) { tagAndPush(beatName: 'heartbeat', arch: arch) - } else if ("${beatsFolder}" == "journalbeat"){ - tagAndPush(beatName: 'journalbeat', arch: arch) } else if (beatsFolder.endsWith('metricbeat')) { tagAndPush(beatName: 'metricbeat', arch: arch) } else if ("${beatsFolder}" == "packetbeat"){ diff --git a/Makefile b/Makefile index 1975bac31659..40b081bf3edc 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BUILD_DIR=$(CURDIR)/build COVERAGE_DIR=$(BUILD_DIR)/coverage -BEATS?=auditbeat filebeat heartbeat journalbeat metricbeat packetbeat winlogbeat x-pack/functionbeat x-pack/elastic-agent x-pack/osquerybeat +BEATS?=auditbeat filebeat heartbeat metricbeat packetbeat winlogbeat x-pack/functionbeat x-pack/elastic-agent x-pack/osquerybeat PROJECTS=libbeat $(BEATS) PROJECTS_ENV=libbeat filebeat metricbeat PYTHON_ENV?=$(BUILD_DIR)/python-env diff --git a/README.md b/README.md index 32d411d74ac2..6707fced374d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ Beat | Description [Filebeat](https://github.com/elastic/beats/tree/master/filebeat) | Tails and ships log files [Functionbeat](https://github.com/elastic/beats/tree/master/x-pack/functionbeat) | Read and ships events from serverless infrastructure. [Heartbeat](https://github.com/elastic/beats/tree/master/heartbeat) | Ping remote services for availability -[Journalbeat](https://github.com/elastic/beats/tree/master/journalbeat) | Read and ships event from Journald. [Metricbeat](https://github.com/elastic/beats/tree/master/metricbeat) | Fetches sets of metrics from the operating system and services [Packetbeat](https://github.com/elastic/beats/tree/master/packetbeat) | Monitors the network and applications by sniffing packets [Winlogbeat](https://github.com/elastic/beats/tree/master/winlogbeat) | Fetches and ships Windows Event logs @@ -45,7 +44,6 @@ on the [elastic.co site](https://www.elastic.co/guide/): * [Filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/index.html) * [Functionbeat](https://www.elastic.co/guide/en/beats/functionbeat/current/index.html) * [Heartbeat](https://www.elastic.co/guide/en/beats/heartbeat/current/index.html) -* [Journalbeat](https://www.elastic.co/guide/en/beats/journalbeat/current/index.html) * [Metricbeat](https://www.elastic.co/guide/en/beats/metricbeat/current/index.html) * [Packetbeat](https://www.elastic.co/guide/en/beats/packetbeat/current/index.html) * [Winlogbeat](https://www.elastic.co/guide/en/beats/winlogbeat/current/index.html) diff --git a/auditbeat/cmd/root.go b/auditbeat/cmd/root.go index 35fa18ecad0b..aa5b523e9768 100644 --- a/auditbeat/cmd/root.go +++ b/auditbeat/cmd/root.go @@ -63,7 +63,7 @@ func AuditbeatSettings() instance.Settings { } } -// Initialize initializes the entrypoint commands for journalbeat +// Initialize initializes the entrypoint commands for auditbeat func Initialize(settings instance.Settings) *cmd.BeatsRootCmd { create := beater.Creator( beater.WithModuleOptions( diff --git a/deploy/docker/journalbeat.docker.yml b/deploy/docker/journalbeat.docker.yml deleted file mode 100644 index a1e67c0d9618..000000000000 --- a/deploy/docker/journalbeat.docker.yml +++ /dev/null @@ -1,11 +0,0 @@ -journalbeat.inputs: -- paths: [] - seek: cursor - -processors: -- add_cloud_metadata: ~ - -output.elasticsearch: - hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' - username: '${ELASTICSEARCH_USERNAME:}' - password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/dev-tools/cmd/update_go/update_go_version.go b/dev-tools/cmd/update_go/update_go_version.go index 9ab0fa8a4a44..f589abc756dd 100644 --- a/dev-tools/cmd/update_go/update_go_version.go +++ b/dev-tools/cmd/update_go/update_go_version.go @@ -30,7 +30,6 @@ var files = []string{ "auditbeat/Dockerfile", "filebeat/Dockerfile", "heartbeat/Dockerfile", - "journalbeat/Dockerfile", "libbeat/Dockerfile", "libbeat/docs/version.asciidoc", "metricbeat/Dockerfile", diff --git a/dev-tools/ecs-migration.yml b/dev-tools/ecs-migration.yml index 39bc49505646..0ea295b2d7e3 100644 --- a/dev-tools/ecs-migration.yml +++ b/dev-tools/ecs-migration.yml @@ -1954,20 +1954,6 @@ alias: true beat: heartbeat -# Journalbeat -- from: host.name - to: host.hostname - alias: false - beat: journalbeat - comment: This field should not be renamed as it would cause issue some Beats and Journalbeat does not have dashboards - # This field should not be renamed as it would cause issue some Beats and Journalbeat does not have dashboards - rename: false - -- from: read_timestamp - to: event.created - alias: true - beat: journalbeat - ## Winlogbeat # Alias to ECS fields diff --git a/filebeat/input/journald/config.go b/filebeat/input/journald/config.go index 6704dabfc021..e3bf6bdd5090 100644 --- a/filebeat/input/journald/config.go +++ b/filebeat/input/journald/config.go @@ -24,8 +24,8 @@ import ( "errors" "time" - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" - "github.com/elastic/beats/v7/journalbeat/pkg/journalread" + "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalfield" + "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalread" ) // Config stores the options of a journald input. diff --git a/filebeat/input/journald/conv.go b/filebeat/input/journald/conv.go index a9785cf49f65..a1bf52f30004 100644 --- a/filebeat/input/journald/conv.go +++ b/filebeat/input/journald/conv.go @@ -23,7 +23,7 @@ package journald import ( "time" - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" + "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalfield" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/logp" ) diff --git a/filebeat/input/journald/input.go b/filebeat/input/journald/input.go index 74bd0983d238..7c8f5085dead 100644 --- a/filebeat/input/journald/input.go +++ b/filebeat/input/journald/input.go @@ -26,10 +26,10 @@ import ( "github.com/coreos/go-systemd/v22/sdjournal" "github.com/urso/sderr" + "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalfield" + "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalread" input "github.com/elastic/beats/v7/filebeat/input/v2" cursor "github.com/elastic/beats/v7/filebeat/input/v2/input-cursor" - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" - "github.com/elastic/beats/v7/journalbeat/pkg/journalread" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/backoff" "github.com/elastic/beats/v7/libbeat/feature" diff --git a/journalbeat/pkg/journalfield/conv.go b/filebeat/input/journald/pkg/journalfield/conv.go similarity index 100% rename from journalbeat/pkg/journalfield/conv.go rename to filebeat/input/journald/pkg/journalfield/conv.go diff --git a/journalbeat/pkg/journalfield/conv_test.go b/filebeat/input/journald/pkg/journalfield/conv_test.go similarity index 100% rename from journalbeat/pkg/journalfield/conv_test.go rename to filebeat/input/journald/pkg/journalfield/conv_test.go diff --git a/journalbeat/pkg/journalfield/default.go b/filebeat/input/journald/pkg/journalfield/default.go similarity index 100% rename from journalbeat/pkg/journalfield/default.go rename to filebeat/input/journald/pkg/journalfield/default.go diff --git a/journalbeat/pkg/journalfield/default_other.go b/filebeat/input/journald/pkg/journalfield/default_other.go similarity index 100% rename from journalbeat/pkg/journalfield/default_other.go rename to filebeat/input/journald/pkg/journalfield/default_other.go diff --git a/journalbeat/pkg/journalfield/matcher.go b/filebeat/input/journald/pkg/journalfield/matcher.go similarity index 100% rename from journalbeat/pkg/journalfield/matcher.go rename to filebeat/input/journald/pkg/journalfield/matcher.go diff --git a/journalbeat/pkg/journalfield/matcher_test.go b/filebeat/input/journald/pkg/journalfield/matcher_test.go similarity index 100% rename from journalbeat/pkg/journalfield/matcher_test.go rename to filebeat/input/journald/pkg/journalfield/matcher_test.go diff --git a/journalbeat/pkg/journalread/mode.go b/filebeat/input/journald/pkg/journalread/mode.go similarity index 100% rename from journalbeat/pkg/journalread/mode.go rename to filebeat/input/journald/pkg/journalread/mode.go diff --git a/journalbeat/pkg/journalread/mode_test.go b/filebeat/input/journald/pkg/journalread/mode_test.go similarity index 100% rename from journalbeat/pkg/journalread/mode_test.go rename to filebeat/input/journald/pkg/journalread/mode_test.go diff --git a/journalbeat/pkg/journalread/reader.go b/filebeat/input/journald/pkg/journalread/reader.go similarity index 100% rename from journalbeat/pkg/journalread/reader.go rename to filebeat/input/journald/pkg/journalread/reader.go diff --git a/journalbeat/.gitignore b/journalbeat/.gitignore deleted file mode 100644 index 504279e50ee3..000000000000 --- a/journalbeat/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.idea -/build -.DS_Store -.journalbeat_position -/journalbeat -/journalbeat.test -*.pyc -data/meta.json -/*.journal diff --git a/journalbeat/Dockerfile b/journalbeat/Dockerfile deleted file mode 100644 index 6c461fcb01a2..000000000000 --- a/journalbeat/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:1.17.2 - -RUN \ - apt-get update \ - && apt-get install -y --no-install-recommends \ - libsystemd-dev \ - libc6-dev-i386 \ - gcc-arm-linux-gnueabi \ - python3 \ - python3-pip \ - python3-venv \ - && rm -rf /var/lib/apt/lists/* - -RUN pip3 install --upgrade pip==20.1.1 -RUN pip3 install --upgrade setuptools==47.3.2 -RUN pip3 install --upgrade docker-compose==1.23.2 - -# Setup work environment -ENV JOURNALBEAT_PATH /go/src/github.com/elastic/beats/journalbeat - -RUN mkdir -p $JOURNALBEAT_PATH/build/coverage -WORKDIR $JOURNALBEAT_PATH -HEALTHCHECK CMD exit 0 diff --git a/journalbeat/Makefile b/journalbeat/Makefile deleted file mode 100644 index 85049183d4ec..000000000000 --- a/journalbeat/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -BEAT_NAME=journalbeat -BEAT_TITLE=Journalbeat -SYSTEM_TESTS=true -TEST_ENVIRONMENT=false -ES_BEATS?=.. - -# Path to the libbeat Makefile --include $(ES_BEATS)/libbeat/scripts/Makefile - -.PHONY: before-build -before-build: - -# Collects all dependencies and then calls update -.PHONY: collect -collect: diff --git a/journalbeat/README.md b/journalbeat/README.md deleted file mode 100644 index 69fccb38f904..000000000000 --- a/journalbeat/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Journalbeat - -Journalbeat is an open source data collector to read and forward journal entries from Linuxes with systemd. - -## Getting started diff --git a/journalbeat/_meta/config/beat.docker.yml.tmpl b/journalbeat/_meta/config/beat.docker.yml.tmpl deleted file mode 100644 index 20ae6ee130d2..000000000000 --- a/journalbeat/_meta/config/beat.docker.yml.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -journalbeat.inputs: -- paths: [] - seek: cursor diff --git a/journalbeat/_meta/config/beat.reference.yml.tmpl b/journalbeat/_meta/config/beat.reference.yml.tmpl deleted file mode 100644 index 8da73b6bf074..000000000000 --- a/journalbeat/_meta/config/beat.reference.yml.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -###################### Journalbeat Configuration Example ######################### - -# This file is an example configuration file highlighting only the most common -# options. The journalbeat.reference.yml file from the same directory contains all the -# supported options with more comments. You can use it as a reference. -# -# You can find the full configuration reference here: -# https://www.elastic.co/guide/en/beats/journalbeat/index.html - -# For more available modules and options, please see the journalbeat.reference.yml sample -# configuration file. - -{{header "Journalbeat inputs"}} - -journalbeat.inputs: - # Paths that should be crawled and fetched. Possible values files and directories. - # When setting a directory, all journals under it are merged. - # When empty starts to read from local journal. -- paths: [] - - # An optional unique identifier for the input. By providing a unique `id` you - # can operate multiple inputs on the same journal. This allows each input's - # cursor to be persisted independently in the registry file. - #id: "" - - # The number of seconds to wait before trying to read again from journals. - #backoff: 1s - # The maximum number of seconds to wait before attempting to read again from journals. - #max_backoff: 20s - - # Position to start reading from journal. Valid values: head, tail, cursor - seek: cursor - # Fallback position if no cursor data is available. - #cursor_seek_fallback: head - - # Exact matching for field values of events. - # Matching for nginx entries: "systemd.unit=nginx" - #include_matches: [] - - # Set the option to preserve the remote hostname in entries from a remote journal. - # It is only needed when used with add_host_metadata, so the original host name - # does not get overwritten by the processor. - #save_remote_hostname: false - - # Optional fields that you can specify to add additional information to the - # output. Fields can be scalar values, arrays, dictionaries, or any nested - # combination of these. - #fields: - # env: staging - - -{{header "Journalbeat global options"}} -#journalbeat: - # Name of the registry file. If a relative path is used, it is considered relative to the - # data path. - #registry_file: registry - -{{header "Elasticsearch template setting"}} -setup.template.settings: - index.number_of_shards: 1 - #index.codec: best_compression - #_source.enabled: false diff --git a/journalbeat/_meta/config/beat.yml.tmpl b/journalbeat/_meta/config/beat.yml.tmpl deleted file mode 100644 index a4f7d5d4c31f..000000000000 --- a/journalbeat/_meta/config/beat.yml.tmpl +++ /dev/null @@ -1,57 +0,0 @@ -###################### Journalbeat Configuration Example ######################### - -# This file is an example configuration file highlighting only the most common -# options. The journalbeat.reference.yml file from the same directory contains all the -# supported options with more comments. You can use it as a reference. -# -# You can find the full configuration reference here: -# https://www.elastic.co/guide/en/beats/journalbeat/index.html - -# For more available modules and options, please see the journalbeat.reference.yml sample -# configuration file. - -{{header "Journalbeat inputs"}} - -journalbeat.inputs: - # Paths that should be crawled and fetched. Possible values files and directories. - # When setting a directory, all journals under it are merged. - # When empty starts to read from local journal. -- paths: [] - - # An optional unique identifier for the input. By providing a unique `id` you - # can operate multiple inputs on the same journal. This allows each input's - # cursor to be persisted independently in the registry file. - #id: "" - - # The number of seconds to wait before trying to read again from journals. - #backoff: 1s - # The maximum number of seconds to wait before attempting to read again from journals. - #max_backoff: 20s - - # Position to start reading from journal. Valid values: head, tail, cursor - seek: cursor - # Fallback position if no cursor data is available. - #cursor_seek_fallback: head - - # Exact matching for field values of events. - # Matching for nginx entries: "systemd.unit=nginx" - #include_matches: [] - - # Optional fields that you can specify to add additional information to the - # output. Fields can be scalar values, arrays, dictionaries, or any nested - # combination of these. - #fields: - # env: staging - - -{{header "Journalbeat global options"}} -#journalbeat: - # Name of the registry file. If a relative path is used, it is considered relative to the - # data path. - #registry_file: registry - -{{header "Elasticsearch template setting"}} -setup.template.settings: - index.number_of_shards: 1 - #index.codec: best_compression - #_source.enabled: false diff --git a/journalbeat/_meta/fields.common.yml b/journalbeat/_meta/fields.common.yml deleted file mode 100644 index b06081ae19b9..000000000000 --- a/journalbeat/_meta/fields.common.yml +++ /dev/null @@ -1,329 +0,0 @@ -- key: common - title: "Common Journalbeat" - description: > - Contains common fields available in all event types. - fields: - - name: coredump - type: group - description: > - Fields used by systemd-coredump kernel helper. - fields: - - name: unit - type: keyword - description: > - Annotations of messages containing coredumps from system units. - - name: user_unit - type: keyword - description: > - Annotations of messages containing coredumps from user units. - - name: journald - type: group - description: > - Fields provided by journald. - fields: - - name: object - type: group - description: > - Fields to log on behalf of a different program. - fields: - - name: audit - type: group - description: > - Audit fields of event. - fields: - - name: login_uid - type: long - required: false - example: 1000 - description: > - The login UID of the object process. - - name: session - type: long - required: false - example: 3 - description: > - The audit session of the object process. - - name: process.command_line - type: keyword - required: false - example: "/lib/systemd/systemd --user" - description: > - The command line of the process. - - name: process.name - type: keyword - required: false - example: "/lib/systemd/systemd" - description: > - Name of the executable. - - name: process.executable - type: keyword - required: false - description: > - Path to the the executable. - example: "/lib/systemd/systemd" - - name: uid - type: long - required: false - description: > - UID of the object process. - - name: gid - type: long - required: false - description: > - GID of the object process. - - name: pid - type: long - required: false - description: > - PID of the object process. - - name: systemd - type: group - description: > - Systemd fields of event. - fields: - - name: owner_uid - type: long - required: false - description: > - The UID of the owner. - - name: session - type: keyword - required: false - description: > - The ID of the systemd session. - - name: unit - type: keyword - required: false - description: > - The name of the systemd unit. - - name: user_unit - type: keyword - required: false - description: > - The name of the systemd user unit. - - name: kernel - type: group - description: > - Fields to log on behalf of a different program. - fields: - - name: device - type: keyword - required: false - description: > - The kernel device name. - - name: subsystem - type: keyword - required: false - description: > - The kernel subsystem name. - - name: device_symlinks - type: keyword - required: false - description: > - Additional symlink names pointing to the device node in /dev. - - name: device_node_path - type: keyword - required: false - description: > - The device node path of this device in /dev. - - name: device_name - type: keyword - required: false - description: > - The kernel device name as it shows up in the device tree below /sys. - - name: code - type: group - description: > - Fields of the code generating the event. - fields: - - name: file - type: keyword - required: false - example: "../src/core/manager.c" - description: > - The name of the source file where the log is generated. - - name: function - type: keyword - required: false - example: "job_log_status_message" - description: > - The name of the function which generated the log message. - - name: line - type: long - required: false - example: 123 - description: > - The line number of the code which generated the log message. - - name: process - type: group - description: > - Fields to log on behalf of a different program. - fields: - - name: audit - type: group - description: > - Audit fields of event. - fields: - - name: loginuid - type: long - required: false - example: 1000 - description: > - The login UID of the source process. - - name: session - type: long - required: false - example: 3 - description: > - The audit session of the source process. - - name: command_line - type: keyword - required: false - example: "/lib/systemd/systemd --user" - description: > - The command line of the process. - - name: name - type: keyword - required: false - example: "/lib/systemd/systemd" - description: > - Name of the executable. - - name: executable - type: keyword - required: false - description: > - Path to the the executable. - example: "/lib/systemd/systemd" - - name: pid - type: long - required: false - example: 1 - description: > - The ID of the process which logged the message. - - name: gid - type: long - required: false - example: 1 - description: > - The ID of the group which runs the process. - - name: uid - type: long - required: false - example: 1 - description: > - The ID of the user which runs the process. - - name: capabilities - required: false - description: > - The effective capabilities of the process. - - name: systemd - type: group - description: > - Fields of systemd. - fields: - - name: invocation_id - type: keyword - required: false - example: "8450f1672de646c88cd133aadd4f2d70" - description: > - The invocation ID for the runtime cycle of the unit the message was generated in. - - name: cgroup - type: keyword - required: false - example: "/user.slice/user-1234.slice/session-2.scope" - description: > - The control group path in the systemd hierarchy. - - name: owner_uid - type: long - required: false - description: > - The owner UID of the systemd user unit or systemd session. - - name: session - type: keyword - required: false - description: > - The ID of the systemd session. - - name: slice - type: keyword - required: false - example: "user-1234.slice" - description: > - The systemd slice unit. - - name: user_slice - type: keyword - required: false - description: > - The systemd user slice unit. - - name: unit - type: keyword - required: false - example: "nginx.service" - description: > - The name of the systemd unit. - - name: user_unit - type: keyword - required: false - example: "user-1234.slice" - description: > - The name of the systemd user unit. - - name: transport - type: keyword - required: true - example: "syslog" - description: > - How the log message was received by journald. - - name: host - type: group - description: > - Fields of the host. - fields: - - name: boot_id - type: keyword - required: false - example: "dd8c974asdf01dbe2ef26d7fasdf264c9" - description: > - The boot ID for the boot the log was generated in. - - name: syslog - type: group - description: > - Fields of the code generating the event. - fields: - - name: priority - type: long - required: false - example: 1 - description: > - The priority of the message. A syslog compatibility field. - - name: facility - type: long - required: false - example: 1 - description: > - The facility of the message. A syslog compatibility field. - - name: identifier - type: keyword - required: false - example: "su" - description: > - The identifier of the message. A syslog compatibility field. - - name: custom - type: nested - required: false - description: > - Arbitrary fields coming from processes. - - - name: read_timestamp - type: alias - path: event.created - migration: true - - - name: container - type: group - fields: - - name: log - type: group - fields: - - name: tag - type: keyword - description: > - User defined tag of a container. diff --git a/journalbeat/_meta/kibana/default/index-pattern/journalbeat.json b/journalbeat/_meta/kibana/default/index-pattern/journalbeat.json deleted file mode 100644 index 55e70bd81d12..000000000000 --- a/journalbeat/_meta/kibana/default/index-pattern/journalbeat.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "7.0.0-alpha1", - "objects": [ - { - "attributes": { - "fields": "[{\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"beat.name\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"beat.hostname\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"beat.timezone\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"beat.version\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"@timestamp\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"date\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"tags\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"fields\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": false, \"name\": \"error.message\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"error.code\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"number\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"error.type\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.provider\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.instance_id\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.instance_name\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.machine_type\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.availability_zone\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.project_id\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"meta.cloud.region\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"docker.container.id\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"docker.container.image\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"docker.container.name\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"docker.container.labels\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.pod.name\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.namespace\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.labels\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.annotations\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.container.name\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"kubernetes.container.image\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"counter\", \"searchable\": true, \"indexed\": true, \"doc_values\": true, \"type\": \"number\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": false, \"name\": \"_id\", \"searchable\": false, \"indexed\": false, \"doc_values\": false, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": true, \"name\": \"_type\", \"searchable\": true, \"indexed\": false, \"doc_values\": false, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": false, \"name\": \"_index\", \"searchable\": false, \"indexed\": false, \"doc_values\": false, \"type\": \"string\", \"scripted\": false}, {\"count\": 0, \"analyzed\": false, \"aggregatable\": false, \"name\": \"_score\", \"searchable\": false, \"indexed\": false, \"doc_values\": false, \"type\": \"number\", \"scripted\": false}]", - "fieldFormatMap": "{\"@timestamp\": {\"id\": \"date\"}}", - "timeFieldName": "@timestamp", - "title": "journalbeat-*" - }, - "version": 1, - "type": "index-pattern", - "id": "journalbeat-*" - } - ] -} \ No newline at end of file diff --git a/journalbeat/beater/journalbeat.go b/journalbeat/beater/journalbeat.go deleted file mode 100644 index 6694dbd8a9a0..000000000000 --- a/journalbeat/beater/journalbeat.go +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package beater - -import ( - "fmt" - "sync" - "time" - - "github.com/elastic/beats/v7/journalbeat/checkpoint" - "github.com/elastic/beats/v7/journalbeat/cmd/instance" - "github.com/elastic/beats/v7/journalbeat/input" - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/acker" - "github.com/elastic/beats/v7/libbeat/common/cfgwarn" - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/publisher/pipetool" - - "github.com/elastic/beats/v7/journalbeat/config" - _ "github.com/elastic/beats/v7/journalbeat/include" - - // Add dedicated processors - _ "github.com/elastic/beats/v7/libbeat/processors/decode_csv_fields" -) - -// Journalbeat instance -type Journalbeat struct { - inputs []*input.Input - done chan struct{} - config config.Config - - pipeline beat.Pipeline - checkpoint *checkpoint.Checkpoint - logger *logp.Logger -} - -// New returns a new Journalbeat instance -func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { - cfgwarn.Experimental("Journalbeat is experimental.") - - config := config.DefaultConfig - if err := cfg.Unpack(&config); err != nil { - return nil, fmt.Errorf("error reading config file: %v", err) - } - - done := make(chan struct{}) - cp, err := checkpoint.NewCheckpoint(config.RegistryFile, 10, 1*time.Second) - if err != nil { - return nil, err - } - - instance.SetupJournalMetrics() - - var inputs []*input.Input - for _, c := range config.Inputs { - i, err := input.New(c, b.Info, done, cp.States()) - if err != nil { - return nil, err - } - inputs = append(inputs, i) - } - - bt := &Journalbeat{ - inputs: inputs, - done: done, - config: config, - pipeline: b.Publisher, - checkpoint: cp, - logger: logp.NewLogger("journalbeat"), - } - - return bt, nil -} - -// Run sets up the ACK handler and starts inputs to read and forward events to outputs. -func (bt *Journalbeat) Run(b *beat.Beat) error { - bt.logger.Info("journalbeat is running! Hit CTRL-C to stop it.") - defer bt.logger.Info("journalbeat is stopping") - - defer bt.checkpoint.Shutdown() - - pipeline := pipetool.WithACKer(b.Publisher, acker.LastEventPrivateReporter(func(_ int, private interface{}) { - if st, ok := private.(checkpoint.JournalState); ok { - bt.checkpoint.PersistState(st) - } - })) - - var wg sync.WaitGroup - for _, i := range bt.inputs { - wg.Add(1) - go bt.runInput(i, &wg, pipeline) - } - - wg.Wait() - - return nil -} - -func (bt *Journalbeat) runInput(i *input.Input, wg *sync.WaitGroup, pipeline beat.Pipeline) { - defer wg.Done() - i.Run(pipeline) -} - -// Stop stops the beat and its inputs. -func (bt *Journalbeat) Stop() { - close(bt.done) - for _, i := range bt.inputs { - i.Stop() - } -} diff --git a/journalbeat/checkpoint/checkpoint.go b/journalbeat/checkpoint/checkpoint.go deleted file mode 100644 index 2ba4140182a1..000000000000 --- a/journalbeat/checkpoint/checkpoint.go +++ /dev/null @@ -1,352 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// Package checkpoint persists event log state information to disk so that -// event log monitoring can resume from the last read event in the case of a -// restart or unexpected interruption. -package checkpoint - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "sort" - "sync" - "time" - - "gopkg.in/yaml.v2" - - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/paths" -) - -// Checkpoint persists event log state information to disk. -type Checkpoint struct { - wg sync.WaitGroup // WaitGroup used to wait on the shutdown of the checkpoint worker. - done chan struct{} // Channel for shutting down the checkpoint worker. - once sync.Once // Used to guarantee shutdown happens once. - file string // File where the state is persisted. - fileLock sync.RWMutex // Lock that protects concurrent reads/writes to file. - numUpdates int // Number of updates received since last persisting to disk. - maxUpdates int // Maximum number of updates to buffer before persisting to disk. - flushInterval time.Duration // Maximum time interval that can pass before persisting to disk. - sort []string // Slice used for sorting states map (store to save on mallocs). - - lock sync.RWMutex - states map[string]JournalState - - save chan JournalState -} - -// PersistedState represents the format of the data persisted to disk. -type PersistedState struct { - UpdateTime time.Time `yaml:"update_time"` - States []JournalState `yaml:"journal_entries"` -} - -// JournalState represents the state of an individual event log. -type JournalState struct { - Path string `yaml:"path"` - Cursor string `yaml:"cursor"` - RealtimeTimestamp uint64 `yaml:"realtime_timestamp"` - MonotonicTimestamp uint64 `yaml:"monotonic_timestamp"` -} - -// NewCheckpoint creates and returns a new Checkpoint. This method loads state -// information from disk if it exists and starts a goroutine for persisting -// state information to disk. Shutdown should be called when finished to -// guarantee any in-memory state information is flushed to disk. -// -// file is the name of the file where event log state is persisted as YAML. -// maxUpdates is the maximum number of updates checkpoint will accept before -// triggering a flush to disk. interval is maximum amount of time that can -// pass since the last flush before triggering a flush to disk (minimum value -// is 1s). -func NewCheckpoint(file string, maxUpdates int, interval time.Duration) (*Checkpoint, error) { - c := &Checkpoint{ - done: make(chan struct{}), - file: file, - maxUpdates: maxUpdates, - flushInterval: interval, - sort: make([]string, 0, 10), - states: make(map[string]JournalState), - save: make(chan JournalState, 1), - } - - err := c.findRegistryFile() - if err != nil { - return nil, fmt.Errorf("error locating the proper registry file: %+v", err) - } - - // Minimum batch size. - if c.maxUpdates < 1 { - c.maxUpdates = 1 - } - - // Minimum flush interval. - if c.flushInterval < time.Second { - c.flushInterval = time.Second - } - - // Read existing state information: - ps, err := c.read() - if err != nil { - return nil, err - } - - if ps != nil { - for _, state := range ps.States { - c.states[state.Path] = state - } - } - - // Write the state file to verify we have have permissions. - err = c.flush() - if err != nil { - return nil, err - } - - c.wg.Add(1) - go c.run() - return c, nil -} - -// Previously the registry file was written to the root folder. It was fixed on -// 7.x but not on 6.x. Thus, migration is needed, so users avoid losing state info. -func (c *Checkpoint) findRegistryFile() error { - migratedPath := paths.Resolve(paths.Data, c.file) - - fs, err := os.Stat(c.file) - if os.IsNotExist(err) { - c.file = migratedPath - return nil - } else if err != nil { - return fmt.Errorf("error accessing previous registry file: %+v", err) - } - - // if two files are the same, do not do anything - migratedFs, err := os.Stat(migratedPath) - if err == nil { - if os.SameFile(fs, migratedFs) { - return nil - } - } - - f, err := os.Open(c.file) - if err != nil { - return err - } - defer f.Close() - - target, err := os.OpenFile(migratedPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fs.Mode()) - if err != nil { - return err - } - defer target.Close() - - if _, err := io.Copy(target, f); err != nil { - return err - } - - err = target.Sync() - if err != nil { - return fmt.Errorf("error while syncing new registry file to disk: %+v", err) - } - - c.file = migratedPath - - p := filepath.Dir(migratedPath) - pf, err := os.Open(p) - if err != nil { - return nil - } - defer pf.Close() - pf.Sync() - - return nil -} - -// run is worker loop that reads incoming state information from the save -// channel and persists it when the number of changes reaches maxEvents or -// the amount of time since the last disk write reaches flushInterval. -func (c *Checkpoint) run() { - defer c.wg.Done() - defer c.persist() - - flushTimer := time.NewTimer(c.flushInterval) - defer flushTimer.Stop() -loop: - for { - select { - case <-c.done: - break loop - case s := <-c.save: - c.lock.Lock() - c.states[s.Path] = s - c.lock.Unlock() - c.numUpdates++ - if c.numUpdates < c.maxUpdates { - continue - } - case <-flushTimer.C: - } - - c.persist() - flushTimer.Reset(c.flushInterval) - } -} - -// Shutdown stops the checkpoint worker (which persists any state to disk as -// it stops). This method blocks until the checkpoint worker shutdowns. Calling -// this method more once is safe and has no effect. -func (c *Checkpoint) Shutdown() { - c.once.Do(func() { - close(c.done) - c.wg.Wait() - }) -} - -// States returns the current in-memory event log state. This state information -// is bootstrapped with any data found on disk at creation time. -func (c *Checkpoint) States() map[string]JournalState { - c.lock.RLock() - defer c.lock.RUnlock() - - copy := make(map[string]JournalState) - for k, v := range c.states { - copy[k] = v - } - - return copy -} - -// Persist queues the given event log state information to be written to disk. -func (c *Checkpoint) Persist(path, cursor string, realTs, monotonicTs uint64) { - c.PersistState(JournalState{ - Path: path, - Cursor: cursor, - RealtimeTimestamp: realTs, - MonotonicTimestamp: monotonicTs, - }) -} - -// PersistState queues the given event log state to be written to disk. -func (c *Checkpoint) PersistState(st JournalState) { - c.save <- st -} - -// persist writes the current state to disk if the in-memory state is dirty. -func (c *Checkpoint) persist() bool { - if c.numUpdates == 0 { - return false - } - - err := c.flush() - if err != nil { - return false - } - - logp.Debug("checkpoint", "Checkpoint saved to disk. numUpdates=%d", - c.numUpdates) - c.numUpdates = 0 - return true -} - -// flush writes the current state to disk. -func (c *Checkpoint) flush() error { - c.fileLock.Lock() - defer c.fileLock.Unlock() - - tempFile := c.file + ".new" - file, err := create(tempFile) - if os.IsNotExist(err) { - // Try to create directory if it does not exist. - if createDirErr := c.createDir(); createDirErr == nil { - file, err = create(tempFile) - } - } - - if err != nil { - return fmt.Errorf("Failed to flush state to disk. %v", err) - } - - // Sort persisted eventLogs by name. - c.sort = c.sort[:0] - for k := range c.states { - c.sort = append(c.sort, k) - } - sort.Strings(c.sort) - - ps := PersistedState{ - UpdateTime: time.Now().UTC(), - States: make([]JournalState, len(c.sort)), - } - for i, name := range c.sort { - ps.States[i] = c.states[name] - } - - data, err := yaml.Marshal(ps) - if err != nil { - file.Close() - return fmt.Errorf("Failed to flush state to disk. Could not marshal "+ - "data to YAML. %v", err) - } - - _, err = file.Write(data) - if err != nil { - file.Close() - return fmt.Errorf("Failed to flush state to disk. Could not write to "+ - "%s. %v", tempFile, err) - } - - file.Close() - err = os.Rename(tempFile, c.file) - return err -} - -// read loads the persisted state from disk. If the file does not exists then -// the method returns nil and no error. -func (c *Checkpoint) read() (*PersistedState, error) { - c.fileLock.RLock() - defer c.fileLock.RUnlock() - - contents, err := ioutil.ReadFile(c.file) - if err != nil { - if os.IsNotExist(err) { - err = nil - } - return nil, err - } - - ps := &PersistedState{} - err = yaml.Unmarshal(contents, ps) - if err != nil { - return nil, err - } - - return ps, nil -} - -// createDir creates the directory in which the state file will reside if the -// directory does not already exist. -func (c *Checkpoint) createDir() error { - dir := filepath.Dir(c.file) - logp.Info("Creating %s if it does not exist.", dir) - return os.MkdirAll(dir, os.FileMode(0750)) -} diff --git a/journalbeat/checkpoint/checkpoint_test.go b/journalbeat/checkpoint/checkpoint_test.go deleted file mode 100644 index 6f6aa780d9a3..000000000000 --- a/journalbeat/checkpoint/checkpoint_test.go +++ /dev/null @@ -1,223 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !integration -// +build !integration - -package checkpoint - -import ( - "io/ioutil" - "os" - "path/filepath" - "runtime" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func eventually(t *testing.T, predicate func() (bool, error), timeout time.Duration) { - const minInterval = time.Millisecond * 5 - const maxInterval = time.Millisecond * 500 - - checkInterval := timeout / 100 - if checkInterval < minInterval { - checkInterval = minInterval - } - if checkInterval > maxInterval { - checkInterval = maxInterval - } - for deadline, first := time.Now().Add(timeout), true; first || time.Now().Before(deadline); first = false { - ok, err := predicate() - if err != nil { - t.Fatal("predicate failed with error:", err) - return - } - if ok { - return - } - time.Sleep(checkInterval) - } - t.Fatal("predicate is not true after", timeout) -} - -// Test that a write is triggered when the maximum number of updates is reached. -func TestWriteMaxUpdates(t *testing.T) { - t.Skip("Duplicate of winlogbeat/checkpoint") - dir, err := ioutil.TempDir("", "wlb-checkpoint-test") - if err != nil { - t.Fatal(err) - } - defer func() { - err := os.RemoveAll(dir) - if err != nil { - t.Fatal(err) - } - }() - - file := filepath.Join(dir, "some", "new", "dir", ".winlogbeat.yml") - if !assert.False(t, fileExists(file), "%s should not exist", file) { - return - } - - cp, err := NewCheckpoint(file, 2, time.Hour) - if err != nil { - t.Fatal(err) - } - defer cp.Shutdown() - - // Send update - it's not written to disk but it's in memory. - cp.Persist("", "", 123456, 123456) - found := false - eventually(t, func() (bool, error) { - _, found = cp.States()[""] - return found, nil - }, time.Second*15) - assert.True(t, found) - - ps, err := cp.read() - if err != nil { - t.Fatal("read failed", err) - } - assert.Len(t, ps.States, 0) - - // Send update - it is written to disk. - cp.Persist("", "", 123456, 123456) - eventually(t, func() (bool, error) { - ps, err = cp.read() - return ps != nil && len(ps.States) > 0, err - }, time.Second*15) - - if assert.Len(t, ps.States, 1, "state not written, could be a flush timing issue, retry") { - assert.Equal(t, "", ps.States[0].Path) - assert.Equal(t, "", ps.States[0].Cursor) - } -} - -// Test that a write is triggered when the maximum time period since the last -// write is reached. -func TestWriteTimedFlush(t *testing.T) { - t.Skip("Duplicate of winlogbeat/checkpoint") - dir, err := ioutil.TempDir("", "wlb-checkpoint-test") - if err != nil { - t.Fatal(err) - } - defer func() { - err := os.RemoveAll(dir) - if err != nil { - t.Fatal(err) - } - }() - - file := filepath.Join(dir, ".winlogbeat.yml") - if !assert.False(t, fileExists(file), "%s should not exist", file) { - return - } - - cp, err := NewCheckpoint(file, 100, time.Second) - if err != nil { - t.Fatal(err) - } - defer cp.Shutdown() - - // Send update then wait longer than the flush interval and it should be - // on disk. - cp.Persist("", "cursor", 123456, 123456) - eventually(t, func() (bool, error) { - ps, err := cp.read() - return ps != nil && len(ps.States) > 0, err - }, time.Second*15) - - ps, err := cp.read() - if err != nil { - t.Fatal("read failed", err) - } - if assert.Len(t, ps.States, 1) { - assert.Equal(t, "", ps.States[0].Path) - assert.Equal(t, "cursor", ps.States[0].Cursor) - } -} - -// Test that createDir creates the directory with 0750 permissions. -func TestCreateDir(t *testing.T) { - t.Skip("Duplicate of winlogbeat/checkpoint") - dir, err := ioutil.TempDir("", "wlb-checkpoint-test") - if err != nil { - t.Fatal(err) - } - defer func() { - err := os.RemoveAll(dir) - if err != nil { - t.Fatal(err) - } - }() - - stateDir := filepath.Join(dir, "state", "dir", "does", "not", "exists") - file := filepath.Join(stateDir, ".winlogbeat.yml") - cp := &Checkpoint{file: file} - - if !assert.False(t, fileExists(file), "%s should not exist", file) { - return - } - if err = cp.createDir(); err != nil { - t.Fatal("createDir", err) - } - if !assert.True(t, fileExists(stateDir), "%s should exist", file) { - return - } - - // mkdir on Windows does not pass the POSIX mode to the CreateDirectory - // syscall so doesn't test the mode. - if runtime.GOOS != "windows" { - fileInfo, err := os.Stat(stateDir) - if assert.NoError(t, err) { - assert.Equal(t, true, fileInfo.IsDir()) - assert.Equal(t, os.FileMode(0750), fileInfo.Mode().Perm()) - } - } -} - -// Test createDir when the directory already exists to verify that no error is -// returned. -func TestCreateDirAlreadyExists(t *testing.T) { - t.Skip("Duplicate of winlogbeat/checkpoint") - dir, err := ioutil.TempDir("", "wlb-checkpoint-test") - if err != nil { - t.Fatal(err) - } - defer func() { - err := os.RemoveAll(dir) - if err != nil { - t.Fatal(err) - } - }() - - file := filepath.Join(dir, ".winlogbeat.yml") - cp := &Checkpoint{file: file} - - if !assert.True(t, fileExists(dir), "%s should exist", file) { - return - } - assert.NoError(t, cp.createDir()) -} - -// fileExists returns true if the specified file exists. -func fileExists(file string) bool { - _, err := os.Stat(file) - return !os.IsNotExist(err) -} diff --git a/journalbeat/checkpoint/file_unix.go b/journalbeat/checkpoint/file_unix.go deleted file mode 100644 index 248b5301955d..000000000000 --- a/journalbeat/checkpoint/file_unix.go +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !windows -// +build !windows - -package checkpoint - -import "os" - -func create(path string) (*os.File, error) { - return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, 0600) -} diff --git a/journalbeat/checkpoint/file_windows.go b/journalbeat/checkpoint/file_windows.go deleted file mode 100644 index 267086398f3b..000000000000 --- a/journalbeat/checkpoint/file_windows.go +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package checkpoint - -import ( - "os" - "syscall" -) - -const ( - _FILE_FLAG_WRITE_THROUGH = 0x80000000 -) - -func create(path string) (*os.File, error) { - return createWriteThroughFile(path) -} - -// createWriteThroughFile creates a file whose write operations do not go -// through any intermediary cache, they go directly to disk. -func createWriteThroughFile(path string) (*os.File, error) { - if len(path) == 0 { - return nil, syscall.ERROR_FILE_NOT_FOUND - } - pathp, err := syscall.UTF16PtrFromString(path) - if err != nil { - return nil, err - } - - h, err := syscall.CreateFile( - pathp, // Path - syscall.GENERIC_READ|syscall.GENERIC_WRITE, // Access Mode - uint32(syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE), // Share Mode - nil, // Security Attributes - syscall.CREATE_ALWAYS, // Create Mode - uint32(syscall.FILE_ATTRIBUTE_NORMAL|_FILE_FLAG_WRITE_THROUGH), // Flags and Attributes - 0) // Template File - - return os.NewFile(uintptr(h), path), err -} diff --git a/journalbeat/cmd/instance/metrics.go b/journalbeat/cmd/instance/metrics.go deleted file mode 100644 index 3d75426c809c..000000000000 --- a/journalbeat/cmd/instance/metrics.go +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build linux && cgo -// +build linux,cgo - -package instance - -import ( - "fmt" - - "github.com/coreos/go-systemd/v22/sdjournal" - - "github.com/elastic/beats/v7/libbeat/monitoring" -) - -var ( - metrics *monitoring.Registry - journals map[string]*sdjournal.Journal -) - -// SetupJournalMetrics initializes and registers monitoring functions. -func SetupJournalMetrics() { - metrics = monitoring.Default.NewRegistry("journalbeat") - journals = make(map[string]*sdjournal.Journal) - - monitoring.NewFunc(metrics, "journals", reportJournalSizes, monitoring.Report) -} - -// AddJournalToMonitor adds a new journal which has to be monitored. -func AddJournalToMonitor(path string, journal *sdjournal.Journal) { - journals[path] = journal -} - -// StopMonitoringJournal stops monitoring the journal under the path. -func StopMonitoringJournal(path string) { - delete(journals, path) -} - -func reportJournalSizes(m monitoring.Mode, V monitoring.Visitor) { - i := 0 - for path, journal := range journals { - s, err := journal.GetUsage() - if err != nil { - continue - } - - ns := fmt.Sprintf("journal_%d", i) - monitoring.ReportNamespace(V, ns, func() { - monitoring.ReportString(V, "path", path) - monitoring.ReportInt(V, "size_in_bytes", int64(s)) - }) - i++ - } -} diff --git a/journalbeat/cmd/instance/metrics_other.go b/journalbeat/cmd/instance/metrics_other.go deleted file mode 100644 index 990d5f06b09f..000000000000 --- a/journalbeat/cmd/instance/metrics_other.go +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !linux || !cgo -// +build !linux !cgo - -package instance - -// SetupJournalMetrics initializes and registers monitoring functions. -func SetupJournalMetrics() {} - -// StopMonitoringJournal stops monitoring the journal under the path. -func StopMonitoringJournal(path string) {} diff --git a/journalbeat/cmd/root.go b/journalbeat/cmd/root.go deleted file mode 100644 index a7a2d8ddcaad..000000000000 --- a/journalbeat/cmd/root.go +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package cmd - -import ( - "github.com/elastic/beats/v7/journalbeat/beater" - "github.com/elastic/beats/v7/libbeat/cmd" - "github.com/elastic/beats/v7/libbeat/cmd/instance" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/ecs" - "github.com/elastic/beats/v7/libbeat/publisher/processing" - - // Import processors. - _ "github.com/elastic/beats/v7/libbeat/processors/script" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -const ( - // Name of this beat. - Name = "journalbeat" -) - -// withECSVersion is a modifier that adds ecs.version to events. -var withECSVersion = processing.WithFields(common.MapStr{ - "ecs": common.MapStr{ - "version": ecs.Version, - }, -}) - -// RootCmd to handle beats cli -var RootCmd *cmd.BeatsRootCmd - -// JournalbeatSettings contains the default settings for journalbeat -func JournalbeatSettings() instance.Settings { - return instance.Settings{ - Name: Name, - HasDashboards: false, - Processing: processing.MakeDefaultSupport(true, withECSVersion, processing.WithHost, processing.WithAgentMeta()), - } -} - -// Initialize initializes the entrypoint commands for journalbeat -func Initialize(settings instance.Settings) *cmd.BeatsRootCmd { - return cmd.GenRootCmdWithSettings(beater.New, settings) -} - -func init() { - RootCmd = Initialize(JournalbeatSettings()) -} diff --git a/journalbeat/config/config.go b/journalbeat/config/config.go deleted file mode 100644 index 1771a2a4e7c9..000000000000 --- a/journalbeat/config/config.go +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// Config is put into a different package to prevent cyclic imports in case -// it is needed in several locations - -package config - -import ( - "github.com/elastic/beats/v7/libbeat/common" -) - -// Config stores the configuration of Journalbeat -type Config struct { - Inputs []*common.Config `config:"inputs"` - RegistryFile string `config:"registry_file"` -} - -var ( - // DefaultConfig are the defaults of a Journalbeat instance - DefaultConfig = Config{ - RegistryFile: "registry", - } -) diff --git a/journalbeat/conftest.py b/journalbeat/conftest.py deleted file mode 100644 index 2f3f81995598..000000000000 --- a/journalbeat/conftest.py +++ /dev/null @@ -1,4 +0,0 @@ -import os -import sys - -sys.path.append(os.path.join(os.path.dirname(__file__), '../libbeat/tests/system')) diff --git a/journalbeat/docs/config-options.asciidoc b/journalbeat/docs/config-options.asciidoc deleted file mode 100644 index 106318ceb6dc..000000000000 --- a/journalbeat/docs/config-options.asciidoc +++ /dev/null @@ -1,251 +0,0 @@ -[id="configuration-{beatname_lc}-options"] -== Configure inputs - -++++ -Inputs -++++ - -By default, {beatname_uc} reads log events from the default systemd journals. To -specify other journal files, set the <<{beatname_lc}-paths,`paths`>> option in -the +{beatname_lc}.inputs+ section of the +{beatname_lc}.yml+ file. Each path -can be a directory path (to collect events from all journals in a directory), or -a file path. For example: - -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: - - "/dev/log" - - "/var/log/messages/my-journal-file.journal" ----- - -Within the configuration file, you can also specify options that control how -{beatname_uc} reads the journal files and which fields are sent to the -configured output. See <<{beatname_lc}-options>> for a list of available -options. - -The following examples show how to configure {beatname_uc} for some common use -cases. - -[[monitor-multiple-journals]] -.Example 1: Monitor multiple journals under the same directory -This example configures {beatname_uc} to read from multiple journals that are -stored under the same directory. {beatname_uc} merges all journals under the -directory into a single event stream and reads the events. With `seek` set to -`cursor`, {beatname_uc} starts reading at the beginning of the journal, but will -continue reading at the last known position after a reload or restart. -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: ["/path/to/journal/directory"] - seek: cursor ----- - -[[filter-using-field-names]] -.Example 2: Fetch log events for Redis running on Docker (uses field names from systemd) -This example configures {beatname_uc} to fetch log events for Redis running in a -Docker container. The fields are matched using field names from the systemd -journal. -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: [] - include_matches: - - "CONTAINER_TAG=redis" - - "_COMM=redis" ----- - -[[filter-using-translated-names]] -.Example 3: Fetch log events for Redis running on Docker (uses translated field names) -This example also configures {beatname_uc} to fetch log events for Redis running -in a Docker container. However, in this example the fields are matched using the -<> provided by {beatname_uc}. -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: [] - include_matches: - - "container.image.tag=redis" - - "process.name=redis" ----- - -[id="{beatname_lc}-options"] -[float] -=== Configuration options -You can specify the following options to configure how {beatname_uc} reads the -journal files. - -[float] -[id="{beatname_lc}-id"] -==== `id` - -An optional unique identifier for the input. By providing a unique `id` you can -operate multiple inputs on the same journal. This allows each input's cursor -to be persisted independently in the registry file. - ----- -{beatname_lc}.inputs: -- id: consul.service - paths: [] - include_matches: - - _SYSTEMD_UNIT=consul.service - -- id: vault.service - paths: [] - include_matches: - - _SYSTEMD_UNIT=vault.service ----- - -[float] -[id="{beatname_lc}-paths"] -==== `paths` - -A list of paths that will be crawled and fetched. Each path can be a directory -path (to collect events from all journals in a directory), or a file path. If -you specify a directory, {beatname_uc} merges all journals under the directory -into a single journal and reads them. - -If no paths are specified, {beatname_uc} reads from the default journal. - -[float] -[id="{beatname_lc}-backoff"] -==== `backoff` - -The number of seconds to wait before trying to read again from journals. The -default is 1s. - -[float] -[id="{beatname_lc}-max-backoff"] -==== `max_backoff` - -The maximum number of seconds to wait before attempting to read again from -journals. The default is 60s. - -[float] -[id="seek"] -==== `seek` - -The position to start reading the journal from. Valid settings are: - -* `head`: Starts reading at the beginning of the journal. After a restart, -{beatname_uc} resends all log messages in the journal. -* `tail`: Starts reading at the end of the journal. After a restart, -{beatname_uc} resends the last message, which might result in duplicates. If -multiple log messages are written to a journal while {beatname_uc} is down, -only the last log message is sent on restart. -* `cursor`: On first read, starts reading at the beginning of the journal. After a -reload or restart, continues reading at the last known position. - -When specified under `paths`, the `seek` setting applies to all journals under -the configured paths. When specified directly under the +{beatname_lc}+ -namespace, the setting applies to all journals read by {beatname_uc}. - -If you have old log files and want to skip lines, start {beatname_uc} with -`seek: tail` specified. Then stop {beatname_uc}, set `seek: cursor`, and restart -{beatname_uc}. - -[float] -[id="include-matches"] -==== `include_matches` - -A list of filter expressions used to match fields. The format of the expression -is `field=value`. {beatname_uc} fetches all events that exactly match the -expressions. Pattern matching is not supported. - -To reference fields, use one of the following: - -* The field name used by the systemd journal. For example, -`CONTAINER_TAG=redis` (<>). -* The <> used by -{beatname_uc}. For example, `container.image.tag=redis` -(<>). {beatname_uc} -does not translate all fields from the journal. For custom fields, use the name -specified in the systemd journal. - -When specified under `paths`, the `include_matches` filter is applied to all -journals under the configured paths. When specified directly under the -+{beatname_lc}+ namespace, the setting applies to all journals read by -{beatname_uc}. - -[float] -[[translated-fields]] -=== Translated field names - -You can use the following translated names in filter expressions to reference -journald fields: - -[horizontal] -*Journald field name*:: *Translated name* -`COREDUMP_UNIT`:: `journald.coredump.unit` -`COREDUMP_USER_UNIT`:: `journald.coredump.user_unit` -`OBJECT_AUDIT_LOGINUID`:: `journald.object.audit.login_uid` -`OBJECT_AUDIT_SESSION`:: `journald.object.audit.session` -`OBJECT_CMDLINE`:: `journald.object.cmd` -`OBJECT_COMM`:: `journald.object.name` -`OBJECT_EXE`:: `journald.object.executable` -`OBJECT_GID`:: `journald.object.gid` -`OBJECT_PID`:: `journald.object.pid` -`OBJECT_SYSTEMD_OWNER_UID`:: `journald.object.systemd.owner_uid` -`OBJECT_SYSTEMD_SESSION`:: `journald.object.systemd.session` -`OBJECT_SYSTEMD_UNIT`:: `journald.object.systemd.unit` -`OBJECT_SYSTEMD_USER_UNIT`:: `journald.object.systemd.user_unit` -`OBJECT_UID`:: `journald.object.uid` -`_AUDIT_LOGINUID`:: `process.audit.login_uid` -`_AUDIT_SESSION`:: `process.audit.session` -`_BOOT_ID`:: `host.boot_id` -`_CAP_EFFECTIVE`:: `process.capabilites` -`_CMDLINE`:: `process.cmd` -`_CODE_FILE`:: `journald.code.file` -`_CODE_FUNC`:: `journald.code.func` -`_CODE_LINE`:: `journald.code.line` -`_COMM`:: `process.name` -`_EXE`:: `process.executable` -`_GID`:: `process.uid` -`_HOSTNAME`:: `host.name` -`_KERNEL_DEVICE`:: `journald.kernel.device` -`_KERNEL_SUBSYSTEM`:: `journald.kernel.subsystem` -`_MACHINE_ID`:: `host.id` -`_MESSAGE`:: `message` -`_PID`:: `process.pid` -`_PRIORITY`:: `syslog.priority` -`_SYSLOG_FACILITY`:: `syslog.facility` -`_SYSLOG_IDENTIFIER`:: `syslog.identifier` -`_SYSLOG_PID`:: `syslog.pid` -`_SYSTEMD_CGROUP`:: `systemd.cgroup` -`_SYSTEMD_INVOCATION_ID`:: `systemd.invocation_id` -`_SYSTEMD_OWNER_UID`:: `systemd.owner_uid` -`_SYSTEMD_SESSION`:: `systemd.session` -`_SYSTEMD_SLICE`:: `systemd.slice` -`_SYSTEMD_UNIT`:: `systemd.unit` -`_SYSTEMD_USER_SLICE`:: `systemd.user_slice` -`_SYSTEMD_USER_UNIT`:: `systemd.user_unit` -`_TRANSPORT`:: `systemd.transport` -`_UDEV_DEVLINK`:: `journald.kernel.device_symlinks` -`_UDEV_DEVNODE`:: `journald.kernel.device_node_path` -`_UDEV_SYSNAME`:: `journald.kernel.device_name` -`_UID`:: `process.uid` - - -The following translated fields for -https://docs.docker.com/config/containers/logging/journald/[Docker] are also -available: - -[horizontal] -`CONTAINER_ID`:: `container.id_truncated` -`CONTAINER_ID_FULL`:: `container.id` -`CONTAINER_NAME`:: `container.name` -`CONTAINER_PARTIAL_MESSAGE`:: `container.partial` -`CONTAINER_TAG`:: `container.image.tag` - -[float] -[id="index"] -==== `index` - -If present, this formatted string overrides the index for events from this input -(for elasticsearch outputs), or sets the `raw_index` field of the event's -metadata (for other outputs). This string can only refer to the agent name and -version and the event timestamp; for access to dynamic fields, use -`output.elasticsearch.index` or a processor. - -Example value: `"%{[agent.name]}-myindex-%{+yyyy.MM.dd}"` might -expand to `"journalbeat-myindex-2019.12.13"`. diff --git a/journalbeat/docs/configuring-howto.asciidoc b/journalbeat/docs/configuring-howto.asciidoc deleted file mode 100644 index 246880468e33..000000000000 --- a/journalbeat/docs/configuring-howto.asciidoc +++ /dev/null @@ -1,59 +0,0 @@ -[id="configuring-howto-{beatname_lc}"] -= Configure {beatname_uc} - -[partintro] --- -++++ -Configure -++++ - -include::{libbeat-dir}/shared/configuring-intro.asciidoc[] - -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <<{beatname_lc}-reference-yml>> - --- - -include::./config-options.asciidoc[] - -include::./general-options.asciidoc[] - -include::{libbeat-dir}/shared-path-config.asciidoc[] - -include::{libbeat-dir}/outputconfig.asciidoc[] - -ifndef::no_kerberos[] -include::{libbeat-dir}/shared-kerberos-config.asciidoc[] -endif::[] - -include::{libbeat-dir}/shared-ssl-config.asciidoc[] - -include::{libbeat-dir}/shared-ilm.asciidoc[] - -include::{libbeat-dir}/setup-config.asciidoc[] - -include::./filtering.asciidoc[] - -include::{libbeat-dir}/queueconfig.asciidoc[] - -include::{libbeat-dir}/loggingconfig.asciidoc[] - -include::{libbeat-dir}/http-endpoint.asciidoc[] - -include::{libbeat-dir}/regexp.asciidoc[] - -include::{libbeat-dir}/shared-instrumentation.asciidoc[] - -include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/journalbeat/docs/faq.asciidoc b/journalbeat/docs/faq.asciidoc deleted file mode 100644 index bbe89a61c721..000000000000 --- a/journalbeat/docs/faq.asciidoc +++ /dev/null @@ -1,10 +0,0 @@ -[[faq]] -== Common problems - -This section describes common problems you might encounter with -{beatname_uc}. Also check out the -https://discuss.elastic.co/c/beats/{beatname_lc}[{beatname_uc} discussion forum]. - -include::{libbeat-dir}/faq-limit-bandwidth.asciidoc[] - -include::{libbeat-dir}/shared-faq.asciidoc[] diff --git a/journalbeat/docs/fields.asciidoc b/journalbeat/docs/fields.asciidoc deleted file mode 100644 index f69b2225c1ff..000000000000 --- a/journalbeat/docs/fields.asciidoc +++ /dev/null @@ -1,16301 +0,0 @@ - -//// -This file is generated! See _meta/fields.yml and scripts/generate_fields_docs.py -//// - -[[exported-fields]] -= Exported fields - -[partintro] - --- -This document describes the fields that are exported by Journalbeat. They are -grouped in the following categories: - -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> -* <> - --- -[[exported-fields-beat-common]] -== Beat fields - -Contains common beat fields available in all event types. - - - -*`agent.hostname`*:: -+ --- -Deprecated - use agent.name or agent.id to identify an agent. - - -type: alias - -alias to: agent.name - --- - -*`beat.timezone`*:: -+ --- -type: alias - -alias to: event.timezone - --- - -*`fields`*:: -+ --- -Contains user configurable fields. - - -type: object - --- - -*`beat.name`*:: -+ --- -type: alias - -alias to: host.name - --- - -*`beat.hostname`*:: -+ --- -type: alias - -alias to: agent.name - --- - -*`timeseries.instance`*:: -+ --- -Time series instance id - -type: keyword - --- - -[[exported-fields-cloud]] -== Cloud provider metadata fields - -Metadata from cloud providers added by the add_cloud_metadata processor. - - - -*`cloud.image.id`*:: -+ --- -Image ID for the cloud instance. - - -example: ami-abcd1234 - --- - -*`meta.cloud.provider`*:: -+ --- -type: alias - -alias to: cloud.provider - --- - -*`meta.cloud.instance_id`*:: -+ --- -type: alias - -alias to: cloud.instance.id - --- - -*`meta.cloud.instance_name`*:: -+ --- -type: alias - -alias to: cloud.instance.name - --- - -*`meta.cloud.machine_type`*:: -+ --- -type: alias - -alias to: cloud.machine.type - --- - -*`meta.cloud.availability_zone`*:: -+ --- -type: alias - -alias to: cloud.availability_zone - --- - -*`meta.cloud.project_id`*:: -+ --- -type: alias - -alias to: cloud.project.id - --- - -*`meta.cloud.region`*:: -+ --- -type: alias - -alias to: cloud.region - --- - -[[exported-fields-common]] -== Common Journalbeat fields - -Contains common fields available in all event types. - - - -[float] -=== coredump - -Fields used by systemd-coredump kernel helper. - - - -*`coredump.unit`*:: -+ --- -Annotations of messages containing coredumps from system units. - - -type: keyword - --- - -*`coredump.user_unit`*:: -+ --- -Annotations of messages containing coredumps from user units. - - -type: keyword - --- - -[float] -=== journald - -Fields provided by journald. - - - -[float] -=== object - -Fields to log on behalf of a different program. - - - -[float] -=== audit - -Audit fields of event. - - - -*`journald.object.audit.login_uid`*:: -+ --- -The login UID of the object process. - - -type: long - -example: 1000 - -required: False - --- - -*`journald.object.audit.session`*:: -+ --- -The audit session of the object process. - - -type: long - -example: 3 - -required: False - --- - -*`journald.object.process.command_line`*:: -+ --- -The command line of the process. - - -type: keyword - -example: /lib/systemd/systemd --user - -required: False - --- - -*`journald.object.process.name`*:: -+ --- -Name of the executable. - - -type: keyword - -example: /lib/systemd/systemd - -required: False - --- - -*`journald.object.process.executable`*:: -+ --- -Path to the the executable. - - -type: keyword - -example: /lib/systemd/systemd - -required: False - --- - -*`journald.object.uid`*:: -+ --- -UID of the object process. - - -type: long - -required: False - --- - -*`journald.object.gid`*:: -+ --- -GID of the object process. - - -type: long - -required: False - --- - -*`journald.object.pid`*:: -+ --- -PID of the object process. - - -type: long - -required: False - --- - -[float] -=== systemd - -Systemd fields of event. - - - -*`journald.object.systemd.owner_uid`*:: -+ --- -The UID of the owner. - - -type: long - -required: False - --- - -*`journald.object.systemd.session`*:: -+ --- -The ID of the systemd session. - - -type: keyword - -required: False - --- - -*`journald.object.systemd.unit`*:: -+ --- -The name of the systemd unit. - - -type: keyword - -required: False - --- - -*`journald.object.systemd.user_unit`*:: -+ --- -The name of the systemd user unit. - - -type: keyword - -required: False - --- - -[float] -=== kernel - -Fields to log on behalf of a different program. - - - -*`journald.kernel.device`*:: -+ --- -The kernel device name. - - -type: keyword - -required: False - --- - -*`journald.kernel.subsystem`*:: -+ --- -The kernel subsystem name. - - -type: keyword - -required: False - --- - -*`journald.kernel.device_symlinks`*:: -+ --- -Additional symlink names pointing to the device node in /dev. - - -type: keyword - -required: False - --- - -*`journald.kernel.device_node_path`*:: -+ --- -The device node path of this device in /dev. - - -type: keyword - -required: False - --- - -*`journald.kernel.device_name`*:: -+ --- -The kernel device name as it shows up in the device tree below /sys. - - -type: keyword - -required: False - --- - -[float] -=== code - -Fields of the code generating the event. - - - -*`journald.code.file`*:: -+ --- -The name of the source file where the log is generated. - - -type: keyword - -example: ../src/core/manager.c - -required: False - --- - -*`journald.code.function`*:: -+ --- -The name of the function which generated the log message. - - -type: keyword - -example: job_log_status_message - -required: False - --- - -*`journald.code.line`*:: -+ --- -The line number of the code which generated the log message. - - -type: long - -example: 123 - -required: False - --- - -[float] -=== process - -Fields to log on behalf of a different program. - - - -[float] -=== audit - -Audit fields of event. - - - -*`journald.process.audit.loginuid`*:: -+ --- -The login UID of the source process. - - -type: long - -example: 1000 - -required: False - --- - -*`journald.process.audit.session`*:: -+ --- -The audit session of the source process. - - -type: long - -example: 3 - -required: False - --- - -*`journald.process.command_line`*:: -+ --- -The command line of the process. - - -type: keyword - -example: /lib/systemd/systemd --user - -required: False - --- - -*`journald.process.name`*:: -+ --- -Name of the executable. - - -type: keyword - -example: /lib/systemd/systemd - -required: False - --- - -*`journald.process.executable`*:: -+ --- -Path to the the executable. - - -type: keyword - -example: /lib/systemd/systemd - -required: False - --- - -*`journald.process.pid`*:: -+ --- -The ID of the process which logged the message. - - -type: long - -example: 1 - -required: False - --- - -*`journald.process.gid`*:: -+ --- -The ID of the group which runs the process. - - -type: long - -example: 1 - -required: False - --- - -*`journald.process.uid`*:: -+ --- -The ID of the user which runs the process. - - -type: long - -example: 1 - -required: False - --- - -*`journald.process.capabilities`*:: -+ --- -The effective capabilities of the process. - - -required: False - --- - -[float] -=== systemd - -Fields of systemd. - - - -*`systemd.invocation_id`*:: -+ --- -The invocation ID for the runtime cycle of the unit the message was generated in. - - -type: keyword - -example: 8450f1672de646c88cd133aadd4f2d70 - -required: False - --- - -*`systemd.cgroup`*:: -+ --- -The control group path in the systemd hierarchy. - - -type: keyword - -example: /user.slice/user-1234.slice/session-2.scope - -required: False - --- - -*`systemd.owner_uid`*:: -+ --- -The owner UID of the systemd user unit or systemd session. - - -type: long - -required: False - --- - -*`systemd.session`*:: -+ --- -The ID of the systemd session. - - -type: keyword - -required: False - --- - -*`systemd.slice`*:: -+ --- -The systemd slice unit. - - -type: keyword - -example: user-1234.slice - -required: False - --- - -*`systemd.user_slice`*:: -+ --- -The systemd user slice unit. - - -type: keyword - -required: False - --- - -*`systemd.unit`*:: -+ --- -The name of the systemd unit. - - -type: keyword - -example: nginx.service - -required: False - --- - -*`systemd.user_unit`*:: -+ --- -The name of the systemd user unit. - - -type: keyword - -example: user-1234.slice - -required: False - --- - -*`systemd.transport`*:: -+ --- -How the log message was received by journald. - - -type: keyword - -example: syslog - -required: True - --- - -[float] -=== host - -Fields of the host. - - - -*`host.boot_id`*:: -+ --- -The boot ID for the boot the log was generated in. - - -type: keyword - -example: dd8c974asdf01dbe2ef26d7fasdf264c9 - -required: False - --- - -[float] -=== syslog - -Fields of the code generating the event. - - - -*`syslog.priority`*:: -+ --- -The priority of the message. A syslog compatibility field. - - -type: long - -example: 1 - -required: False - --- - -*`syslog.facility`*:: -+ --- -The facility of the message. A syslog compatibility field. - - -type: long - -example: 1 - -required: False - --- - -*`syslog.identifier`*:: -+ --- -The identifier of the message. A syslog compatibility field. - - -type: keyword - -example: su - -required: False - --- - -*`custom`*:: -+ --- -Arbitrary fields coming from processes. - - -type: nested - -required: False - --- - -*`read_timestamp`*:: -+ --- -type: alias - -alias to: event.created - --- - - - -*`container.log.tag`*:: -+ --- -User defined tag of a container. - - -type: keyword - --- - -[[exported-fields-docker-processor]] -== Docker fields - -Docker stats collected from Docker. - - - - -*`docker.container.id`*:: -+ --- -type: alias - -alias to: container.id - --- - -*`docker.container.image`*:: -+ --- -type: alias - -alias to: container.image.name - --- - -*`docker.container.name`*:: -+ --- -type: alias - -alias to: container.name - --- - -*`docker.container.labels`*:: -+ --- -Image labels. - - -type: object - --- - -[[exported-fields-ecs]] -== ECS fields - - -This section defines Elastic Common Schema (ECS) fields—a common set of fields -to be used when storing event data in {es}. - -This is an exhaustive list, and fields listed here are not necessarily used by {beatname_uc}. -The goal of ECS is to enable and encourage users of {es} to normalize their event data, -so that they can better analyze, visualize, and correlate the data represented in their events. - -See the {ecs-ref}[ECS reference] for more information. - -*`@timestamp`*:: -+ --- -Date/time when the event originated. -This is the date/time extracted from the event, typically representing when the event was generated by the source. -If the event source has no original timestamp, this value is typically populated by the first time the event was received by the pipeline. -Required field for all events. - -type: date - -example: 2016-05-23T08:05:34.853Z - -required: True - --- - -*`labels`*:: -+ --- -Custom key/value pairs. -Can be used to add meta information to events. Should not contain nested objects. All values are stored as keyword. -Example: `docker` and `k8s` labels. - -type: object - -example: {"application": "foo-bar", "env": "production"} - --- - -*`message`*:: -+ --- -For log events the message field contains the log message, optimized for viewing in a log viewer. -For structured logs without an original message field, other fields can be concatenated to form a human-readable summary of the event. -If multiple messages exist, they can be combined into one message. - -type: match_only_text - -example: Hello World - --- - -*`tags`*:: -+ --- -List of keywords used to tag each event. - -type: keyword - -example: ["production", "env2"] - --- - -[float] -=== agent - -The agent fields contain the data about the software entity, if any, that collects, detects, or observes events on a host, or takes measurements on a host. -Examples include Beats. Agents may also run on observers. ECS agent.* fields shall be populated with details of the agent running on the host or observer where the event happened or the measurement was taken. - - -*`agent.build.original`*:: -+ --- -Extended build information for the agent. -This field is intended to contain any build information that a data source may provide, no specific formatting is required. - -type: keyword - -example: metricbeat version 7.6.0 (amd64), libbeat 7.6.0 [6a23e8f8f30f5001ba344e4e54d8d9cb82cb107c built 2020-02-05 23:10:10 +0000 UTC] - --- - -*`agent.ephemeral_id`*:: -+ --- -Ephemeral identifier of this agent (if one exists). -This id normally changes across restarts, but `agent.id` does not. - -type: keyword - -example: 8a4f500f - --- - -*`agent.id`*:: -+ --- -Unique identifier of this agent (if one exists). -Example: For Beats this would be beat.id. - -type: keyword - -example: 8a4f500d - --- - -*`agent.name`*:: -+ --- -Custom name of the agent. -This is a name that can be given to an agent. This can be helpful if for example two Filebeat instances are running on the same host but a human readable separation is needed on which Filebeat instance data is coming from. -If no name is given, the name is often left empty. - -type: keyword - -example: foo - --- - -*`agent.type`*:: -+ --- -Type of the agent. -The agent type always stays the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine. - -type: keyword - -example: filebeat - --- - -*`agent.version`*:: -+ --- -Version of the agent. - -type: keyword - -example: 6.0.0-rc2 - --- - -[float] -=== as - -An autonomous system (AS) is a collection of connected Internet Protocol (IP) routing prefixes under the control of one or more network operators on behalf of a single administrative entity or domain that presents a common, clearly defined routing policy to the internet. - - -*`as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -[float] -=== client - -A client is defined as the initiator of a network connection for events regarding sessions, connections, or bidirectional flow records. -For TCP events, the client is the initiator of the TCP connection that sends the SYN packet(s). For other protocols, the client is generally the initiator or requestor in the network transaction. Some systems use the term "originator" to refer the client in TCP connections. The client fields describe details about the system acting as the client in the network event. Client fields are usually populated in conjunction with server fields. Client fields are generally not populated for packet-level events. -Client / server representations can add semantic context to an exchange, which is helpful to visualize the data in certain situations. If your context falls in that category, you should still ensure that source and destination are filled appropriately. - - -*`client.address`*:: -+ --- -Some event client addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. -Then it should be duplicated to `.ip` or `.domain`, depending on which one it is. - -type: keyword - --- - -*`client.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`client.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`client.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`client.bytes`*:: -+ --- -Bytes sent from the client to the server. - -type: long - -example: 184 - -format: bytes - --- - -*`client.domain`*:: -+ --- -Client domain. - -type: keyword - --- - -*`client.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`client.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`client.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`client.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`client.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`client.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`client.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`client.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`client.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`client.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`client.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`client.ip`*:: -+ --- -IP address of the client (IPv4 or IPv6). - -type: ip - --- - -*`client.mac`*:: -+ --- -MAC address of the client. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: 00-00-5E-00-53-23 - --- - -*`client.nat.ip`*:: -+ --- -Translated IP of source based NAT sessions (e.g. internal client to internet). -Typically connections traversing load balancers, firewalls, or routers. - -type: ip - --- - -*`client.nat.port`*:: -+ --- -Translated port of source based NAT sessions (e.g. internal client to internet). -Typically connections traversing load balancers, firewalls, or routers. - -type: long - -format: string - --- - -*`client.packets`*:: -+ --- -Packets sent from the client to the server. - -type: long - -example: 12 - --- - -*`client.port`*:: -+ --- -Port of the client. - -type: long - -format: string - --- - -*`client.registered_domain`*:: -+ --- -The highest registered client domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`client.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`client.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`client.user.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`client.user.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`client.user.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`client.user.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`client.user.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`client.user.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`client.user.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`client.user.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`client.user.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`client.user.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`client.user.name.text`*:: -+ --- -type: match_only_text - --- - -*`client.user.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -[float] -=== cloud - -Fields related to the cloud or infrastructure the events are coming from. - - -*`cloud.account.id`*:: -+ --- -The cloud account or organization id used to identify different entities in a multi-tenant environment. -Examples: AWS account id, Google Cloud ORG Id, or other unique identifier. - -type: keyword - -example: 666777888999 - --- - -*`cloud.account.name`*:: -+ --- -The cloud account name or alias used to identify different entities in a multi-tenant environment. -Examples: AWS account name, Google Cloud ORG display name. - -type: keyword - -example: elastic-dev - --- - -*`cloud.availability_zone`*:: -+ --- -Availability zone in which this host, resource, or service is located. - -type: keyword - -example: us-east-1c - --- - -*`cloud.instance.id`*:: -+ --- -Instance ID of the host machine. - -type: keyword - -example: i-1234567890abcdef0 - --- - -*`cloud.instance.name`*:: -+ --- -Instance name of the host machine. - -type: keyword - --- - -*`cloud.machine.type`*:: -+ --- -Machine type of the host machine. - -type: keyword - -example: t2.medium - --- - -*`cloud.origin.account.id`*:: -+ --- -The cloud account or organization id used to identify different entities in a multi-tenant environment. -Examples: AWS account id, Google Cloud ORG Id, or other unique identifier. - -type: keyword - -example: 666777888999 - --- - -*`cloud.origin.account.name`*:: -+ --- -The cloud account name or alias used to identify different entities in a multi-tenant environment. -Examples: AWS account name, Google Cloud ORG display name. - -type: keyword - -example: elastic-dev - --- - -*`cloud.origin.availability_zone`*:: -+ --- -Availability zone in which this host, resource, or service is located. - -type: keyword - -example: us-east-1c - --- - -*`cloud.origin.instance.id`*:: -+ --- -Instance ID of the host machine. - -type: keyword - -example: i-1234567890abcdef0 - --- - -*`cloud.origin.instance.name`*:: -+ --- -Instance name of the host machine. - -type: keyword - --- - -*`cloud.origin.machine.type`*:: -+ --- -Machine type of the host machine. - -type: keyword - -example: t2.medium - --- - -*`cloud.origin.project.id`*:: -+ --- -The cloud project identifier. -Examples: Google Cloud Project id, Azure Project id. - -type: keyword - -example: my-project - --- - -*`cloud.origin.project.name`*:: -+ --- -The cloud project name. -Examples: Google Cloud Project name, Azure Project name. - -type: keyword - -example: my project - --- - -*`cloud.origin.provider`*:: -+ --- -Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean. - -type: keyword - -example: aws - --- - -*`cloud.origin.region`*:: -+ --- -Region in which this host, resource, or service is located. - -type: keyword - -example: us-east-1 - --- - -*`cloud.origin.service.name`*:: -+ --- -The cloud service name is intended to distinguish services running on different platforms within a provider, eg AWS EC2 vs Lambda, GCP GCE vs App Engine, Azure VM vs App Server. -Examples: app engine, app service, cloud run, fargate, lambda. - -type: keyword - -example: lambda - --- - -*`cloud.project.id`*:: -+ --- -The cloud project identifier. -Examples: Google Cloud Project id, Azure Project id. - -type: keyword - -example: my-project - --- - -*`cloud.project.name`*:: -+ --- -The cloud project name. -Examples: Google Cloud Project name, Azure Project name. - -type: keyword - -example: my project - --- - -*`cloud.provider`*:: -+ --- -Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean. - -type: keyword - -example: aws - --- - -*`cloud.region`*:: -+ --- -Region in which this host, resource, or service is located. - -type: keyword - -example: us-east-1 - --- - -*`cloud.service.name`*:: -+ --- -The cloud service name is intended to distinguish services running on different platforms within a provider, eg AWS EC2 vs Lambda, GCP GCE vs App Engine, Azure VM vs App Server. -Examples: app engine, app service, cloud run, fargate, lambda. - -type: keyword - -example: lambda - --- - -*`cloud.target.account.id`*:: -+ --- -The cloud account or organization id used to identify different entities in a multi-tenant environment. -Examples: AWS account id, Google Cloud ORG Id, or other unique identifier. - -type: keyword - -example: 666777888999 - --- - -*`cloud.target.account.name`*:: -+ --- -The cloud account name or alias used to identify different entities in a multi-tenant environment. -Examples: AWS account name, Google Cloud ORG display name. - -type: keyword - -example: elastic-dev - --- - -*`cloud.target.availability_zone`*:: -+ --- -Availability zone in which this host, resource, or service is located. - -type: keyword - -example: us-east-1c - --- - -*`cloud.target.instance.id`*:: -+ --- -Instance ID of the host machine. - -type: keyword - -example: i-1234567890abcdef0 - --- - -*`cloud.target.instance.name`*:: -+ --- -Instance name of the host machine. - -type: keyword - --- - -*`cloud.target.machine.type`*:: -+ --- -Machine type of the host machine. - -type: keyword - -example: t2.medium - --- - -*`cloud.target.project.id`*:: -+ --- -The cloud project identifier. -Examples: Google Cloud Project id, Azure Project id. - -type: keyword - -example: my-project - --- - -*`cloud.target.project.name`*:: -+ --- -The cloud project name. -Examples: Google Cloud Project name, Azure Project name. - -type: keyword - -example: my project - --- - -*`cloud.target.provider`*:: -+ --- -Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean. - -type: keyword - -example: aws - --- - -*`cloud.target.region`*:: -+ --- -Region in which this host, resource, or service is located. - -type: keyword - -example: us-east-1 - --- - -*`cloud.target.service.name`*:: -+ --- -The cloud service name is intended to distinguish services running on different platforms within a provider, eg AWS EC2 vs Lambda, GCP GCE vs App Engine, Azure VM vs App Server. -Examples: app engine, app service, cloud run, fargate, lambda. - -type: keyword - -example: lambda - --- - -[float] -=== code_signature - -These fields contain information about binary code signatures. - - -*`code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -[float] -=== container - -Container fields are used for meta information about the specific container that is the source of information. -These fields help correlate data based containers from any runtime. - - -*`container.id`*:: -+ --- -Unique container id. - -type: keyword - --- - -*`container.image.name`*:: -+ --- -Name of the image the container was built on. - -type: keyword - --- - -*`container.image.tag`*:: -+ --- -Container image tags. - -type: keyword - --- - -*`container.labels`*:: -+ --- -Image labels. - -type: object - --- - -*`container.name`*:: -+ --- -Container name. - -type: keyword - --- - -*`container.runtime`*:: -+ --- -Runtime managing this container. - -type: keyword - -example: docker - --- - -[float] -=== data_stream - -The data_stream fields take part in defining the new data stream naming scheme. -In the new data stream naming scheme the value of the data stream fields combine to the name of the actual data stream in the following manner: `{data_stream.type}-{data_stream.dataset}-{data_stream.namespace}`. This means the fields can only contain characters that are valid as part of names of data streams. More details about this can be found in this https://www.elastic.co/blog/an-introduction-to-the-elastic-data-stream-naming-scheme[blog post]. -An Elasticsearch data stream consists of one or more backing indices, and a data stream name forms part of the backing indices names. Due to this convention, data streams must also follow index naming restrictions. For example, data stream names cannot include `\`, `/`, `*`, `?`, `"`, `<`, `>`, `|`, ` ` (space character), `,`, or `#`. Please see the Elasticsearch reference for additional https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html#indices-create-api-path-params[restrictions]. - - -*`data_stream.dataset`*:: -+ --- -The field can contain anything that makes sense to signify the source of the data. -Examples include `nginx.access`, `prometheus`, `endpoint` etc. For data streams that otherwise fit, but that do not have dataset set we use the value "generic" for the dataset value. `event.dataset` should have the same value as `data_stream.dataset`. -Beyond the Elasticsearch data stream naming criteria noted above, the `dataset` value has additional restrictions: - * Must not contain `-` - * No longer than 100 characters - -type: constant_keyword - -example: nginx.access - --- - -*`data_stream.namespace`*:: -+ --- -A user defined namespace. Namespaces are useful to allow grouping of data. -Many users already organize their indices this way, and the data stream naming scheme now provides this best practice as a default. Many users will populate this field with `default`. If no value is used, it falls back to `default`. -Beyond the Elasticsearch index naming criteria noted above, `namespace` value has the additional restrictions: - * Must not contain `-` - * No longer than 100 characters - -type: constant_keyword - -example: production - --- - -*`data_stream.type`*:: -+ --- -An overarching type for the data stream. -Currently allowed values are "logs" and "metrics". We expect to also add "traces" and "synthetics" in the near future. - -type: constant_keyword - -example: logs - --- - -[float] -=== destination - -Destination fields capture details about the receiver of a network exchange/packet. These fields are populated from a network event, packet, or other event containing details of a network transaction. -Destination fields are usually populated in conjunction with source fields. The source and destination fields are considered the baseline and should always be filled if an event contains source and destination details from a network transaction. If the event also contains identification of the client and server roles, then the client and server fields should also be populated. - - -*`destination.address`*:: -+ --- -Some event destination addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. -Then it should be duplicated to `.ip` or `.domain`, depending on which one it is. - -type: keyword - --- - -*`destination.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`destination.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`destination.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`destination.bytes`*:: -+ --- -Bytes sent from the destination to the source. - -type: long - -example: 184 - -format: bytes - --- - -*`destination.domain`*:: -+ --- -Destination domain. - -type: keyword - --- - -*`destination.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`destination.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`destination.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`destination.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`destination.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`destination.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`destination.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`destination.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`destination.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`destination.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`destination.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`destination.ip`*:: -+ --- -IP address of the destination (IPv4 or IPv6). - -type: ip - --- - -*`destination.mac`*:: -+ --- -MAC address of the destination. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: 00-00-5E-00-53-23 - --- - -*`destination.nat.ip`*:: -+ --- -Translated ip of destination based NAT sessions (e.g. internet to private DMZ) -Typically used with load balancers, firewalls, or routers. - -type: ip - --- - -*`destination.nat.port`*:: -+ --- -Port the source session is translated to by NAT Device. -Typically used with load balancers, firewalls, or routers. - -type: long - -format: string - --- - -*`destination.packets`*:: -+ --- -Packets sent from the destination to the source. - -type: long - -example: 12 - --- - -*`destination.port`*:: -+ --- -Port of the destination. - -type: long - -format: string - --- - -*`destination.registered_domain`*:: -+ --- -The highest registered destination domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`destination.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`destination.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`destination.user.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`destination.user.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`destination.user.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`destination.user.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`destination.user.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`destination.user.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`destination.user.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`destination.user.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`destination.user.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`destination.user.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`destination.user.name.text`*:: -+ --- -type: match_only_text - --- - -*`destination.user.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -[float] -=== dll - -These fields contain information about code libraries dynamically loaded into processes. - -Many operating systems refer to "shared code libraries" with different names, but this field set refers to all of the following: -* Dynamic-link library (`.dll`) commonly used on Windows -* Shared Object (`.so`) commonly used on Unix-like operating systems -* Dynamic library (`.dylib`) commonly used on macOS - - -*`dll.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`dll.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`dll.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`dll.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`dll.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`dll.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`dll.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`dll.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`dll.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`dll.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`dll.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`dll.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`dll.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`dll.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`dll.name`*:: -+ --- -Name of the library. -This generally maps to the name of the file on disk. - -type: keyword - -example: kernel32.dll - --- - -*`dll.path`*:: -+ --- -Full file path of the library. - -type: keyword - -example: C:\Windows\System32\kernel32.dll - --- - -*`dll.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`dll.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`dll.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`dll.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`dll.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`dll.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`dll.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -[float] -=== dns - -Fields describing DNS queries and answers. -DNS events should either represent a single DNS query prior to getting answers (`dns.type:query`) or they should represent a full exchange and contain the query details as well as all of the answers that were provided for this query (`dns.type:answer`). - - -*`dns.answers`*:: -+ --- -An array containing an object for each answer section returned by the server. -The main keys that should be present in these objects are defined by ECS. Records that have more information may contain more keys than what ECS defines. -Not all DNS data sources give all details about DNS answers. At minimum, answer objects must contain the `data` key. If more information is available, map as much of it to ECS as possible, and add any additional fields to the answer objects as custom fields. - -type: object - --- - -*`dns.answers.class`*:: -+ --- -The class of DNS data contained in this resource record. - -type: keyword - -example: IN - --- - -*`dns.answers.data`*:: -+ --- -The data describing the resource. -The meaning of this data depends on the type and class of the resource record. - -type: keyword - -example: 10.10.10.10 - --- - -*`dns.answers.name`*:: -+ --- -The domain name to which this resource record pertains. -If a chain of CNAME is being resolved, each answer's `name` should be the one that corresponds with the answer's `data`. It should not simply be the original `question.name` repeated. - -type: keyword - -example: www.example.com - --- - -*`dns.answers.ttl`*:: -+ --- -The time interval in seconds that this resource record may be cached before it should be discarded. Zero values mean that the data should not be cached. - -type: long - -example: 180 - --- - -*`dns.answers.type`*:: -+ --- -The type of data contained in this resource record. - -type: keyword - -example: CNAME - --- - -*`dns.header_flags`*:: -+ --- -Array of 2 letter DNS header flags. -Expected values are: AA, TC, RD, RA, AD, CD, DO. - -type: keyword - -example: ["RD", "RA"] - --- - -*`dns.id`*:: -+ --- -The DNS packet identifier assigned by the program that generated the query. The identifier is copied to the response. - -type: keyword - -example: 62111 - --- - -*`dns.op_code`*:: -+ --- -The DNS operation code that specifies the kind of query in the message. This value is set by the originator of a query and copied into the response. - -type: keyword - -example: QUERY - --- - -*`dns.question.class`*:: -+ --- -The class of records being queried. - -type: keyword - -example: IN - --- - -*`dns.question.name`*:: -+ --- -The name being queried. -If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. - -type: keyword - -example: www.example.com - --- - -*`dns.question.registered_domain`*:: -+ --- -The highest registered domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`dns.question.subdomain`*:: -+ --- -The subdomain is all of the labels under the registered_domain. -If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: www - --- - -*`dns.question.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`dns.question.type`*:: -+ --- -The type of record being queried. - -type: keyword - -example: AAAA - --- - -*`dns.resolved_ip`*:: -+ --- -Array containing all IPs seen in `answers.data`. -The `answers` array can be difficult to use, because of the variety of data formats it can contain. Extracting all IP addresses seen in there to `dns.resolved_ip` makes it possible to index them as IP addresses, and makes them easier to visualize and query for. - -type: ip - -example: ["10.10.10.10", "10.10.10.11"] - --- - -*`dns.response_code`*:: -+ --- -The DNS response code. - -type: keyword - -example: NOERROR - --- - -*`dns.type`*:: -+ --- -The type of DNS event captured, query or answer. -If your source of DNS events only gives you DNS queries, you should only create dns events of type `dns.type:query`. -If your source of DNS events gives you answers as well, you should create one event per query (optionally as soon as the query is seen). And a second event containing all query details as well as an array of answers. - -type: keyword - -example: answer - --- - -[float] -=== ecs - -Meta-information specific to ECS. - - -*`ecs.version`*:: -+ --- -ECS version this event conforms to. `ecs.version` is a required field and must exist in all events. -When querying across multiple indices -- which may conform to slightly different ECS versions -- this field lets integrations adjust to the schema version of the events. - -type: keyword - -example: 1.0.0 - -required: True - --- - -[float] -=== elf - -These fields contain Linux Executable Linkable Format (ELF) metadata. - - -*`elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -[float] -=== error - -These fields can represent errors of any kind. -Use them for errors that happen while fetching events or in cases where the event itself contains an error. - - -*`error.code`*:: -+ --- -Error code describing the error. - -type: keyword - --- - -*`error.id`*:: -+ --- -Unique identifier for the error. - -type: keyword - --- - -*`error.message`*:: -+ --- -Error message. - -type: match_only_text - --- - -*`error.stack_trace`*:: -+ --- -The stack trace of this error in plain text. - -type: wildcard - --- - -*`error.stack_trace.text`*:: -+ --- -type: match_only_text - --- - -*`error.type`*:: -+ --- -The type of the error, for example the class name of the exception. - -type: keyword - -example: java.lang.NullPointerException - --- - -[float] -=== event - -The event fields are used for context information about the log or metric event itself. -A log is defined as an event containing details of something that happened. Log events must include the time at which the thing happened. Examples of log events include a process starting on a host, a network packet being sent from a source to a destination, or a network connection between a client and a server being initiated or closed. A metric is defined as an event containing one or more numerical measurements and the time at which the measurement was taken. Examples of metric events include memory pressure measured on a host and device temperature. See the `event.kind` definition in this section for additional details about metric and state events. - - -*`event.action`*:: -+ --- -The action captured by the event. -This describes the information in the event. It is more specific than `event.category`. Examples are `group-add`, `process-started`, `file-created`. The value is normally defined by the implementer. - -type: keyword - -example: user-password-change - --- - -*`event.agent_id_status`*:: -+ --- -Agents are normally responsible for populating the `agent.id` field value. If the system receiving events is capable of validating the value based on authentication information for the client then this field can be used to reflect the outcome of that validation. -For example if the agent's connection is authenticated with mTLS and the client cert contains the ID of the agent to which the cert was issued then the `agent.id` value in events can be checked against the certificate. If the values match then `event.agent_id_status: verified` is added to the event, otherwise one of the other allowed values should be used. -If no validation is performed then the field should be omitted. -The allowed values are: -`verified` - The `agent.id` field value matches expected value obtained from auth metadata. -`mismatch` - The `agent.id` field value does not match the expected value obtained from auth metadata. -`missing` - There was no `agent.id` field in the event to validate. -`auth_metadata_missing` - There was no auth metadata or it was missing information about the agent ID. - -type: keyword - -example: verified - --- - -*`event.category`*:: -+ --- -This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy. -`event.category` represents the "big buckets" of ECS categories. For example, filtering on `event.category:process` yields all events relating to process activity. This field is closely related to `event.type`, which is used as a subcategory. -This field is an array. This will allow proper categorization of some events that fall in multiple categories. - -type: keyword - -example: authentication - --- - -*`event.code`*:: -+ --- -Identification code for this event, if one exists. -Some event sources use event codes to identify messages unambiguously, regardless of message language or wording adjustments over time. An example of this is the Windows Event ID. - -type: keyword - -example: 4648 - --- - -*`event.created`*:: -+ --- -event.created contains the date/time when the event was first read by an agent, or by your pipeline. -This field is distinct from @timestamp in that @timestamp typically contain the time extracted from the original event. -In most situations, these two timestamps will be slightly different. The difference can be used to calculate the delay between your source generating an event, and the time when your agent first processed it. This can be used to monitor your agent's or pipeline's ability to keep up with your event source. -In case the two timestamps are identical, @timestamp should be used. - -type: date - -example: 2016-05-23T08:05:34.857Z - --- - -*`event.dataset`*:: -+ --- -Name of the dataset. -If an event source publishes more than one type of log or events (e.g. access log, error log), the dataset is used to specify which one the event comes from. -It's recommended but not required to start the dataset name with the module name, followed by a dot, then the dataset name. - -type: keyword - -example: apache.access - --- - -*`event.duration`*:: -+ --- -Duration of the event in nanoseconds. -If event.start and event.end are known this value should be the difference between the end and start time. - -type: long - -format: duration - --- - -*`event.end`*:: -+ --- -event.end contains the date when the event ended or when the activity was last observed. - -type: date - --- - -*`event.hash`*:: -+ --- -Hash (perhaps logstash fingerprint) of raw field to be able to demonstrate log integrity. - -type: keyword - -example: 123456789012345678901234567890ABCD - --- - -*`event.id`*:: -+ --- -Unique ID to describe the event. - -type: keyword - -example: 8a4f500d - --- - -*`event.ingested`*:: -+ --- -Timestamp when an event arrived in the central data store. -This is different from `@timestamp`, which is when the event originally occurred. It's also different from `event.created`, which is meant to capture the first time an agent saw the event. -In normal conditions, assuming no tampering, the timestamps should chronologically look like this: `@timestamp` < `event.created` < `event.ingested`. - -type: date - -example: 2016-05-23T08:05:35.101Z - --- - -*`event.kind`*:: -+ --- -This is one of four ECS Categorization Fields, and indicates the highest level in the ECS category hierarchy. -`event.kind` gives high-level information about what type of information the event contains, without being specific to the contents of the event. For example, values of this field distinguish alert events from metric events. -The value of this field can be used to inform how these kinds of events should be handled. They may warrant different retention, different access control, it may also help understand whether the data coming in at a regular interval or not. - -type: keyword - -example: alert - --- - -*`event.module`*:: -+ --- -Name of the module this data is coming from. -If your monitoring agent supports the concept of modules or plugins to process events of a given source (e.g. Apache logs), `event.module` should contain the name of this module. - -type: keyword - -example: apache - --- - -*`event.original`*:: -+ --- -Raw text message of entire event. Used to demonstrate log integrity or where the full log message (before splitting it up in multiple parts) may be required, e.g. for reindex. -This field is not indexed and doc_values are disabled. It cannot be searched, but it can be retrieved from `_source`. If users wish to override this and index this field, please see `Field data types` in the `Elasticsearch Reference`. - -type: keyword - -example: Sep 19 08:26:10 host CEF:0|Security| threatmanager|1.0|100| worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2spt=1232 - -Field is not indexed. - --- - -*`event.outcome`*:: -+ --- -This is one of four ECS Categorization Fields, and indicates the lowest level in the ECS category hierarchy. -`event.outcome` simply denotes whether the event represents a success or a failure from the perspective of the entity that produced the event. -Note that when a single transaction is described in multiple events, each event may populate different values of `event.outcome`, according to their perspective. -Also note that in the case of a compound event (a single event that contains multiple logical events), this field should be populated with the value that best captures the overall success or failure from the perspective of the event producer. -Further note that not all events will have an associated outcome. For example, this field is generally not populated for metric events, events with `event.type:info`, or any events for which an outcome does not make logical sense. - -type: keyword - -example: success - --- - -*`event.provider`*:: -+ --- -Source of the event. -Event transports such as Syslog or the Windows Event Log typically mention the source of an event. It can be the name of the software that generated the event (e.g. Sysmon, httpd), or of a subsystem of the operating system (kernel, Microsoft-Windows-Security-Auditing). - -type: keyword - -example: kernel - --- - -*`event.reason`*:: -+ --- -Reason why this event happened, according to the source. -This describes the why of a particular action or outcome captured in the event. Where `event.action` captures the action from the event, `event.reason` describes why that action was taken. For example, a web proxy with an `event.action` which denied the request may also populate `event.reason` with the reason why (e.g. `blocked site`). - -type: keyword - -example: Terminated an unexpected process - --- - -*`event.reference`*:: -+ --- -Reference URL linking to additional information about this event. -This URL links to a static definition of this event. Alert events, indicated by `event.kind:alert`, are a common use case for this field. - -type: keyword - -example: https://system.example.com/event/#0001234 - --- - -*`event.risk_score`*:: -+ --- -Risk score or priority of the event (e.g. security solutions). Use your system's original value here. - -type: float - --- - -*`event.risk_score_norm`*:: -+ --- -Normalized risk score or priority of the event, on a scale of 0 to 100. -This is mainly useful if you use more than one system that assigns risk scores, and you want to see a normalized value across all systems. - -type: float - --- - -*`event.sequence`*:: -+ --- -Sequence number of the event. -The sequence number is a value published by some event sources, to make the exact ordering of events unambiguous, regardless of the timestamp precision. - -type: long - -format: string - --- - -*`event.severity`*:: -+ --- -The numeric severity of the event according to your event source. -What the different severity values mean can be different between sources and use cases. It's up to the implementer to make sure severities are consistent across events from the same source. -The Syslog severity belongs in `log.syslog.severity.code`. `event.severity` is meant to represent the severity according to the event source (e.g. firewall, IDS). If the event source does not publish its own severity, you may optionally copy the `log.syslog.severity.code` to `event.severity`. - -type: long - -example: 7 - -format: string - --- - -*`event.start`*:: -+ --- -event.start contains the date when the event started or when the activity was first observed. - -type: date - --- - -*`event.timezone`*:: -+ --- -This field should be populated when the event's timestamp does not include timezone information already (e.g. default Syslog timestamps). It's optional otherwise. -Acceptable timezone formats are: a canonical ID (e.g. "Europe/Amsterdam"), abbreviated (e.g. "EST") or an HH:mm differential (e.g. "-05:00"). - -type: keyword - --- - -*`event.type`*:: -+ --- -This is one of four ECS Categorization Fields, and indicates the third level in the ECS category hierarchy. -`event.type` represents a categorization "sub-bucket" that, when used along with the `event.category` field values, enables filtering events down to a level appropriate for single visualization. -This field is an array. This will allow proper categorization of some events that fall in multiple event types. - -type: keyword - --- - -*`event.url`*:: -+ --- -URL linking to an external system to continue investigation of this event. -This URL links to another system where in-depth investigation of the specific occurrence of this event can take place. Alert events, indicated by `event.kind:alert`, are a common use case for this field. - -type: keyword - -example: https://mysystem.example.com/alert/5271dedb-f5b0-4218-87f0-4ac4870a38fe - --- - -[float] -=== faas - -The user fields describe information about the function as a service that is relevant to the event. - - -*`faas.coldstart`*:: -+ --- -Boolean value indicating a cold start of a function. - -type: boolean - --- - -*`faas.execution`*:: -+ --- -The execution ID of the current function execution. - -type: keyword - -example: af9d5aa4-a685-4c5f-a22b-444f80b3cc28 - --- - -*`faas.trigger`*:: -+ --- -Details about the function trigger. - -type: nested - --- - -*`faas.trigger.request_id`*:: -+ --- -The ID of the trigger request , message, event, etc. - -type: keyword - -example: 123456789 - --- - -*`faas.trigger.type`*:: -+ --- -The trigger for the function execution. -Expected values are: - * http - * pubsub - * datasource - * timer - * other - -type: keyword - -example: http - --- - -[float] -=== file - -A file is defined as a set of information that has been created on, or has existed on a filesystem. -File objects can be associated with host events, network events, and/or file events (e.g., those produced by File Integrity Monitoring [FIM] products or services). File fields provide details about the affected file associated with the event or metric. - - -*`file.accessed`*:: -+ --- -Last time the file was accessed. -Note that not all filesystems keep track of access time. - -type: date - --- - -*`file.attributes`*:: -+ --- -Array of file attributes. -Attributes names will vary by platform. Here's a non-exhaustive list of values that are expected in this field: archive, compressed, directory, encrypted, execute, hidden, read, readonly, system, write. - -type: keyword - -example: ["readonly", "system"] - --- - -*`file.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`file.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`file.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`file.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`file.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`file.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`file.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`file.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`file.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`file.created`*:: -+ --- -File creation time. -Note that not all filesystems store the creation time. - -type: date - --- - -*`file.ctime`*:: -+ --- -Last time the file attributes or metadata changed. -Note that changes to the file content will update `mtime`. This implies `ctime` will be adjusted at the same time, since `mtime` is an attribute of the file. - -type: date - --- - -*`file.device`*:: -+ --- -Device that is the source of the file. - -type: keyword - -example: sda - --- - -*`file.directory`*:: -+ --- -Directory where the file is located. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice - --- - -*`file.drive_letter`*:: -+ --- -Drive letter where the file is located. This field is only relevant on Windows. -The value should be uppercase, and not include the colon. - -type: keyword - -example: C - --- - -*`file.elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`file.elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`file.elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`file.elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`file.elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`file.elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`file.elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`file.elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`file.elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`file.elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`file.elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`file.elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`file.elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`file.elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`file.elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`file.elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`file.elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`file.elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`file.elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`file.elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`file.elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`file.elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`file.elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`file.elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`file.elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`file.elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`file.elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`file.elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`file.elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -*`file.extension`*:: -+ --- -File extension, excluding the leading dot. -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`file.fork_name`*:: -+ --- -A fork is additional data associated with a filesystem object. -On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. -On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. An ADS is typically of the form: `C:\path\to\filename.extension:some_fork_name`, and `some_fork_name` is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. - -type: keyword - -example: Zone.Identifer - --- - -*`file.gid`*:: -+ --- -Primary group ID (GID) of the file. - -type: keyword - -example: 1001 - --- - -*`file.group`*:: -+ --- -Primary group name of the file. - -type: keyword - -example: alice - --- - -*`file.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`file.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`file.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`file.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`file.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`file.inode`*:: -+ --- -Inode representing the file in the filesystem. - -type: keyword - -example: 256383 - --- - -*`file.mime_type`*:: -+ --- -MIME type should identify the format of the file or stream of bytes using https://www.iana.org/assignments/media-types/media-types.xhtml[IANA official types], where possible. When more than one type is applicable, the most specific type should be used. - -type: keyword - --- - -*`file.mode`*:: -+ --- -Mode of the file in octal representation. - -type: keyword - -example: 0640 - --- - -*`file.mtime`*:: -+ --- -Last time the file content was modified. - -type: date - --- - -*`file.name`*:: -+ --- -Name of the file including the extension, without the directory. - -type: keyword - -example: example.png - --- - -*`file.owner`*:: -+ --- -File owner's username. - -type: keyword - -example: alice - --- - -*`file.path`*:: -+ --- -Full path to the file, including the file name. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice/example.png - --- - -*`file.path.text`*:: -+ --- -type: match_only_text - --- - -*`file.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`file.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`file.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`file.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`file.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`file.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`file.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -*`file.size`*:: -+ --- -File size in bytes. -Only relevant when `file.type` is "file". - -type: long - -example: 16384 - --- - -*`file.target_path`*:: -+ --- -Target path for symlinks. - -type: keyword - --- - -*`file.target_path.text`*:: -+ --- -type: match_only_text - --- - -*`file.type`*:: -+ --- -File type (file, dir, or symlink). - -type: keyword - -example: file - --- - -*`file.uid`*:: -+ --- -The user ID (UID) or security identifier (SID) of the file owner. - -type: keyword - -example: 1001 - --- - -*`file.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`file.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`file.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`file.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`file.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`file.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`file.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`file.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`file.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`file.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`file.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`file.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`file.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`file.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`file.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`file.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`file.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`file.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`file.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`file.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`file.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`file.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`file.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`file.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -[float] -=== geo - -Geo fields can carry data about a specific location related to an event. -This geolocation information can be derived from techniques such as Geo IP, or be user-supplied. - - -*`geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -[float] -=== group - -The group fields are meant to represent groups that are relevant to the event. - - -*`group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -[float] -=== hash - -The hash fields represent different bitwise hash algorithms and their values. -Field names for common hashes (e.g. MD5, SHA1) are predefined. Add fields for other hashes by lowercasing the hash algorithm name and using underscore separators as appropriate (snake case, e.g. sha3_512). -Note that this fieldset is used for common hashes that may be computed over a range of generic bytes. Entity-specific hashes such as ja3 or imphash are placed in the fieldsets to which they relate (tls and pe, respectively). - - -*`hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -[float] -=== host - -A host is defined as a general computing instance. -ECS host.* fields should be populated with details about the host on which the event happened, or from which the measurement was taken. Host types include hardware, virtual machines, Docker containers, and Kubernetes nodes. - - -*`host.architecture`*:: -+ --- -Operating system architecture. - -type: keyword - -example: x86_64 - --- - -*`host.cpu.usage`*:: -+ --- -Percent CPU used which is normalized by the number of CPU cores and it ranges from 0 to 1. -Scaling factor: 1000. -For example: For a two core host, this value should be the average of the two cores, between 0 and 1. - -type: scaled_float - --- - -*`host.disk.read.bytes`*:: -+ --- -The total number of bytes (gauge) read successfully (aggregated from all disks) since the last metric collection. - -type: long - --- - -*`host.disk.write.bytes`*:: -+ --- -The total number of bytes (gauge) written successfully (aggregated from all disks) since the last metric collection. - -type: long - --- - -*`host.domain`*:: -+ --- -Name of the domain of which the host is a member. -For example, on Windows this could be the host's Active Directory domain or NetBIOS domain name. For Linux this could be the domain of the host's LDAP provider. - -type: keyword - -example: CONTOSO - --- - -*`host.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`host.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`host.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`host.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`host.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`host.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`host.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`host.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`host.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`host.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`host.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`host.hostname`*:: -+ --- -Hostname of the host. -It normally contains what the `hostname` command returns on the host machine. - -type: keyword - --- - -*`host.id`*:: -+ --- -Unique host id. -As hostname is not always unique, use values that are meaningful in your environment. -Example: The current usage of `beat.name`. - -type: keyword - --- - -*`host.ip`*:: -+ --- -Host ip addresses. - -type: ip - --- - -*`host.mac`*:: -+ --- -Host MAC addresses. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: ["00-00-5E-00-53-23", "00-00-5E-00-53-24"] - --- - -*`host.name`*:: -+ --- -Name of the host. -It can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use. - -type: keyword - --- - -*`host.network.egress.bytes`*:: -+ --- -The number of bytes (gauge) sent out on all network interfaces by the host since the last metric collection. - -type: long - --- - -*`host.network.egress.packets`*:: -+ --- -The number of packets (gauge) sent out on all network interfaces by the host since the last metric collection. - -type: long - --- - -*`host.network.ingress.bytes`*:: -+ --- -The number of bytes received (gauge) on all network interfaces by the host since the last metric collection. - -type: long - --- - -*`host.network.ingress.packets`*:: -+ --- -The number of packets (gauge) received on all network interfaces by the host since the last metric collection. - -type: long - --- - -*`host.os.family`*:: -+ --- -OS family (such as redhat, debian, freebsd, windows). - -type: keyword - -example: debian - --- - -*`host.os.full`*:: -+ --- -Operating system name, including the version or code name. - -type: keyword - -example: Mac OS Mojave - --- - -*`host.os.full.text`*:: -+ --- -type: match_only_text - --- - -*`host.os.kernel`*:: -+ --- -Operating system kernel version as a raw string. - -type: keyword - -example: 4.4.0-112-generic - --- - -*`host.os.name`*:: -+ --- -Operating system name, without the version. - -type: keyword - -example: Mac OS X - --- - -*`host.os.name.text`*:: -+ --- -type: match_only_text - --- - -*`host.os.platform`*:: -+ --- -Operating system platform (such centos, ubuntu, windows). - -type: keyword - -example: darwin - --- - -*`host.os.type`*:: -+ --- -Use the `os.type` field to categorize the operating system into one of the broad commercial families. -One of these following values should be used (lowercase): linux, macos, unix, windows. -If the OS you're dealing with is not in the list, the field should not be populated. Please let us know by opening an issue with ECS, to propose its addition. - -type: keyword - -example: macos - --- - -*`host.os.version`*:: -+ --- -Operating system version as a raw string. - -type: keyword - -example: 10.14.1 - --- - -*`host.type`*:: -+ --- -Type of host. -For Cloud providers this can be the machine type like `t2.medium`. If vm, this could be the container, for example, or other information meaningful in your environment. - -type: keyword - --- - -*`host.uptime`*:: -+ --- -Seconds the host has been up. - -type: long - -example: 1325 - --- - -[float] -=== http - -Fields related to HTTP activity. Use the `url` field set to store the url of the request. - - -*`http.request.body.bytes`*:: -+ --- -Size in bytes of the request body. - -type: long - -example: 887 - -format: bytes - --- - -*`http.request.body.content`*:: -+ --- -The full HTTP request body. - -type: wildcard - -example: Hello world - --- - -*`http.request.body.content.text`*:: -+ --- -type: match_only_text - --- - -*`http.request.bytes`*:: -+ --- -Total size in bytes of the request (body and headers). - -type: long - -example: 1437 - -format: bytes - --- - -*`http.request.id`*:: -+ --- -A unique identifier for each HTTP request to correlate logs between clients and servers in transactions. -The id may be contained in a non-standard HTTP header, such as `X-Request-ID` or `X-Correlation-ID`. - -type: keyword - -example: 123e4567-e89b-12d3-a456-426614174000 - --- - -*`http.request.method`*:: -+ --- -HTTP request method. -The value should retain its casing from the original event. For example, `GET`, `get`, and `GeT` are all considered valid values for this field. - -type: keyword - -example: POST - --- - -*`http.request.mime_type`*:: -+ --- -Mime type of the body of the request. -This value must only be populated based on the content of the request body, not on the `Content-Type` header. Comparing the mime type of a request with the request's Content-Type header can be helpful in detecting threats or misconfigured clients. - -type: keyword - -example: image/gif - --- - -*`http.request.referrer`*:: -+ --- -Referrer for this HTTP request. - -type: keyword - -example: https://blog.example.com/ - --- - -*`http.response.body.bytes`*:: -+ --- -Size in bytes of the response body. - -type: long - -example: 887 - -format: bytes - --- - -*`http.response.body.content`*:: -+ --- -The full HTTP response body. - -type: wildcard - -example: Hello world - --- - -*`http.response.body.content.text`*:: -+ --- -type: match_only_text - --- - -*`http.response.bytes`*:: -+ --- -Total size in bytes of the response (body and headers). - -type: long - -example: 1437 - -format: bytes - --- - -*`http.response.mime_type`*:: -+ --- -Mime type of the body of the response. -This value must only be populated based on the content of the response body, not on the `Content-Type` header. Comparing the mime type of a response with the response's Content-Type header can be helpful in detecting misconfigured servers. - -type: keyword - -example: image/gif - --- - -*`http.response.status_code`*:: -+ --- -HTTP response status code. - -type: long - -example: 404 - -format: string - --- - -*`http.version`*:: -+ --- -HTTP version. - -type: keyword - -example: 1.1 - --- - -[float] -=== interface - -The interface fields are used to record ingress and egress interface information when reported by an observer (e.g. firewall, router, load balancer) in the context of the observer handling a network connection. In the case of a single observer interface (e.g. network sensor on a span port) only the observer.ingress information should be populated. - - -*`interface.alias`*:: -+ --- -Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming. - -type: keyword - -example: outside - --- - -*`interface.id`*:: -+ --- -Interface ID as reported by an observer (typically SNMP interface ID). - -type: keyword - -example: 10 - --- - -*`interface.name`*:: -+ --- -Interface name as reported by the system. - -type: keyword - -example: eth0 - --- - -[float] -=== log - -Details about the event's logging mechanism or logging transport. -The log.* fields are typically populated with details about the logging mechanism used to create and/or transport the event. For example, syslog details belong under `log.syslog.*`. -The details specific to your event source are typically not logged under `log.*`, but rather in `event.*` or in other ECS fields. - - -*`log.file.path`*:: -+ --- -Full path to the log file this event came from, including the file name. It should include the drive letter, when appropriate. -If the event wasn't read from a log file, do not populate this field. - -type: keyword - -example: /var/log/fun-times.log - --- - -*`log.level`*:: -+ --- -Original log level of the log event. -If the source of the event provides a log level or textual severity, this is the one that goes in `log.level`. If your source doesn't specify one, you may put your event transport's severity here (e.g. Syslog severity). -Some examples are `warn`, `err`, `i`, `informational`. - -type: keyword - -example: error - --- - -*`log.logger`*:: -+ --- -The name of the logger inside an application. This is usually the name of the class which initialized the logger, or can be a custom name. - -type: keyword - -example: org.elasticsearch.bootstrap.Bootstrap - --- - -*`log.origin.file.line`*:: -+ --- -The line number of the file containing the source code which originated the log event. - -type: long - -example: 42 - --- - -*`log.origin.file.name`*:: -+ --- -The name of the file containing the source code which originated the log event. -Note that this field is not meant to capture the log file. The correct field to capture the log file is `log.file.path`. - -type: keyword - -example: Bootstrap.java - --- - -*`log.origin.function`*:: -+ --- -The name of the function or method which originated the log event. - -type: keyword - -example: init - --- - -*`log.syslog`*:: -+ --- -The Syslog metadata of the event, if the event was transmitted via Syslog. Please see RFCs 5424 or 3164. - -type: object - --- - -*`log.syslog.facility.code`*:: -+ --- -The Syslog numeric facility of the log event, if available. -According to RFCs 5424 and 3164, this value should be an integer between 0 and 23. - -type: long - -example: 23 - -format: string - --- - -*`log.syslog.facility.name`*:: -+ --- -The Syslog text-based facility of the log event, if available. - -type: keyword - -example: local7 - --- - -*`log.syslog.priority`*:: -+ --- -Syslog numeric priority of the event, if available. -According to RFCs 5424 and 3164, the priority is 8 * facility + severity. This number is therefore expected to contain a value between 0 and 191. - -type: long - -example: 135 - -format: string - --- - -*`log.syslog.severity.code`*:: -+ --- -The Syslog numeric severity of the log event, if available. -If the event source publishing via Syslog provides a different numeric severity value (e.g. firewall, IDS), your source's numeric severity should go to `event.severity`. If the event source does not specify a distinct severity, you can optionally copy the Syslog severity to `event.severity`. - -type: long - -example: 3 - --- - -*`log.syslog.severity.name`*:: -+ --- -The Syslog numeric severity of the log event, if available. -If the event source publishing via Syslog provides a different severity value (e.g. firewall, IDS), your source's text severity should go to `log.level`. If the event source does not specify a distinct severity, you can optionally copy the Syslog severity to `log.level`. - -type: keyword - -example: Error - --- - -[float] -=== network - -The network is defined as the communication path over which a host or network event happens. -The network.* fields should be populated with details about the network activity associated with an event. - - -*`network.application`*:: -+ --- -When a specific application or service is identified from network connection details (source/dest IPs, ports, certificates, or wire format), this field captures the application's or service's name. -For example, the original event identifies the network connection being from a specific web service in a `https` network connection, like `facebook` or `twitter`. -The field value must be normalized to lowercase for querying. - -type: keyword - -example: aim - --- - -*`network.bytes`*:: -+ --- -Total bytes transferred in both directions. -If `source.bytes` and `destination.bytes` are known, `network.bytes` is their sum. - -type: long - -example: 368 - -format: bytes - --- - -*`network.community_id`*:: -+ --- -A hash of source and destination IPs and ports, as well as the protocol used in a communication. This is a tool-agnostic standard to identify flows. -Learn more at https://github.com/corelight/community-id-spec. - -type: keyword - -example: 1:hO+sN4H+MG5MY/8hIrXPqc4ZQz0= - --- - -*`network.direction`*:: -+ --- -Direction of the network traffic. -Recommended values are: - * ingress - * egress - * inbound - * outbound - * internal - * external - * unknown - -When mapping events from a host-based monitoring context, populate this field from the host's point of view, using the values "ingress" or "egress". -When mapping events from a network or perimeter-based monitoring context, populate this field from the point of view of the network perimeter, using the values "inbound", "outbound", "internal" or "external". -Note that "internal" is not crossing perimeter boundaries, and is meant to describe communication between two hosts within the perimeter. Note also that "external" is meant to describe traffic between two hosts that are external to the perimeter. This could for example be useful for ISPs or VPN service providers. - -type: keyword - -example: inbound - --- - -*`network.forwarded_ip`*:: -+ --- -Host IP address when the source IP address is the proxy. - -type: ip - -example: 192.1.1.2 - --- - -*`network.iana_number`*:: -+ --- -IANA Protocol Number (https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). Standardized list of protocols. This aligns well with NetFlow and sFlow related logs which use the IANA Protocol Number. - -type: keyword - -example: 6 - --- - -*`network.inner`*:: -+ --- -Network.inner fields are added in addition to network.vlan fields to describe the innermost VLAN when q-in-q VLAN tagging is present. Allowed fields include vlan.id and vlan.name. Inner vlan fields are typically used when sending traffic with multiple 802.1q encapsulations to a network sensor (e.g. Zeek, Wireshark.) - -type: object - --- - -*`network.inner.vlan.id`*:: -+ --- -VLAN ID as reported by the observer. - -type: keyword - -example: 10 - --- - -*`network.inner.vlan.name`*:: -+ --- -Optional VLAN name as reported by the observer. - -type: keyword - -example: outside - --- - -*`network.name`*:: -+ --- -Name given by operators to sections of their network. - -type: keyword - -example: Guest Wifi - --- - -*`network.packets`*:: -+ --- -Total packets transferred in both directions. -If `source.packets` and `destination.packets` are known, `network.packets` is their sum. - -type: long - -example: 24 - --- - -*`network.protocol`*:: -+ --- -In the OSI Model this would be the Application Layer protocol. For example, `http`, `dns`, or `ssh`. -The field value must be normalized to lowercase for querying. - -type: keyword - -example: http - --- - -*`network.transport`*:: -+ --- -Same as network.iana_number, but instead using the Keyword name of the transport layer (udp, tcp, ipv6-icmp, etc.) -The field value must be normalized to lowercase for querying. - -type: keyword - -example: tcp - --- - -*`network.type`*:: -+ --- -In the OSI Model this would be the Network Layer. ipv4, ipv6, ipsec, pim, etc -The field value must be normalized to lowercase for querying. - -type: keyword - -example: ipv4 - --- - -*`network.vlan.id`*:: -+ --- -VLAN ID as reported by the observer. - -type: keyword - -example: 10 - --- - -*`network.vlan.name`*:: -+ --- -Optional VLAN name as reported by the observer. - -type: keyword - -example: outside - --- - -[float] -=== observer - -An observer is defined as a special network, security, or application device used to detect, observe, or create network, security, or application-related events and metrics. -This could be a custom hardware appliance or a server that has been configured to run special network, security, or application software. Examples include firewalls, web proxies, intrusion detection/prevention systems, network monitoring sensors, web application firewalls, data loss prevention systems, and APM servers. The observer.* fields shall be populated with details of the system, if any, that detects, observes and/or creates a network, security, or application event or metric. Message queues and ETL components used in processing events or metrics are not considered observers in ECS. - - -*`observer.egress`*:: -+ --- -Observer.egress holds information like interface number and name, vlan, and zone information to classify egress traffic. Single armed monitoring such as a network sensor on a span port should only use observer.ingress to categorize traffic. - -type: object - --- - -*`observer.egress.interface.alias`*:: -+ --- -Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming. - -type: keyword - -example: outside - --- - -*`observer.egress.interface.id`*:: -+ --- -Interface ID as reported by an observer (typically SNMP interface ID). - -type: keyword - -example: 10 - --- - -*`observer.egress.interface.name`*:: -+ --- -Interface name as reported by the system. - -type: keyword - -example: eth0 - --- - -*`observer.egress.vlan.id`*:: -+ --- -VLAN ID as reported by the observer. - -type: keyword - -example: 10 - --- - -*`observer.egress.vlan.name`*:: -+ --- -Optional VLAN name as reported by the observer. - -type: keyword - -example: outside - --- - -*`observer.egress.zone`*:: -+ --- -Network zone of outbound traffic as reported by the observer to categorize the destination area of egress traffic, e.g. Internal, External, DMZ, HR, Legal, etc. - -type: keyword - -example: Public_Internet - --- - -*`observer.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`observer.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`observer.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`observer.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`observer.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`observer.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`observer.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`observer.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`observer.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`observer.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`observer.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`observer.hostname`*:: -+ --- -Hostname of the observer. - -type: keyword - --- - -*`observer.ingress`*:: -+ --- -Observer.ingress holds information like interface number and name, vlan, and zone information to classify ingress traffic. Single armed monitoring such as a network sensor on a span port should only use observer.ingress to categorize traffic. - -type: object - --- - -*`observer.ingress.interface.alias`*:: -+ --- -Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming. - -type: keyword - -example: outside - --- - -*`observer.ingress.interface.id`*:: -+ --- -Interface ID as reported by an observer (typically SNMP interface ID). - -type: keyword - -example: 10 - --- - -*`observer.ingress.interface.name`*:: -+ --- -Interface name as reported by the system. - -type: keyword - -example: eth0 - --- - -*`observer.ingress.vlan.id`*:: -+ --- -VLAN ID as reported by the observer. - -type: keyword - -example: 10 - --- - -*`observer.ingress.vlan.name`*:: -+ --- -Optional VLAN name as reported by the observer. - -type: keyword - -example: outside - --- - -*`observer.ingress.zone`*:: -+ --- -Network zone of incoming traffic as reported by the observer to categorize the source area of ingress traffic. e.g. internal, External, DMZ, HR, Legal, etc. - -type: keyword - -example: DMZ - --- - -*`observer.ip`*:: -+ --- -IP addresses of the observer. - -type: ip - --- - -*`observer.mac`*:: -+ --- -MAC addresses of the observer. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: ["00-00-5E-00-53-23", "00-00-5E-00-53-24"] - --- - -*`observer.name`*:: -+ --- -Custom name of the observer. -This is a name that can be given to an observer. This can be helpful for example if multiple firewalls of the same model are used in an organization. -If no custom name is needed, the field can be left empty. - -type: keyword - -example: 1_proxySG - --- - -*`observer.os.family`*:: -+ --- -OS family (such as redhat, debian, freebsd, windows). - -type: keyword - -example: debian - --- - -*`observer.os.full`*:: -+ --- -Operating system name, including the version or code name. - -type: keyword - -example: Mac OS Mojave - --- - -*`observer.os.full.text`*:: -+ --- -type: match_only_text - --- - -*`observer.os.kernel`*:: -+ --- -Operating system kernel version as a raw string. - -type: keyword - -example: 4.4.0-112-generic - --- - -*`observer.os.name`*:: -+ --- -Operating system name, without the version. - -type: keyword - -example: Mac OS X - --- - -*`observer.os.name.text`*:: -+ --- -type: match_only_text - --- - -*`observer.os.platform`*:: -+ --- -Operating system platform (such centos, ubuntu, windows). - -type: keyword - -example: darwin - --- - -*`observer.os.type`*:: -+ --- -Use the `os.type` field to categorize the operating system into one of the broad commercial families. -One of these following values should be used (lowercase): linux, macos, unix, windows. -If the OS you're dealing with is not in the list, the field should not be populated. Please let us know by opening an issue with ECS, to propose its addition. - -type: keyword - -example: macos - --- - -*`observer.os.version`*:: -+ --- -Operating system version as a raw string. - -type: keyword - -example: 10.14.1 - --- - -*`observer.product`*:: -+ --- -The product name of the observer. - -type: keyword - -example: s200 - --- - -*`observer.serial_number`*:: -+ --- -Observer serial number. - -type: keyword - --- - -*`observer.type`*:: -+ --- -The type of the observer the data is coming from. -There is no predefined list of observer types. Some examples are `forwarder`, `firewall`, `ids`, `ips`, `proxy`, `poller`, `sensor`, `APM server`. - -type: keyword - -example: firewall - --- - -*`observer.vendor`*:: -+ --- -Vendor name of the observer. - -type: keyword - -example: Symantec - --- - -*`observer.version`*:: -+ --- -Observer version. - -type: keyword - --- - -[float] -=== orchestrator - -Fields that describe the resources which container orchestrators manage or act upon. - - -*`orchestrator.api_version`*:: -+ --- -API version being used to carry out the action - -type: keyword - -example: v1beta1 - --- - -*`orchestrator.cluster.name`*:: -+ --- -Name of the cluster. - -type: keyword - --- - -*`orchestrator.cluster.url`*:: -+ --- -URL of the API used to manage the cluster. - -type: keyword - --- - -*`orchestrator.cluster.version`*:: -+ --- -The version of the cluster. - -type: keyword - --- - -*`orchestrator.namespace`*:: -+ --- -Namespace in which the action is taking place. - -type: keyword - -example: kube-system - --- - -*`orchestrator.organization`*:: -+ --- -Organization affected by the event (for multi-tenant orchestrator setups). - -type: keyword - -example: elastic - --- - -*`orchestrator.resource.name`*:: -+ --- -Name of the resource being acted upon. - -type: keyword - -example: test-pod-cdcws - --- - -*`orchestrator.resource.type`*:: -+ --- -Type of resource being acted upon. - -type: keyword - -example: service - --- - -*`orchestrator.type`*:: -+ --- -Orchestrator cluster type (e.g. kubernetes, nomad or cloudfoundry). - -type: keyword - -example: kubernetes - --- - -[float] -=== organization - -The organization fields enrich data with information about the company or entity the data is associated with. -These fields help you arrange or filter data stored in an index by one or multiple organizations. - - -*`organization.id`*:: -+ --- -Unique identifier for the organization. - -type: keyword - --- - -*`organization.name`*:: -+ --- -Organization name. - -type: keyword - --- - -*`organization.name.text`*:: -+ --- -type: match_only_text - --- - -[float] -=== os - -The OS fields contain information about the operating system. - - -*`os.family`*:: -+ --- -OS family (such as redhat, debian, freebsd, windows). - -type: keyword - -example: debian - --- - -*`os.full`*:: -+ --- -Operating system name, including the version or code name. - -type: keyword - -example: Mac OS Mojave - --- - -*`os.full.text`*:: -+ --- -type: match_only_text - --- - -*`os.kernel`*:: -+ --- -Operating system kernel version as a raw string. - -type: keyword - -example: 4.4.0-112-generic - --- - -*`os.name`*:: -+ --- -Operating system name, without the version. - -type: keyword - -example: Mac OS X - --- - -*`os.name.text`*:: -+ --- -type: match_only_text - --- - -*`os.platform`*:: -+ --- -Operating system platform (such centos, ubuntu, windows). - -type: keyword - -example: darwin - --- - -*`os.type`*:: -+ --- -Use the `os.type` field to categorize the operating system into one of the broad commercial families. -One of these following values should be used (lowercase): linux, macos, unix, windows. -If the OS you're dealing with is not in the list, the field should not be populated. Please let us know by opening an issue with ECS, to propose its addition. - -type: keyword - -example: macos - --- - -*`os.version`*:: -+ --- -Operating system version as a raw string. - -type: keyword - -example: 10.14.1 - --- - -[float] -=== package - -These fields contain information about an installed software package. It contains general information about a package, such as name, version or size. It also contains installation details, such as time or location. - - -*`package.architecture`*:: -+ --- -Package architecture. - -type: keyword - -example: x86_64 - --- - -*`package.build_version`*:: -+ --- -Additional information about the build version of the installed package. -For example use the commit SHA of a non-released package. - -type: keyword - -example: 36f4f7e89dd61b0988b12ee000b98966867710cd - --- - -*`package.checksum`*:: -+ --- -Checksum of the installed package for verification. - -type: keyword - -example: 68b329da9893e34099c7d8ad5cb9c940 - --- - -*`package.description`*:: -+ --- -Description of the package. - -type: keyword - -example: Open source programming language to build simple/reliable/efficient software. - --- - -*`package.install_scope`*:: -+ --- -Indicating how the package was installed, e.g. user-local, global. - -type: keyword - -example: global - --- - -*`package.installed`*:: -+ --- -Time when package was installed. - -type: date - --- - -*`package.license`*:: -+ --- -License under which the package was released. -Use a short name, e.g. the license identifier from SPDX License List where possible (https://spdx.org/licenses/). - -type: keyword - -example: Apache License 2.0 - --- - -*`package.name`*:: -+ --- -Package name - -type: keyword - -example: go - --- - -*`package.path`*:: -+ --- -Path where the package is installed. - -type: keyword - -example: /usr/local/Cellar/go/1.12.9/ - --- - -*`package.reference`*:: -+ --- -Home page or reference URL of the software in this package, if available. - -type: keyword - -example: https://golang.org - --- - -*`package.size`*:: -+ --- -Package size in bytes. - -type: long - -example: 62231 - -format: string - --- - -*`package.type`*:: -+ --- -Type of package. -This should contain the package file type, rather than the package manager name. Examples: rpm, dpkg, brew, npm, gem, nupkg, jar. - -type: keyword - -example: rpm - --- - -*`package.version`*:: -+ --- -Package version - -type: keyword - -example: 1.12.9 - --- - -[float] -=== pe - -These fields contain Windows Portable Executable (PE) metadata. - - -*`pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -[float] -=== process - -These fields contain information about a process. -These fields can help you correlate metrics information with a process id/name from a log message. The `process.pid` often stays in the metric itself and is copied to the global field for correlation. - - -*`process.args`*:: -+ --- -Array of process arguments, starting with the absolute path to the executable. -May be filtered to protect sensitive information. - -type: keyword - -example: ["/usr/bin/ssh", "-l", "user", "10.0.0.16"] - --- - -*`process.args_count`*:: -+ --- -Length of the process.args array. -This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. - -type: long - -example: 4 - --- - -*`process.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`process.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`process.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`process.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`process.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`process.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`process.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`process.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`process.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`process.command_line`*:: -+ --- -Full command line that started the process, including the absolute path to the executable, and all arguments. -Some arguments may be filtered to protect sensitive information. - -type: wildcard - -example: /usr/bin/ssh -l user 10.0.0.16 - --- - -*`process.command_line.text`*:: -+ --- -type: match_only_text - --- - -*`process.elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`process.elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`process.elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`process.elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`process.elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`process.elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`process.elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`process.elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`process.elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`process.elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`process.elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`process.elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`process.elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`process.elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`process.elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`process.elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`process.elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`process.elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`process.elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`process.elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`process.elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`process.elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`process.elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`process.elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`process.elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`process.elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`process.elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`process.elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`process.elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -*`process.end`*:: -+ --- -The time the process ended. - -type: date - -example: 2016-05-23T08:05:34.853Z - --- - -*`process.entity_id`*:: -+ --- -Unique identifier for the process. -The implementation of this is specified by the data source, but some examples of what could be used here are a process-generated UUID, Sysmon Process GUIDs, or a hash of some uniquely identifying components of a process. -Constructing a globally unique identifier is a common practice to mitigate PID reuse as well as to identify a specific process over time, across multiple monitored hosts. - -type: keyword - -example: c2c455d9f99375d - --- - -*`process.executable`*:: -+ --- -Absolute path to the process executable. - -type: keyword - -example: /usr/bin/ssh - --- - -*`process.executable.text`*:: -+ --- -type: match_only_text - --- - -*`process.exit_code`*:: -+ --- -The exit code of the process, if this is a termination event. -The field should be absent if there is no exit code for the event (e.g. process start). - -type: long - -example: 137 - --- - -*`process.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`process.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`process.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`process.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`process.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`process.name`*:: -+ --- -Process name. -Sometimes called program name or similar. - -type: keyword - -example: ssh - --- - -*`process.name.text`*:: -+ --- -type: match_only_text - --- - -*`process.parent.args`*:: -+ --- -Array of process arguments, starting with the absolute path to the executable. -May be filtered to protect sensitive information. - -type: keyword - -example: ["/usr/bin/ssh", "-l", "user", "10.0.0.16"] - --- - -*`process.parent.args_count`*:: -+ --- -Length of the process.args array. -This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. - -type: long - -example: 4 - --- - -*`process.parent.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`process.parent.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`process.parent.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`process.parent.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`process.parent.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`process.parent.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`process.parent.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`process.parent.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`process.parent.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`process.parent.command_line`*:: -+ --- -Full command line that started the process, including the absolute path to the executable, and all arguments. -Some arguments may be filtered to protect sensitive information. - -type: wildcard - -example: /usr/bin/ssh -l user 10.0.0.16 - --- - -*`process.parent.command_line.text`*:: -+ --- -type: match_only_text - --- - -*`process.parent.elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`process.parent.elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`process.parent.elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`process.parent.elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`process.parent.elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`process.parent.elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`process.parent.elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`process.parent.elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`process.parent.elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`process.parent.elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`process.parent.elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`process.parent.elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`process.parent.elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`process.parent.elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`process.parent.elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`process.parent.elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`process.parent.elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`process.parent.elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`process.parent.elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`process.parent.elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`process.parent.elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`process.parent.elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`process.parent.elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`process.parent.elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`process.parent.elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`process.parent.elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`process.parent.elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`process.parent.elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`process.parent.elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -*`process.parent.end`*:: -+ --- -The time the process ended. - -type: date - -example: 2016-05-23T08:05:34.853Z - --- - -*`process.parent.entity_id`*:: -+ --- -Unique identifier for the process. -The implementation of this is specified by the data source, but some examples of what could be used here are a process-generated UUID, Sysmon Process GUIDs, or a hash of some uniquely identifying components of a process. -Constructing a globally unique identifier is a common practice to mitigate PID reuse as well as to identify a specific process over time, across multiple monitored hosts. - -type: keyword - -example: c2c455d9f99375d - --- - -*`process.parent.executable`*:: -+ --- -Absolute path to the process executable. - -type: keyword - -example: /usr/bin/ssh - --- - -*`process.parent.executable.text`*:: -+ --- -type: match_only_text - --- - -*`process.parent.exit_code`*:: -+ --- -The exit code of the process, if this is a termination event. -The field should be absent if there is no exit code for the event (e.g. process start). - -type: long - -example: 137 - --- - -*`process.parent.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`process.parent.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`process.parent.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`process.parent.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`process.parent.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`process.parent.name`*:: -+ --- -Process name. -Sometimes called program name or similar. - -type: keyword - -example: ssh - --- - -*`process.parent.name.text`*:: -+ --- -type: match_only_text - --- - -*`process.parent.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`process.parent.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`process.parent.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`process.parent.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`process.parent.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`process.parent.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`process.parent.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -*`process.parent.pgid`*:: -+ --- -Identifier of the group of processes the process belongs to. - -type: long - -format: string - --- - -*`process.parent.pid`*:: -+ --- -Process id. - -type: long - -example: 4242 - -format: string - --- - -*`process.parent.start`*:: -+ --- -The time the process started. - -type: date - -example: 2016-05-23T08:05:34.853Z - --- - -*`process.parent.thread.id`*:: -+ --- -Thread ID. - -type: long - -example: 4242 - -format: string - --- - -*`process.parent.thread.name`*:: -+ --- -Thread name. - -type: keyword - -example: thread-0 - --- - -*`process.parent.title`*:: -+ --- -Process title. -The proctitle, some times the same as process name. Can also be different: for example a browser setting its title to the web page currently opened. - -type: keyword - --- - -*`process.parent.title.text`*:: -+ --- -type: match_only_text - --- - -*`process.parent.uptime`*:: -+ --- -Seconds the process has been up. - -type: long - -example: 1325 - --- - -*`process.parent.working_directory`*:: -+ --- -The working directory of the process. - -type: keyword - -example: /home/alice - --- - -*`process.parent.working_directory.text`*:: -+ --- -type: match_only_text - --- - -*`process.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`process.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`process.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`process.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`process.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`process.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`process.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -*`process.pgid`*:: -+ --- -Identifier of the group of processes the process belongs to. - -type: long - -format: string - --- - -*`process.pid`*:: -+ --- -Process id. - -type: long - -example: 4242 - -format: string - --- - -*`process.start`*:: -+ --- -The time the process started. - -type: date - -example: 2016-05-23T08:05:34.853Z - --- - -*`process.thread.id`*:: -+ --- -Thread ID. - -type: long - -example: 4242 - -format: string - --- - -*`process.thread.name`*:: -+ --- -Thread name. - -type: keyword - -example: thread-0 - --- - -*`process.title`*:: -+ --- -Process title. -The proctitle, some times the same as process name. Can also be different: for example a browser setting its title to the web page currently opened. - -type: keyword - --- - -*`process.title.text`*:: -+ --- -type: match_only_text - --- - -*`process.uptime`*:: -+ --- -Seconds the process has been up. - -type: long - -example: 1325 - --- - -*`process.working_directory`*:: -+ --- -The working directory of the process. - -type: keyword - -example: /home/alice - --- - -*`process.working_directory.text`*:: -+ --- -type: match_only_text - --- - -[float] -=== registry - -Fields related to Windows Registry operations. - - -*`registry.data.bytes`*:: -+ --- -Original bytes written with base64 encoding. -For Windows registry operations, such as SetValueEx and RegQueryValueEx, this corresponds to the data pointed by `lp_data`. This is optional but provides better recoverability and should be populated for REG_BINARY encoded values. - -type: keyword - -example: ZQBuAC0AVQBTAAAAZQBuAAAAAAA= - --- - -*`registry.data.strings`*:: -+ --- -Content when writing string types. -Populated as an array when writing string data to the registry. For single string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with one string. For sequences of string with REG_MULTI_SZ, this array will be variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should be populated with the decimal representation (e.g `"1"`). - -type: wildcard - -example: ["C:\rta\red_ttp\bin\myapp.exe"] - --- - -*`registry.data.type`*:: -+ --- -Standard registry type for encoding contents - -type: keyword - -example: REG_SZ - --- - -*`registry.hive`*:: -+ --- -Abbreviated name for the hive. - -type: keyword - -example: HKLM - --- - -*`registry.key`*:: -+ --- -Hive-relative path of keys. - -type: keyword - -example: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe - --- - -*`registry.path`*:: -+ --- -Full path, including hive, key and value - -type: keyword - -example: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe\Debugger - --- - -*`registry.value`*:: -+ --- -Name of the value written. - -type: keyword - -example: Debugger - --- - -[float] -=== related - -This field set is meant to facilitate pivoting around a piece of data. -Some pieces of information can be seen in many places in an ECS event. To facilitate searching for them, store an array of all seen values to their corresponding field in `related.`. -A concrete example is IP addresses, which can be under host, observer, source, destination, client, server, and network.forwarded_ip. If you append all IPs to `related.ip`, you can then search for a given IP trivially, no matter where it appeared, by querying `related.ip:192.0.2.15`. - - -*`related.hash`*:: -+ --- -All the hashes seen on your event. Populating this field, then using it to search for hashes can help in situations where you're unsure what the hash algorithm is (and therefore which key name to search). - -type: keyword - --- - -*`related.hosts`*:: -+ --- -All hostnames or other host identifiers seen on your event. Example identifiers include FQDNs, domain names, workstation names, or aliases. - -type: keyword - --- - -*`related.ip`*:: -+ --- -All of the IPs seen on your event. - -type: ip - --- - -*`related.user`*:: -+ --- -All the user names or other user identifiers seen on the event. - -type: keyword - --- - -[float] -=== rule - -Rule fields are used to capture the specifics of any observer or agent rules that generate alerts or other notable events. -Examples of data sources that would populate the rule fields include: network admission control platforms, network or host IDS/IPS, network firewalls, web application firewalls, url filters, endpoint detection and response (EDR) systems, etc. - - -*`rule.author`*:: -+ --- -Name, organization, or pseudonym of the author or authors who created the rule used to generate this event. - -type: keyword - -example: ["Star-Lord"] - --- - -*`rule.category`*:: -+ --- -A categorization value keyword used by the entity using the rule for detection of this event. - -type: keyword - -example: Attempted Information Leak - --- - -*`rule.description`*:: -+ --- -The description of the rule generating the event. - -type: keyword - -example: Block requests to public DNS over HTTPS / TLS protocols - --- - -*`rule.id`*:: -+ --- -A rule ID that is unique within the scope of an agent, observer, or other entity using the rule for detection of this event. - -type: keyword - -example: 101 - --- - -*`rule.license`*:: -+ --- -Name of the license under which the rule used to generate this event is made available. - -type: keyword - -example: Apache 2.0 - --- - -*`rule.name`*:: -+ --- -The name of the rule or signature generating the event. - -type: keyword - -example: BLOCK_DNS_over_TLS - --- - -*`rule.reference`*:: -+ --- -Reference URL to additional information about the rule used to generate this event. -The URL can point to the vendor's documentation about the rule. If that's not available, it can also be a link to a more general page describing this type of alert. - -type: keyword - -example: https://en.wikipedia.org/wiki/DNS_over_TLS - --- - -*`rule.ruleset`*:: -+ --- -Name of the ruleset, policy, group, or parent category in which the rule used to generate this event is a member. - -type: keyword - -example: Standard_Protocol_Filters - --- - -*`rule.uuid`*:: -+ --- -A rule ID that is unique within the scope of a set or group of agents, observers, or other entities using the rule for detection of this event. - -type: keyword - -example: 1100110011 - --- - -*`rule.version`*:: -+ --- -The version / revision of the rule being used for analysis. - -type: keyword - -example: 1.1 - --- - -[float] -=== server - -A Server is defined as the responder in a network connection for events regarding sessions, connections, or bidirectional flow records. -For TCP events, the server is the receiver of the initial SYN packet(s) of the TCP connection. For other protocols, the server is generally the responder in the network transaction. Some systems actually use the term "responder" to refer the server in TCP connections. The server fields describe details about the system acting as the server in the network event. Server fields are usually populated in conjunction with client fields. Server fields are generally not populated for packet-level events. -Client / server representations can add semantic context to an exchange, which is helpful to visualize the data in certain situations. If your context falls in that category, you should still ensure that source and destination are filled appropriately. - - -*`server.address`*:: -+ --- -Some event server addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. -Then it should be duplicated to `.ip` or `.domain`, depending on which one it is. - -type: keyword - --- - -*`server.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`server.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`server.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`server.bytes`*:: -+ --- -Bytes sent from the server to the client. - -type: long - -example: 184 - -format: bytes - --- - -*`server.domain`*:: -+ --- -Server domain. - -type: keyword - --- - -*`server.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`server.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`server.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`server.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`server.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`server.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`server.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`server.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`server.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`server.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`server.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`server.ip`*:: -+ --- -IP address of the server (IPv4 or IPv6). - -type: ip - --- - -*`server.mac`*:: -+ --- -MAC address of the server. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: 00-00-5E-00-53-23 - --- - -*`server.nat.ip`*:: -+ --- -Translated ip of destination based NAT sessions (e.g. internet to private DMZ) -Typically used with load balancers, firewalls, or routers. - -type: ip - --- - -*`server.nat.port`*:: -+ --- -Translated port of destination based NAT sessions (e.g. internet to private DMZ) -Typically used with load balancers, firewalls, or routers. - -type: long - -format: string - --- - -*`server.packets`*:: -+ --- -Packets sent from the server to the client. - -type: long - -example: 12 - --- - -*`server.port`*:: -+ --- -Port of the server. - -type: long - -format: string - --- - -*`server.registered_domain`*:: -+ --- -The highest registered server domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`server.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`server.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`server.user.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`server.user.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`server.user.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`server.user.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`server.user.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`server.user.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`server.user.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`server.user.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`server.user.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`server.user.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`server.user.name.text`*:: -+ --- -type: match_only_text - --- - -*`server.user.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -[float] -=== service - -The service fields describe the service for or from which the data was collected. -These fields help you find and correlate logs for a specific service and version. - - -*`service.address`*:: -+ --- -Address where data about this service was collected from. -This should be a URI, network address (ipv4:port or [ipv6]:port) or a resource path (sockets). - -type: keyword - -example: 172.26.0.2:5432 - --- - -*`service.environment`*:: -+ --- -Identifies the environment where the service is running. -If the same service runs in different environments (production, staging, QA, development, etc.), the environment can identify other instances of the same service. Can also group services and applications from the same environment. - -type: keyword - -example: production - --- - -*`service.ephemeral_id`*:: -+ --- -Ephemeral identifier of this service (if one exists). -This id normally changes across restarts, but `service.id` does not. - -type: keyword - -example: 8a4f500f - --- - -*`service.id`*:: -+ --- -Unique identifier of the running service. If the service is comprised of many nodes, the `service.id` should be the same for all nodes. -This id should uniquely identify the service. This makes it possible to correlate logs and metrics for one specific service, no matter which particular node emitted the event. -Note that if you need to see the events from one specific host of the service, you should filter on that `host.name` or `host.id` instead. - -type: keyword - -example: d37e5ebfe0ae6c4972dbe9f0174a1637bb8247f6 - --- - -*`service.name`*:: -+ --- -Name of the service data is collected from. -The name of the service is normally user given. This allows for distributed services that run on multiple hosts to correlate the related instances based on the name. -In the case of Elasticsearch the `service.name` could contain the cluster name. For Beats the `service.name` is by default a copy of the `service.type` field if no name is specified. - -type: keyword - -example: elasticsearch-metrics - --- - -*`service.node.name`*:: -+ --- -Name of a service node. -This allows for two nodes of the same service running on the same host to be differentiated. Therefore, `service.node.name` should typically be unique across nodes of a given service. -In the case of Elasticsearch, the `service.node.name` could contain the unique node name within the Elasticsearch cluster. In cases where the service doesn't have the concept of a node name, the host name or container name can be used to distinguish running instances that make up this service. If those do not provide uniqueness (e.g. multiple instances of the service running on the same host) - the node name can be manually set. - -type: keyword - -example: instance-0000000016 - --- - -*`service.origin.address`*:: -+ --- -Address where data about this service was collected from. -This should be a URI, network address (ipv4:port or [ipv6]:port) or a resource path (sockets). - -type: keyword - -example: 172.26.0.2:5432 - --- - -*`service.origin.environment`*:: -+ --- -Identifies the environment where the service is running. -If the same service runs in different environments (production, staging, QA, development, etc.), the environment can identify other instances of the same service. Can also group services and applications from the same environment. - -type: keyword - -example: production - --- - -*`service.origin.ephemeral_id`*:: -+ --- -Ephemeral identifier of this service (if one exists). -This id normally changes across restarts, but `service.id` does not. - -type: keyword - -example: 8a4f500f - --- - -*`service.origin.id`*:: -+ --- -Unique identifier of the running service. If the service is comprised of many nodes, the `service.id` should be the same for all nodes. -This id should uniquely identify the service. This makes it possible to correlate logs and metrics for one specific service, no matter which particular node emitted the event. -Note that if you need to see the events from one specific host of the service, you should filter on that `host.name` or `host.id` instead. - -type: keyword - -example: d37e5ebfe0ae6c4972dbe9f0174a1637bb8247f6 - --- - -*`service.origin.name`*:: -+ --- -Name of the service data is collected from. -The name of the service is normally user given. This allows for distributed services that run on multiple hosts to correlate the related instances based on the name. -In the case of Elasticsearch the `service.name` could contain the cluster name. For Beats the `service.name` is by default a copy of the `service.type` field if no name is specified. - -type: keyword - -example: elasticsearch-metrics - --- - -*`service.origin.node.name`*:: -+ --- -Name of a service node. -This allows for two nodes of the same service running on the same host to be differentiated. Therefore, `service.node.name` should typically be unique across nodes of a given service. -In the case of Elasticsearch, the `service.node.name` could contain the unique node name within the Elasticsearch cluster. In cases where the service doesn't have the concept of a node name, the host name or container name can be used to distinguish running instances that make up this service. If those do not provide uniqueness (e.g. multiple instances of the service running on the same host) - the node name can be manually set. - -type: keyword - -example: instance-0000000016 - --- - -*`service.origin.state`*:: -+ --- -Current state of the service. - -type: keyword - --- - -*`service.origin.type`*:: -+ --- -The type of the service data is collected from. -The type can be used to group and correlate logs and metrics from one service type. -Example: If logs or metrics are collected from Elasticsearch, `service.type` would be `elasticsearch`. - -type: keyword - -example: elasticsearch - --- - -*`service.origin.version`*:: -+ --- -Version of the service the data was collected from. -This allows to look at a data set only for a specific version of a service. - -type: keyword - -example: 3.2.4 - --- - -*`service.state`*:: -+ --- -Current state of the service. - -type: keyword - --- - -*`service.target.address`*:: -+ --- -Address where data about this service was collected from. -This should be a URI, network address (ipv4:port or [ipv6]:port) or a resource path (sockets). - -type: keyword - -example: 172.26.0.2:5432 - --- - -*`service.target.environment`*:: -+ --- -Identifies the environment where the service is running. -If the same service runs in different environments (production, staging, QA, development, etc.), the environment can identify other instances of the same service. Can also group services and applications from the same environment. - -type: keyword - -example: production - --- - -*`service.target.ephemeral_id`*:: -+ --- -Ephemeral identifier of this service (if one exists). -This id normally changes across restarts, but `service.id` does not. - -type: keyword - -example: 8a4f500f - --- - -*`service.target.id`*:: -+ --- -Unique identifier of the running service. If the service is comprised of many nodes, the `service.id` should be the same for all nodes. -This id should uniquely identify the service. This makes it possible to correlate logs and metrics for one specific service, no matter which particular node emitted the event. -Note that if you need to see the events from one specific host of the service, you should filter on that `host.name` or `host.id` instead. - -type: keyword - -example: d37e5ebfe0ae6c4972dbe9f0174a1637bb8247f6 - --- - -*`service.target.name`*:: -+ --- -Name of the service data is collected from. -The name of the service is normally user given. This allows for distributed services that run on multiple hosts to correlate the related instances based on the name. -In the case of Elasticsearch the `service.name` could contain the cluster name. For Beats the `service.name` is by default a copy of the `service.type` field if no name is specified. - -type: keyword - -example: elasticsearch-metrics - --- - -*`service.target.node.name`*:: -+ --- -Name of a service node. -This allows for two nodes of the same service running on the same host to be differentiated. Therefore, `service.node.name` should typically be unique across nodes of a given service. -In the case of Elasticsearch, the `service.node.name` could contain the unique node name within the Elasticsearch cluster. In cases where the service doesn't have the concept of a node name, the host name or container name can be used to distinguish running instances that make up this service. If those do not provide uniqueness (e.g. multiple instances of the service running on the same host) - the node name can be manually set. - -type: keyword - -example: instance-0000000016 - --- - -*`service.target.state`*:: -+ --- -Current state of the service. - -type: keyword - --- - -*`service.target.type`*:: -+ --- -The type of the service data is collected from. -The type can be used to group and correlate logs and metrics from one service type. -Example: If logs or metrics are collected from Elasticsearch, `service.type` would be `elasticsearch`. - -type: keyword - -example: elasticsearch - --- - -*`service.target.version`*:: -+ --- -Version of the service the data was collected from. -This allows to look at a data set only for a specific version of a service. - -type: keyword - -example: 3.2.4 - --- - -*`service.type`*:: -+ --- -The type of the service data is collected from. -The type can be used to group and correlate logs and metrics from one service type. -Example: If logs or metrics are collected from Elasticsearch, `service.type` would be `elasticsearch`. - -type: keyword - -example: elasticsearch - --- - -*`service.version`*:: -+ --- -Version of the service the data was collected from. -This allows to look at a data set only for a specific version of a service. - -type: keyword - -example: 3.2.4 - --- - -[float] -=== source - -Source fields capture details about the sender of a network exchange/packet. These fields are populated from a network event, packet, or other event containing details of a network transaction. -Source fields are usually populated in conjunction with destination fields. The source and destination fields are considered the baseline and should always be filled if an event contains source and destination details from a network transaction. If the event also contains identification of the client and server roles, then the client and server fields should also be populated. - - -*`source.address`*:: -+ --- -Some event source addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. -Then it should be duplicated to `.ip` or `.domain`, depending on which one it is. - -type: keyword - --- - -*`source.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`source.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`source.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`source.bytes`*:: -+ --- -Bytes sent from the source to the destination. - -type: long - -example: 184 - -format: bytes - --- - -*`source.domain`*:: -+ --- -Source domain. - -type: keyword - --- - -*`source.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`source.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`source.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`source.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`source.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`source.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`source.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`source.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`source.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`source.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`source.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`source.ip`*:: -+ --- -IP address of the source (IPv4 or IPv6). - -type: ip - --- - -*`source.mac`*:: -+ --- -MAC address of the source. -The notation format from RFC 7042 is suggested: Each octet (that is, 8-bit byte) is represented by two [uppercase] hexadecimal digits giving the value of the octet as an unsigned integer. Successive octets are separated by a hyphen. - -type: keyword - -example: 00-00-5E-00-53-23 - --- - -*`source.nat.ip`*:: -+ --- -Translated ip of source based NAT sessions (e.g. internal client to internet) -Typically connections traversing load balancers, firewalls, or routers. - -type: ip - --- - -*`source.nat.port`*:: -+ --- -Translated port of source based NAT sessions. (e.g. internal client to internet) -Typically used with load balancers, firewalls, or routers. - -type: long - -format: string - --- - -*`source.packets`*:: -+ --- -Packets sent from the source to the destination. - -type: long - -example: 12 - --- - -*`source.port`*:: -+ --- -Port of the source. - -type: long - -format: string - --- - -*`source.registered_domain`*:: -+ --- -The highest registered source domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`source.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`source.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`source.user.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`source.user.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`source.user.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`source.user.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`source.user.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`source.user.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`source.user.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`source.user.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`source.user.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`source.user.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`source.user.name.text`*:: -+ --- -type: match_only_text - --- - -*`source.user.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -[float] -=== threat - -Fields to classify events and alerts according to a threat taxonomy such as the MITRE ATT&CK® framework. -These fields are for users to classify alerts from all of their sources (e.g. IDS, NGFW, etc.) within a common taxonomy. The threat.tactic.* fields are meant to capture the high level category of the threat (e.g. "impact"). The threat.technique.* fields are meant to capture which kind of approach is used by this detected threat, to accomplish the goal (e.g. "endpoint denial of service"). - - -*`threat.enrichments`*:: -+ --- -A list of associated indicators objects enriching the event, and the context of that association/enrichment. - -type: nested - --- - -*`threat.enrichments.indicator`*:: -+ --- -Object containing associated indicators enriching the event. - -type: object - --- - -*`threat.enrichments.indicator.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`threat.enrichments.indicator.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`threat.enrichments.indicator.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`threat.enrichments.indicator.confidence`*:: -+ --- -Identifies the vendor-neutral confidence rating using the None/Low/Medium/High scale defined in Appendix A of the STIX 2.1 framework. Vendor-specific confidence scales may be added as custom fields. -Expected values are: - * Not Specified - * None - * Low - * Medium - * High - -type: keyword - -example: Medium - --- - -*`threat.enrichments.indicator.description`*:: -+ --- -Describes the type of action conducted by the threat. - -type: keyword - -example: IP x.x.x.x was observed delivering the Angler EK. - --- - -*`threat.enrichments.indicator.email.address`*:: -+ --- -Identifies a threat indicator as an email address (irrespective of direction). - -type: keyword - -example: phish@example.com - --- - -*`threat.enrichments.indicator.file.accessed`*:: -+ --- -Last time the file was accessed. -Note that not all filesystems keep track of access time. - -type: date - --- - -*`threat.enrichments.indicator.file.attributes`*:: -+ --- -Array of file attributes. -Attributes names will vary by platform. Here's a non-exhaustive list of values that are expected in this field: archive, compressed, directory, encrypted, execute, hidden, read, readonly, system, write. - -type: keyword - -example: ["readonly", "system"] - --- - -*`threat.enrichments.indicator.file.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`threat.enrichments.indicator.file.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`threat.enrichments.indicator.file.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`threat.enrichments.indicator.file.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`threat.enrichments.indicator.file.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`threat.enrichments.indicator.file.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`threat.enrichments.indicator.file.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`threat.enrichments.indicator.file.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`threat.enrichments.indicator.file.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`threat.enrichments.indicator.file.created`*:: -+ --- -File creation time. -Note that not all filesystems store the creation time. - -type: date - --- - -*`threat.enrichments.indicator.file.ctime`*:: -+ --- -Last time the file attributes or metadata changed. -Note that changes to the file content will update `mtime`. This implies `ctime` will be adjusted at the same time, since `mtime` is an attribute of the file. - -type: date - --- - -*`threat.enrichments.indicator.file.device`*:: -+ --- -Device that is the source of the file. - -type: keyword - -example: sda - --- - -*`threat.enrichments.indicator.file.directory`*:: -+ --- -Directory where the file is located. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice - --- - -*`threat.enrichments.indicator.file.drive_letter`*:: -+ --- -Drive letter where the file is located. This field is only relevant on Windows. -The value should be uppercase, and not include the colon. - -type: keyword - -example: C - --- - -*`threat.enrichments.indicator.file.elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`threat.enrichments.indicator.file.elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`threat.enrichments.indicator.file.elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`threat.enrichments.indicator.file.elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`threat.enrichments.indicator.file.elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`threat.enrichments.indicator.file.elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`threat.enrichments.indicator.file.elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`threat.enrichments.indicator.file.elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`threat.enrichments.indicator.file.elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`threat.enrichments.indicator.file.elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`threat.enrichments.indicator.file.elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`threat.enrichments.indicator.file.elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`threat.enrichments.indicator.file.elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`threat.enrichments.indicator.file.elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`threat.enrichments.indicator.file.elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`threat.enrichments.indicator.file.elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -*`threat.enrichments.indicator.file.extension`*:: -+ --- -File extension, excluding the leading dot. -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`threat.enrichments.indicator.file.fork_name`*:: -+ --- -A fork is additional data associated with a filesystem object. -On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. -On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. An ADS is typically of the form: `C:\path\to\filename.extension:some_fork_name`, and `some_fork_name` is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. - -type: keyword - -example: Zone.Identifer - --- - -*`threat.enrichments.indicator.file.gid`*:: -+ --- -Primary group ID (GID) of the file. - -type: keyword - -example: 1001 - --- - -*`threat.enrichments.indicator.file.group`*:: -+ --- -Primary group name of the file. - -type: keyword - -example: alice - --- - -*`threat.enrichments.indicator.file.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`threat.enrichments.indicator.file.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`threat.enrichments.indicator.file.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`threat.enrichments.indicator.file.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`threat.enrichments.indicator.file.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`threat.enrichments.indicator.file.inode`*:: -+ --- -Inode representing the file in the filesystem. - -type: keyword - -example: 256383 - --- - -*`threat.enrichments.indicator.file.mime_type`*:: -+ --- -MIME type should identify the format of the file or stream of bytes using https://www.iana.org/assignments/media-types/media-types.xhtml[IANA official types], where possible. When more than one type is applicable, the most specific type should be used. - -type: keyword - --- - -*`threat.enrichments.indicator.file.mode`*:: -+ --- -Mode of the file in octal representation. - -type: keyword - -example: 0640 - --- - -*`threat.enrichments.indicator.file.mtime`*:: -+ --- -Last time the file content was modified. - -type: date - --- - -*`threat.enrichments.indicator.file.name`*:: -+ --- -Name of the file including the extension, without the directory. - -type: keyword - -example: example.png - --- - -*`threat.enrichments.indicator.file.owner`*:: -+ --- -File owner's username. - -type: keyword - -example: alice - --- - -*`threat.enrichments.indicator.file.path`*:: -+ --- -Full path to the file, including the file name. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice/example.png - --- - -*`threat.enrichments.indicator.file.path.text`*:: -+ --- -type: match_only_text - --- - -*`threat.enrichments.indicator.file.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`threat.enrichments.indicator.file.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`threat.enrichments.indicator.file.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`threat.enrichments.indicator.file.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`threat.enrichments.indicator.file.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`threat.enrichments.indicator.file.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`threat.enrichments.indicator.file.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -*`threat.enrichments.indicator.file.size`*:: -+ --- -File size in bytes. -Only relevant when `file.type` is "file". - -type: long - -example: 16384 - --- - -*`threat.enrichments.indicator.file.target_path`*:: -+ --- -Target path for symlinks. - -type: keyword - --- - -*`threat.enrichments.indicator.file.target_path.text`*:: -+ --- -type: match_only_text - --- - -*`threat.enrichments.indicator.file.type`*:: -+ --- -File type (file, dir, or symlink). - -type: keyword - -example: file - --- - -*`threat.enrichments.indicator.file.uid`*:: -+ --- -The user ID (UID) or security identifier (SID) of the file owner. - -type: keyword - -example: 1001 - --- - -*`threat.enrichments.indicator.file.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`threat.enrichments.indicator.file.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`threat.enrichments.indicator.file.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`threat.enrichments.indicator.file.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`threat.enrichments.indicator.file.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`threat.enrichments.indicator.file.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`threat.enrichments.indicator.file.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`threat.enrichments.indicator.file.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.enrichments.indicator.file.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`threat.enrichments.indicator.file.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`threat.enrichments.indicator.file.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`threat.enrichments.indicator.file.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`threat.enrichments.indicator.file.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`threat.enrichments.indicator.file.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`threat.enrichments.indicator.file.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`threat.enrichments.indicator.file.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`threat.enrichments.indicator.file.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`threat.enrichments.indicator.file.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`threat.enrichments.indicator.file.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`threat.enrichments.indicator.file.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`threat.enrichments.indicator.file.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`threat.enrichments.indicator.file.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`threat.enrichments.indicator.file.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.enrichments.indicator.file.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`threat.enrichments.indicator.first_seen`*:: -+ --- -The date and time when intelligence source first reported sighting this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.enrichments.indicator.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`threat.enrichments.indicator.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`threat.enrichments.indicator.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`threat.enrichments.indicator.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`threat.enrichments.indicator.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`threat.enrichments.indicator.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`threat.enrichments.indicator.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`threat.enrichments.indicator.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`threat.enrichments.indicator.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`threat.enrichments.indicator.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`threat.enrichments.indicator.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`threat.enrichments.indicator.ip`*:: -+ --- -Identifies a threat indicator as an IP address (irrespective of direction). - -type: ip - -example: 1.2.3.4 - --- - -*`threat.enrichments.indicator.last_seen`*:: -+ --- -The date and time when intelligence source last reported sighting this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.enrichments.indicator.marking.tlp`*:: -+ --- -Traffic Light Protocol sharing markings. Recommended values are: - * WHITE - * GREEN - * AMBER - * RED - -type: keyword - -example: White - --- - -*`threat.enrichments.indicator.modified_at`*:: -+ --- -The date and time when intelligence source last modified information for this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.enrichments.indicator.port`*:: -+ --- -Identifies a threat indicator as a port number (irrespective of direction). - -type: long - -example: 443 - --- - -*`threat.enrichments.indicator.provider`*:: -+ --- -The name of the indicator's provider. - -type: keyword - -example: lrz_urlhaus - --- - -*`threat.enrichments.indicator.reference`*:: -+ --- -Reference URL linking to additional information about this indicator. - -type: keyword - -example: https://system.example.com/indicator/0001234 - --- - -*`threat.enrichments.indicator.registry.data.bytes`*:: -+ --- -Original bytes written with base64 encoding. -For Windows registry operations, such as SetValueEx and RegQueryValueEx, this corresponds to the data pointed by `lp_data`. This is optional but provides better recoverability and should be populated for REG_BINARY encoded values. - -type: keyword - -example: ZQBuAC0AVQBTAAAAZQBuAAAAAAA= - --- - -*`threat.enrichments.indicator.registry.data.strings`*:: -+ --- -Content when writing string types. -Populated as an array when writing string data to the registry. For single string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with one string. For sequences of string with REG_MULTI_SZ, this array will be variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should be populated with the decimal representation (e.g `"1"`). - -type: wildcard - -example: ["C:\rta\red_ttp\bin\myapp.exe"] - --- - -*`threat.enrichments.indicator.registry.data.type`*:: -+ --- -Standard registry type for encoding contents - -type: keyword - -example: REG_SZ - --- - -*`threat.enrichments.indicator.registry.hive`*:: -+ --- -Abbreviated name for the hive. - -type: keyword - -example: HKLM - --- - -*`threat.enrichments.indicator.registry.key`*:: -+ --- -Hive-relative path of keys. - -type: keyword - -example: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe - --- - -*`threat.enrichments.indicator.registry.path`*:: -+ --- -Full path, including hive, key and value - -type: keyword - -example: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe\Debugger - --- - -*`threat.enrichments.indicator.registry.value`*:: -+ --- -Name of the value written. - -type: keyword - -example: Debugger - --- - -*`threat.enrichments.indicator.scanner_stats`*:: -+ --- -Count of AV/EDR vendors that successfully detected malicious file or URL. - -type: long - -example: 4 - --- - -*`threat.enrichments.indicator.sightings`*:: -+ --- -Number of times this indicator was observed conducting threat activity. - -type: long - -example: 20 - --- - -*`threat.enrichments.indicator.type`*:: -+ --- -Type of indicator as represented by Cyber Observable in STIX 2.0. Recommended values: - * autonomous-system - * artifact - * directory - * domain-name - * email-addr - * file - * ipv4-addr - * ipv6-addr - * mac-addr - * mutex - * port - * process - * software - * url - * user-account - * windows-registry-key - * x509-certificate - -type: keyword - -example: ipv4-addr - --- - -*`threat.enrichments.indicator.url.domain`*:: -+ --- -Domain of the url, such as "www.elastic.co". -In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the `domain` field. -If the URL contains a literal IPv6 address enclosed by `[` and `]` (IETF RFC 2732), the `[` and `]` characters should also be captured in the `domain` field. - -type: keyword - -example: www.elastic.co - --- - -*`threat.enrichments.indicator.url.extension`*:: -+ --- -The field contains the file extension from the original request url, excluding the leading dot. -The file extension is only set if it exists, as not every url has a file extension. -The leading period must not be included. For example, the value must be "png", not ".png". -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`threat.enrichments.indicator.url.fragment`*:: -+ --- -Portion of the url after the `#`, such as "top". -The `#` is not part of the fragment. - -type: keyword - --- - -*`threat.enrichments.indicator.url.full`*:: -+ --- -If full URLs are important to your use case, they should be stored in `url.full`, whether this field is reconstructed or present in the event source. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top - --- - -*`threat.enrichments.indicator.url.full.text`*:: -+ --- -type: match_only_text - --- - -*`threat.enrichments.indicator.url.original`*:: -+ --- -Unmodified original url as seen in the event source. -Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. -This field is meant to represent the URL as it was observed, complete or not. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top or /search?q=elasticsearch - --- - -*`threat.enrichments.indicator.url.original.text`*:: -+ --- -type: match_only_text - --- - -*`threat.enrichments.indicator.url.password`*:: -+ --- -Password of the request. - -type: keyword - --- - -*`threat.enrichments.indicator.url.path`*:: -+ --- -Path of the request, such as "/search". - -type: wildcard - --- - -*`threat.enrichments.indicator.url.port`*:: -+ --- -Port of the request, such as 443. - -type: long - -example: 443 - -format: string - --- - -*`threat.enrichments.indicator.url.query`*:: -+ --- -The query field describes the query string of the request, such as "q=elasticsearch". -The `?` is excluded from the query string. If a URL contains no `?`, there is no query field. If there is a `?` but no query, the query field exists with an empty string. The `exists` query can be used to differentiate between the two cases. - -type: keyword - --- - -*`threat.enrichments.indicator.url.registered_domain`*:: -+ --- -The highest registered url domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`threat.enrichments.indicator.url.scheme`*:: -+ --- -Scheme of the request, such as "https". -Note: The `:` is not part of the scheme. - -type: keyword - -example: https - --- - -*`threat.enrichments.indicator.url.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`threat.enrichments.indicator.url.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`threat.enrichments.indicator.url.username`*:: -+ --- -Username of the request. - -type: keyword - --- - -*`threat.enrichments.indicator.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`threat.enrichments.indicator.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`threat.enrichments.indicator.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`threat.enrichments.indicator.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`threat.enrichments.indicator.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`threat.enrichments.indicator.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`threat.enrichments.indicator.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`threat.enrichments.indicator.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.enrichments.indicator.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`threat.enrichments.indicator.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`threat.enrichments.indicator.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`threat.enrichments.indicator.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`threat.enrichments.indicator.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`threat.enrichments.indicator.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`threat.enrichments.indicator.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`threat.enrichments.indicator.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`threat.enrichments.indicator.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`threat.enrichments.indicator.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`threat.enrichments.indicator.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`threat.enrichments.indicator.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`threat.enrichments.indicator.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`threat.enrichments.indicator.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`threat.enrichments.indicator.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.enrichments.indicator.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`threat.enrichments.matched.atomic`*:: -+ --- -Identifies the atomic indicator value that matched a local environment endpoint or network event. - -type: keyword - -example: bad-domain.com - --- - -*`threat.enrichments.matched.field`*:: -+ --- -Identifies the field of the atomic indicator that matched a local environment endpoint or network event. - -type: keyword - -example: file.hash.sha256 - --- - -*`threat.enrichments.matched.id`*:: -+ --- -Identifies the _id of the indicator document enriching the event. - -type: keyword - -example: ff93aee5-86a1-4a61-b0e6-0cdc313d01b5 - --- - -*`threat.enrichments.matched.index`*:: -+ --- -Identifies the _index of the indicator document enriching the event. - -type: keyword - -example: filebeat-8.0.0-2021.05.23-000011 - --- - -*`threat.enrichments.matched.type`*:: -+ --- -Identifies the type of match that caused the event to be enriched with the given indicator - -type: keyword - -example: indicator_match_rule - --- - -*`threat.framework`*:: -+ --- -Name of the threat framework used to further categorize and classify the tactic and technique of the reported threat. Framework classification can be provided by detecting systems, evaluated at ingest time, or retrospectively tagged to events. - -type: keyword - -example: MITRE ATT&CK - --- - -*`threat.group.alias`*:: -+ --- -The alias(es) of the group for a set of related intrusion activity that are tracked by a common name in the security community. -While not required, you can use a MITRE ATT&CK® group alias(es). - -type: keyword - -example: [ "Magecart Group 6" ] - --- - -*`threat.group.id`*:: -+ --- -The id of the group for a set of related intrusion activity that are tracked by a common name in the security community. -While not required, you can use a MITRE ATT&CK® group id. - -type: keyword - -example: G0037 - --- - -*`threat.group.name`*:: -+ --- -The name of the group for a set of related intrusion activity that are tracked by a common name in the security community. -While not required, you can use a MITRE ATT&CK® group name. - -type: keyword - -example: FIN6 - --- - -*`threat.group.reference`*:: -+ --- -The reference URL of the group for a set of related intrusion activity that are tracked by a common name in the security community. -While not required, you can use a MITRE ATT&CK® group reference URL. - -type: keyword - -example: https://attack.mitre.org/groups/G0037/ - --- - -*`threat.indicator.as.number`*:: -+ --- -Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. - -type: long - -example: 15169 - --- - -*`threat.indicator.as.organization.name`*:: -+ --- -Organization name. - -type: keyword - -example: Google LLC - --- - -*`threat.indicator.as.organization.name.text`*:: -+ --- -type: match_only_text - --- - -*`threat.indicator.confidence`*:: -+ --- -Identifies the vendor-neutral confidence rating using the None/Low/Medium/High scale defined in Appendix A of the STIX 2.1 framework. Vendor-specific confidence scales may be added as custom fields. -Expected values are: - * Not Specified - * None - * Low - * Medium - * High - -type: keyword - -example: Medium - --- - -*`threat.indicator.description`*:: -+ --- -Describes the type of action conducted by the threat. - -type: keyword - -example: IP x.x.x.x was observed delivering the Angler EK. - --- - -*`threat.indicator.email.address`*:: -+ --- -Identifies a threat indicator as an email address (irrespective of direction). - -type: keyword - -example: phish@example.com - --- - -*`threat.indicator.file.accessed`*:: -+ --- -Last time the file was accessed. -Note that not all filesystems keep track of access time. - -type: date - --- - -*`threat.indicator.file.attributes`*:: -+ --- -Array of file attributes. -Attributes names will vary by platform. Here's a non-exhaustive list of values that are expected in this field: archive, compressed, directory, encrypted, execute, hidden, read, readonly, system, write. - -type: keyword - -example: ["readonly", "system"] - --- - -*`threat.indicator.file.code_signature.digest_algorithm`*:: -+ --- -The hashing algorithm used to sign the process. -This value can distinguish signatures when a file is signed multiple times by the same signer but with a different digest algorithm. - -type: keyword - -example: sha256 - --- - -*`threat.indicator.file.code_signature.exists`*:: -+ --- -Boolean to capture if a signature is present. - -type: boolean - -example: true - --- - -*`threat.indicator.file.code_signature.signing_id`*:: -+ --- -The identifier used to sign the process. -This is used to identify the application manufactured by a software vendor. The field is relevant to Apple *OS only. - -type: keyword - -example: com.apple.xpc.proxy - --- - -*`threat.indicator.file.code_signature.status`*:: -+ --- -Additional information about the certificate status. -This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked. - -type: keyword - -example: ERROR_UNTRUSTED_ROOT - --- - -*`threat.indicator.file.code_signature.subject_name`*:: -+ --- -Subject name of the code signer - -type: keyword - -example: Microsoft Corporation - --- - -*`threat.indicator.file.code_signature.team_id`*:: -+ --- -The team identifier used to sign the process. -This is used to identify the team or vendor of a software product. The field is relevant to Apple *OS only. - -type: keyword - -example: EQHXZ8M8AV - --- - -*`threat.indicator.file.code_signature.timestamp`*:: -+ --- -Date and time when the code signature was generated and signed. - -type: date - -example: 2021-01-01T12:10:30Z - --- - -*`threat.indicator.file.code_signature.trusted`*:: -+ --- -Stores the trust status of the certificate chain. -Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status. - -type: boolean - -example: true - --- - -*`threat.indicator.file.code_signature.valid`*:: -+ --- -Boolean to capture if the digital signature is verified against the binary content. -Leave unpopulated if a certificate was unchecked. - -type: boolean - -example: true - --- - -*`threat.indicator.file.created`*:: -+ --- -File creation time. -Note that not all filesystems store the creation time. - -type: date - --- - -*`threat.indicator.file.ctime`*:: -+ --- -Last time the file attributes or metadata changed. -Note that changes to the file content will update `mtime`. This implies `ctime` will be adjusted at the same time, since `mtime` is an attribute of the file. - -type: date - --- - -*`threat.indicator.file.device`*:: -+ --- -Device that is the source of the file. - -type: keyword - -example: sda - --- - -*`threat.indicator.file.directory`*:: -+ --- -Directory where the file is located. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice - --- - -*`threat.indicator.file.drive_letter`*:: -+ --- -Drive letter where the file is located. This field is only relevant on Windows. -The value should be uppercase, and not include the colon. - -type: keyword - -example: C - --- - -*`threat.indicator.file.elf.architecture`*:: -+ --- -Machine architecture of the ELF file. - -type: keyword - -example: x86-64 - --- - -*`threat.indicator.file.elf.byte_order`*:: -+ --- -Byte sequence of ELF file. - -type: keyword - -example: Little Endian - --- - -*`threat.indicator.file.elf.cpu_type`*:: -+ --- -CPU type of the ELF file. - -type: keyword - -example: Intel - --- - -*`threat.indicator.file.elf.creation_date`*:: -+ --- -Extracted when possible from the file's metadata. Indicates when it was built or compiled. It can also be faked by malware creators. - -type: date - --- - -*`threat.indicator.file.elf.exports`*:: -+ --- -List of exported element names and types. - -type: flattened - --- - -*`threat.indicator.file.elf.header.abi_version`*:: -+ --- -Version of the ELF Application Binary Interface (ABI). - -type: keyword - --- - -*`threat.indicator.file.elf.header.class`*:: -+ --- -Header class of the ELF file. - -type: keyword - --- - -*`threat.indicator.file.elf.header.data`*:: -+ --- -Data table of the ELF header. - -type: keyword - --- - -*`threat.indicator.file.elf.header.entrypoint`*:: -+ --- -Header entrypoint of the ELF file. - -type: long - -format: string - --- - -*`threat.indicator.file.elf.header.object_version`*:: -+ --- -"0x1" for original ELF files. - -type: keyword - --- - -*`threat.indicator.file.elf.header.os_abi`*:: -+ --- -Application Binary Interface (ABI) of the Linux OS. - -type: keyword - --- - -*`threat.indicator.file.elf.header.type`*:: -+ --- -Header type of the ELF file. - -type: keyword - --- - -*`threat.indicator.file.elf.header.version`*:: -+ --- -Version of the ELF header. - -type: keyword - --- - -*`threat.indicator.file.elf.imports`*:: -+ --- -List of imported element names and types. - -type: flattened - --- - -*`threat.indicator.file.elf.sections`*:: -+ --- -An array containing an object for each section of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.sections.*`. - -type: nested - --- - -*`threat.indicator.file.elf.sections.chi2`*:: -+ --- -Chi-square probability distribution of the section. - -type: long - -format: number - --- - -*`threat.indicator.file.elf.sections.entropy`*:: -+ --- -Shannon entropy calculation from the section. - -type: long - -format: number - --- - -*`threat.indicator.file.elf.sections.flags`*:: -+ --- -ELF Section List flags. - -type: keyword - --- - -*`threat.indicator.file.elf.sections.name`*:: -+ --- -ELF Section List name. - -type: keyword - --- - -*`threat.indicator.file.elf.sections.physical_offset`*:: -+ --- -ELF Section List offset. - -type: keyword - --- - -*`threat.indicator.file.elf.sections.physical_size`*:: -+ --- -ELF Section List physical size. - -type: long - -format: bytes - --- - -*`threat.indicator.file.elf.sections.type`*:: -+ --- -ELF Section List type. - -type: keyword - --- - -*`threat.indicator.file.elf.sections.virtual_address`*:: -+ --- -ELF Section List virtual address. - -type: long - -format: string - --- - -*`threat.indicator.file.elf.sections.virtual_size`*:: -+ --- -ELF Section List virtual size. - -type: long - -format: string - --- - -*`threat.indicator.file.elf.segments`*:: -+ --- -An array containing an object for each segment of the ELF file. -The keys that should be present in these objects are defined by sub-fields underneath `elf.segments.*`. - -type: nested - --- - -*`threat.indicator.file.elf.segments.sections`*:: -+ --- -ELF object segment sections. - -type: keyword - --- - -*`threat.indicator.file.elf.segments.type`*:: -+ --- -ELF object segment type. - -type: keyword - --- - -*`threat.indicator.file.elf.shared_libraries`*:: -+ --- -List of shared libraries used by this ELF object. - -type: keyword - --- - -*`threat.indicator.file.elf.telfhash`*:: -+ --- -telfhash symbol hash for ELF file. - -type: keyword - --- - -*`threat.indicator.file.extension`*:: -+ --- -File extension, excluding the leading dot. -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`threat.indicator.file.fork_name`*:: -+ --- -A fork is additional data associated with a filesystem object. -On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. -On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. An ADS is typically of the form: `C:\path\to\filename.extension:some_fork_name`, and `some_fork_name` is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. - -type: keyword - -example: Zone.Identifer - --- - -*`threat.indicator.file.gid`*:: -+ --- -Primary group ID (GID) of the file. - -type: keyword - -example: 1001 - --- - -*`threat.indicator.file.group`*:: -+ --- -Primary group name of the file. - -type: keyword - -example: alice - --- - -*`threat.indicator.file.hash.md5`*:: -+ --- -MD5 hash. - -type: keyword - --- - -*`threat.indicator.file.hash.sha1`*:: -+ --- -SHA1 hash. - -type: keyword - --- - -*`threat.indicator.file.hash.sha256`*:: -+ --- -SHA256 hash. - -type: keyword - --- - -*`threat.indicator.file.hash.sha512`*:: -+ --- -SHA512 hash. - -type: keyword - --- - -*`threat.indicator.file.hash.ssdeep`*:: -+ --- -SSDEEP hash. - -type: keyword - --- - -*`threat.indicator.file.inode`*:: -+ --- -Inode representing the file in the filesystem. - -type: keyword - -example: 256383 - --- - -*`threat.indicator.file.mime_type`*:: -+ --- -MIME type should identify the format of the file or stream of bytes using https://www.iana.org/assignments/media-types/media-types.xhtml[IANA official types], where possible. When more than one type is applicable, the most specific type should be used. - -type: keyword - --- - -*`threat.indicator.file.mode`*:: -+ --- -Mode of the file in octal representation. - -type: keyword - -example: 0640 - --- - -*`threat.indicator.file.mtime`*:: -+ --- -Last time the file content was modified. - -type: date - --- - -*`threat.indicator.file.name`*:: -+ --- -Name of the file including the extension, without the directory. - -type: keyword - -example: example.png - --- - -*`threat.indicator.file.owner`*:: -+ --- -File owner's username. - -type: keyword - -example: alice - --- - -*`threat.indicator.file.path`*:: -+ --- -Full path to the file, including the file name. It should include the drive letter, when appropriate. - -type: keyword - -example: /home/alice/example.png - --- - -*`threat.indicator.file.path.text`*:: -+ --- -type: match_only_text - --- - -*`threat.indicator.file.pe.architecture`*:: -+ --- -CPU architecture target for the file. - -type: keyword - -example: x64 - --- - -*`threat.indicator.file.pe.company`*:: -+ --- -Internal company name of the file, provided at compile-time. - -type: keyword - -example: Microsoft Corporation - --- - -*`threat.indicator.file.pe.description`*:: -+ --- -Internal description of the file, provided at compile-time. - -type: keyword - -example: Paint - --- - -*`threat.indicator.file.pe.file_version`*:: -+ --- -Internal version of the file, provided at compile-time. - -type: keyword - -example: 6.3.9600.17415 - --- - -*`threat.indicator.file.pe.imphash`*:: -+ --- -A hash of the imports in a PE file. An imphash -- or import hash -- can be used to fingerprint binaries even after recompilation or other code-level transformations have occurred, which would change more traditional hash values. -Learn more at https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html. - -type: keyword - -example: 0c6803c4e922103c4dca5963aad36ddf - --- - -*`threat.indicator.file.pe.original_file_name`*:: -+ --- -Internal name of the file, provided at compile-time. - -type: keyword - -example: MSPAINT.EXE - --- - -*`threat.indicator.file.pe.product`*:: -+ --- -Internal product name of the file, provided at compile-time. - -type: keyword - -example: Microsoft® Windows® Operating System - --- - -*`threat.indicator.file.size`*:: -+ --- -File size in bytes. -Only relevant when `file.type` is "file". - -type: long - -example: 16384 - --- - -*`threat.indicator.file.target_path`*:: -+ --- -Target path for symlinks. - -type: keyword - --- - -*`threat.indicator.file.target_path.text`*:: -+ --- -type: match_only_text - --- - -*`threat.indicator.file.type`*:: -+ --- -File type (file, dir, or symlink). - -type: keyword - -example: file - --- - -*`threat.indicator.file.uid`*:: -+ --- -The user ID (UID) or security identifier (SID) of the file owner. - -type: keyword - -example: 1001 - --- - -*`threat.indicator.file.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`threat.indicator.file.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`threat.indicator.file.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`threat.indicator.file.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`threat.indicator.file.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`threat.indicator.file.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`threat.indicator.file.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`threat.indicator.file.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.indicator.file.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`threat.indicator.file.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`threat.indicator.file.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`threat.indicator.file.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`threat.indicator.file.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`threat.indicator.file.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`threat.indicator.file.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`threat.indicator.file.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`threat.indicator.file.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`threat.indicator.file.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`threat.indicator.file.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`threat.indicator.file.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`threat.indicator.file.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`threat.indicator.file.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`threat.indicator.file.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.indicator.file.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`threat.indicator.first_seen`*:: -+ --- -The date and time when intelligence source first reported sighting this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.indicator.geo.city_name`*:: -+ --- -City name. - -type: keyword - -example: Montreal - --- - -*`threat.indicator.geo.continent_code`*:: -+ --- -Two-letter code representing continent's name. - -type: keyword - -example: NA - --- - -*`threat.indicator.geo.continent_name`*:: -+ --- -Name of the continent. - -type: keyword - -example: North America - --- - -*`threat.indicator.geo.country_iso_code`*:: -+ --- -Country ISO code. - -type: keyword - -example: CA - --- - -*`threat.indicator.geo.country_name`*:: -+ --- -Country name. - -type: keyword - -example: Canada - --- - -*`threat.indicator.geo.location`*:: -+ --- -Longitude and latitude. - -type: geo_point - -example: { "lon": -73.614830, "lat": 45.505918 } - --- - -*`threat.indicator.geo.name`*:: -+ --- -User-defined description of a location, at the level of granularity they care about. -Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. -Not typically used in automated geolocation. - -type: keyword - -example: boston-dc - --- - -*`threat.indicator.geo.postal_code`*:: -+ --- -Postal code associated with the location. -Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. - -type: keyword - -example: 94040 - --- - -*`threat.indicator.geo.region_iso_code`*:: -+ --- -Region ISO code. - -type: keyword - -example: CA-QC - --- - -*`threat.indicator.geo.region_name`*:: -+ --- -Region name. - -type: keyword - -example: Quebec - --- - -*`threat.indicator.geo.timezone`*:: -+ --- -The time zone of the location, such as IANA time zone name. - -type: keyword - -example: America/Argentina/Buenos_Aires - --- - -*`threat.indicator.ip`*:: -+ --- -Identifies a threat indicator as an IP address (irrespective of direction). - -type: ip - -example: 1.2.3.4 - --- - -*`threat.indicator.last_seen`*:: -+ --- -The date and time when intelligence source last reported sighting this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.indicator.marking.tlp`*:: -+ --- -Traffic Light Protocol sharing markings. -Recommended values are: - * WHITE - * GREEN - * AMBER - * RED - -type: keyword - -example: WHITE - --- - -*`threat.indicator.modified_at`*:: -+ --- -The date and time when intelligence source last modified information for this indicator. - -type: date - -example: 2020-11-05T17:25:47.000Z - --- - -*`threat.indicator.port`*:: -+ --- -Identifies a threat indicator as a port number (irrespective of direction). - -type: long - -example: 443 - --- - -*`threat.indicator.provider`*:: -+ --- -The name of the indicator's provider. - -type: keyword - -example: lrz_urlhaus - --- - -*`threat.indicator.reference`*:: -+ --- -Reference URL linking to additional information about this indicator. - -type: keyword - -example: https://system.example.com/indicator/0001234 - --- - -*`threat.indicator.registry.data.bytes`*:: -+ --- -Original bytes written with base64 encoding. -For Windows registry operations, such as SetValueEx and RegQueryValueEx, this corresponds to the data pointed by `lp_data`. This is optional but provides better recoverability and should be populated for REG_BINARY encoded values. - -type: keyword - -example: ZQBuAC0AVQBTAAAAZQBuAAAAAAA= - --- - -*`threat.indicator.registry.data.strings`*:: -+ --- -Content when writing string types. -Populated as an array when writing string data to the registry. For single string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with one string. For sequences of string with REG_MULTI_SZ, this array will be variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should be populated with the decimal representation (e.g `"1"`). - -type: wildcard - -example: ["C:\rta\red_ttp\bin\myapp.exe"] - --- - -*`threat.indicator.registry.data.type`*:: -+ --- -Standard registry type for encoding contents - -type: keyword - -example: REG_SZ - --- - -*`threat.indicator.registry.hive`*:: -+ --- -Abbreviated name for the hive. - -type: keyword - -example: HKLM - --- - -*`threat.indicator.registry.key`*:: -+ --- -Hive-relative path of keys. - -type: keyword - -example: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe - --- - -*`threat.indicator.registry.path`*:: -+ --- -Full path, including hive, key and value - -type: keyword - -example: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\winword.exe\Debugger - --- - -*`threat.indicator.registry.value`*:: -+ --- -Name of the value written. - -type: keyword - -example: Debugger - --- - -*`threat.indicator.scanner_stats`*:: -+ --- -Count of AV/EDR vendors that successfully detected malicious file or URL. - -type: long - -example: 4 - --- - -*`threat.indicator.sightings`*:: -+ --- -Number of times this indicator was observed conducting threat activity. - -type: long - -example: 20 - --- - -*`threat.indicator.type`*:: -+ --- -Type of indicator as represented by Cyber Observable in STIX 2.0. -Recommended values: - * autonomous-system - * artifact - * directory - * domain-name - * email-addr - * file - * ipv4-addr - * ipv6-addr - * mac-addr - * mutex - * port - * process - * software - * url - * user-account - * windows-registry-key - * x509-certificate - -type: keyword - -example: ipv4-addr - --- - -*`threat.indicator.url.domain`*:: -+ --- -Domain of the url, such as "www.elastic.co". -In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the `domain` field. -If the URL contains a literal IPv6 address enclosed by `[` and `]` (IETF RFC 2732), the `[` and `]` characters should also be captured in the `domain` field. - -type: keyword - -example: www.elastic.co - --- - -*`threat.indicator.url.extension`*:: -+ --- -The field contains the file extension from the original request url, excluding the leading dot. -The file extension is only set if it exists, as not every url has a file extension. -The leading period must not be included. For example, the value must be "png", not ".png". -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`threat.indicator.url.fragment`*:: -+ --- -Portion of the url after the `#`, such as "top". -The `#` is not part of the fragment. - -type: keyword - --- - -*`threat.indicator.url.full`*:: -+ --- -If full URLs are important to your use case, they should be stored in `url.full`, whether this field is reconstructed or present in the event source. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top - --- - -*`threat.indicator.url.full.text`*:: -+ --- -type: match_only_text - --- - -*`threat.indicator.url.original`*:: -+ --- -Unmodified original url as seen in the event source. -Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. -This field is meant to represent the URL as it was observed, complete or not. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top or /search?q=elasticsearch - --- - -*`threat.indicator.url.original.text`*:: -+ --- -type: match_only_text - --- - -*`threat.indicator.url.password`*:: -+ --- -Password of the request. - -type: keyword - --- - -*`threat.indicator.url.path`*:: -+ --- -Path of the request, such as "/search". - -type: wildcard - --- - -*`threat.indicator.url.port`*:: -+ --- -Port of the request, such as 443. - -type: long - -example: 443 - -format: string - --- - -*`threat.indicator.url.query`*:: -+ --- -The query field describes the query string of the request, such as "q=elasticsearch". -The `?` is excluded from the query string. If a URL contains no `?`, there is no query field. If there is a `?` but no query, the query field exists with an empty string. The `exists` query can be used to differentiate between the two cases. - -type: keyword - --- - -*`threat.indicator.url.registered_domain`*:: -+ --- -The highest registered url domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`threat.indicator.url.scheme`*:: -+ --- -Scheme of the request, such as "https". -Note: The `:` is not part of the scheme. - -type: keyword - -example: https - --- - -*`threat.indicator.url.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`threat.indicator.url.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`threat.indicator.url.username`*:: -+ --- -Username of the request. - -type: keyword - --- - -*`threat.indicator.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`threat.indicator.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`threat.indicator.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`threat.indicator.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`threat.indicator.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`threat.indicator.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`threat.indicator.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`threat.indicator.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.indicator.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`threat.indicator.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`threat.indicator.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`threat.indicator.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`threat.indicator.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`threat.indicator.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`threat.indicator.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`threat.indicator.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`threat.indicator.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`threat.indicator.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`threat.indicator.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`threat.indicator.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`threat.indicator.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`threat.indicator.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`threat.indicator.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`threat.indicator.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`threat.software.alias`*:: -+ --- -The alias(es) of the software for a set of related intrusion activity that are tracked by a common name in the security community. -While not required, you can use a MITRE ATT&CK® associated software description. - -type: keyword - -example: [ "X-Agent" ] - --- - -*`threat.software.id`*:: -+ --- -The id of the software used by this threat to conduct behavior commonly modeled using MITRE ATT&CK®. -While not required, you can use a MITRE ATT&CK® software id. - -type: keyword - -example: S0552 - --- - -*`threat.software.name`*:: -+ --- -The name of the software used by this threat to conduct behavior commonly modeled using MITRE ATT&CK®. -While not required, you can use a MITRE ATT&CK® software name. - -type: keyword - -example: AdFind - --- - -*`threat.software.platforms`*:: -+ --- -The platforms of the software used by this threat to conduct behavior commonly modeled using MITRE ATT&CK®. -Recommended Values: - * AWS - * Azure - * Azure AD - * GCP - * Linux - * macOS - * Network - * Office 365 - * SaaS - * Windows - -While not required, you can use a MITRE ATT&CK® software platforms. - -type: keyword - -example: [ "Windows" ] - --- - -*`threat.software.reference`*:: -+ --- -The reference URL of the software used by this threat to conduct behavior commonly modeled using MITRE ATT&CK®. -While not required, you can use a MITRE ATT&CK® software reference URL. - -type: keyword - -example: https://attack.mitre.org/software/S0552/ - --- - -*`threat.software.type`*:: -+ --- -The type of software used by this threat to conduct behavior commonly modeled using MITRE ATT&CK®. -Recommended values - * Malware - * Tool - - While not required, you can use a MITRE ATT&CK® software type. - -type: keyword - -example: Tool - --- - -*`threat.tactic.id`*:: -+ --- -The id of tactic used by this threat. You can use a MITRE ATT&CK® tactic, for example. (ex. https://attack.mitre.org/tactics/TA0002/ ) - -type: keyword - -example: TA0002 - --- - -*`threat.tactic.name`*:: -+ --- -Name of the type of tactic used by this threat. You can use a MITRE ATT&CK® tactic, for example. (ex. https://attack.mitre.org/tactics/TA0002/) - -type: keyword - -example: Execution - --- - -*`threat.tactic.reference`*:: -+ --- -The reference url of tactic used by this threat. You can use a MITRE ATT&CK® tactic, for example. (ex. https://attack.mitre.org/tactics/TA0002/ ) - -type: keyword - -example: https://attack.mitre.org/tactics/TA0002/ - --- - -*`threat.technique.id`*:: -+ --- -The id of technique used by this threat. You can use a MITRE ATT&CK® technique, for example. (ex. https://attack.mitre.org/techniques/T1059/) - -type: keyword - -example: T1059 - --- - -*`threat.technique.name`*:: -+ --- -The name of technique used by this threat. You can use a MITRE ATT&CK® technique, for example. (ex. https://attack.mitre.org/techniques/T1059/) - -type: keyword - -example: Command and Scripting Interpreter - --- - -*`threat.technique.name.text`*:: -+ --- -type: match_only_text - --- - -*`threat.technique.reference`*:: -+ --- -The reference url of technique used by this threat. You can use a MITRE ATT&CK® technique, for example. (ex. https://attack.mitre.org/techniques/T1059/) - -type: keyword - -example: https://attack.mitre.org/techniques/T1059/ - --- - -*`threat.technique.subtechnique.id`*:: -+ --- -The full id of subtechnique used by this threat. You can use a MITRE ATT&CK® subtechnique, for example. (ex. https://attack.mitre.org/techniques/T1059/001/) - -type: keyword - -example: T1059.001 - --- - -*`threat.technique.subtechnique.name`*:: -+ --- -The name of subtechnique used by this threat. You can use a MITRE ATT&CK® subtechnique, for example. (ex. https://attack.mitre.org/techniques/T1059/001/) - -type: keyword - -example: PowerShell - --- - -*`threat.technique.subtechnique.name.text`*:: -+ --- -type: match_only_text - --- - -*`threat.technique.subtechnique.reference`*:: -+ --- -The reference url of subtechnique used by this threat. You can use a MITRE ATT&CK® subtechnique, for example. (ex. https://attack.mitre.org/techniques/T1059/001/) - -type: keyword - -example: https://attack.mitre.org/techniques/T1059/001/ - --- - -[float] -=== tls - -Fields related to a TLS connection. These fields focus on the TLS protocol itself and intentionally avoids in-depth analysis of the related x.509 certificate files. - - -*`tls.cipher`*:: -+ --- -String indicating the cipher used during the current connection. - -type: keyword - -example: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - --- - -*`tls.client.certificate`*:: -+ --- -PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. - -type: keyword - -example: MII... - --- - -*`tls.client.certificate_chain`*:: -+ --- -Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. - -type: keyword - -example: ["MII...", "MII..."] - --- - -*`tls.client.hash.md5`*:: -+ --- -Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC - --- - -*`tls.client.hash.sha1`*:: -+ --- -Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 9E393D93138888D288266C2D915214D1D1CCEB2A - --- - -*`tls.client.hash.sha256`*:: -+ --- -Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0 - --- - -*`tls.client.issuer`*:: -+ --- -Distinguished name of subject of the issuer of the x.509 certificate presented by the client. - -type: keyword - -example: CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com - --- - -*`tls.client.ja3`*:: -+ --- -A hash that identifies clients based on how they perform an SSL/TLS handshake. - -type: keyword - -example: d4e5b18d6b55c71272893221c96ba240 - --- - -*`tls.client.not_after`*:: -+ --- -Date/Time indicating when client certificate is no longer considered valid. - -type: date - -example: 2021-01-01T00:00:00.000Z - --- - -*`tls.client.not_before`*:: -+ --- -Date/Time indicating when client certificate is first considered valid. - -type: date - -example: 1970-01-01T00:00:00.000Z - --- - -*`tls.client.server_name`*:: -+ --- -Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. When this value is available, it should get copied to `destination.domain`. - -type: keyword - -example: www.elastic.co - --- - -*`tls.client.subject`*:: -+ --- -Distinguished name of subject of the x.509 certificate presented by the client. - -type: keyword - -example: CN=myclient, OU=Documentation Team, DC=example, DC=com - --- - -*`tls.client.supported_ciphers`*:: -+ --- -Array of ciphers offered by the client during the client hello. - -type: keyword - -example: ["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."] - --- - -*`tls.client.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`tls.client.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`tls.client.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`tls.client.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`tls.client.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`tls.client.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`tls.client.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`tls.client.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`tls.client.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`tls.client.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`tls.client.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`tls.client.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`tls.client.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`tls.client.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`tls.client.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`tls.client.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`tls.client.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`tls.client.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`tls.client.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`tls.client.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`tls.client.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`tls.client.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`tls.client.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`tls.client.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`tls.curve`*:: -+ --- -String indicating the curve used for the given cipher, when applicable. - -type: keyword - -example: secp256r1 - --- - -*`tls.established`*:: -+ --- -Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. - -type: boolean - --- - -*`tls.next_protocol`*:: -+ --- -String indicating the protocol being tunneled. Per the values in the IANA registry (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. - -type: keyword - -example: http/1.1 - --- - -*`tls.resumed`*:: -+ --- -Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. - -type: boolean - --- - -*`tls.server.certificate`*:: -+ --- -PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. - -type: keyword - -example: MII... - --- - -*`tls.server.certificate_chain`*:: -+ --- -Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. - -type: keyword - -example: ["MII...", "MII..."] - --- - -*`tls.server.hash.md5`*:: -+ --- -Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC - --- - -*`tls.server.hash.sha1`*:: -+ --- -Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 9E393D93138888D288266C2D915214D1D1CCEB2A - --- - -*`tls.server.hash.sha256`*:: -+ --- -Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. - -type: keyword - -example: 0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0 - --- - -*`tls.server.issuer`*:: -+ --- -Subject of the issuer of the x.509 certificate presented by the server. - -type: keyword - -example: CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com - --- - -*`tls.server.ja3s`*:: -+ --- -A hash that identifies servers based on how they perform an SSL/TLS handshake. - -type: keyword - -example: 394441ab65754e2207b1e1b457b3641d - --- - -*`tls.server.not_after`*:: -+ --- -Timestamp indicating when server certificate is no longer considered valid. - -type: date - -example: 2021-01-01T00:00:00.000Z - --- - -*`tls.server.not_before`*:: -+ --- -Timestamp indicating when server certificate is first considered valid. - -type: date - -example: 1970-01-01T00:00:00.000Z - --- - -*`tls.server.subject`*:: -+ --- -Subject of the x.509 certificate presented by the server. - -type: keyword - -example: CN=www.example.com, OU=Infrastructure Team, DC=example, DC=com - --- - -*`tls.server.x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`tls.server.x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`tls.server.x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`tls.server.x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`tls.server.x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`tls.server.x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`tls.server.x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`tls.server.x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`tls.server.x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`tls.server.x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`tls.server.x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`tls.server.x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`tls.server.x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`tls.server.x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`tls.server.x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`tls.server.x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`tls.server.x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`tls.server.x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`tls.server.x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`tls.server.x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`tls.server.x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`tls.server.x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`tls.server.x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`tls.server.x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -*`tls.version`*:: -+ --- -Numeric part of the version parsed from the original string. - -type: keyword - -example: 1.2 - --- - -*`tls.version_protocol`*:: -+ --- -Normalized lowercase protocol name parsed from original string. - -type: keyword - -example: tls - --- - -*`span.id`*:: -+ --- -Unique identifier of the span within the scope of its trace. -A span represents an operation within a transaction, such as a request to another service, or a database query. - -type: keyword - -example: 3ff9a8981b7ccd5a - --- - -*`trace.id`*:: -+ --- -Unique identifier of the trace. -A trace groups multiple events like transactions that belong together. For example, a user request handled by multiple inter-connected services. - -type: keyword - -example: 4bf92f3577b34da6a3ce929d0e0e4736 - --- - -*`transaction.id`*:: -+ --- -Unique identifier of the transaction within the scope of its trace. -A transaction is the highest level of work measured within a service, such as a request to a server. - -type: keyword - -example: 00f067aa0ba902b7 - --- - -[float] -=== url - -URL fields provide support for complete or partial URLs, and supports the breaking down into scheme, domain, path, and so on. - - -*`url.domain`*:: -+ --- -Domain of the url, such as "www.elastic.co". -In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the `domain` field. -If the URL contains a literal IPv6 address enclosed by `[` and `]` (IETF RFC 2732), the `[` and `]` characters should also be captured in the `domain` field. - -type: keyword - -example: www.elastic.co - --- - -*`url.extension`*:: -+ --- -The field contains the file extension from the original request url, excluding the leading dot. -The file extension is only set if it exists, as not every url has a file extension. -The leading period must not be included. For example, the value must be "png", not ".png". -Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - -type: keyword - -example: png - --- - -*`url.fragment`*:: -+ --- -Portion of the url after the `#`, such as "top". -The `#` is not part of the fragment. - -type: keyword - --- - -*`url.full`*:: -+ --- -If full URLs are important to your use case, they should be stored in `url.full`, whether this field is reconstructed or present in the event source. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top - --- - -*`url.full.text`*:: -+ --- -type: match_only_text - --- - -*`url.original`*:: -+ --- -Unmodified original url as seen in the event source. -Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. -This field is meant to represent the URL as it was observed, complete or not. - -type: wildcard - -example: https://www.elastic.co:443/search?q=elasticsearch#top or /search?q=elasticsearch - --- - -*`url.original.text`*:: -+ --- -type: match_only_text - --- - -*`url.password`*:: -+ --- -Password of the request. - -type: keyword - --- - -*`url.path`*:: -+ --- -Path of the request, such as "/search". - -type: wildcard - --- - -*`url.port`*:: -+ --- -Port of the request, such as 443. - -type: long - -example: 443 - -format: string - --- - -*`url.query`*:: -+ --- -The query field describes the query string of the request, such as "q=elasticsearch". -The `?` is excluded from the query string. If a URL contains no `?`, there is no query field. If there is a `?` but no query, the query field exists with an empty string. The `exists` query can be used to differentiate between the two cases. - -type: keyword - --- - -*`url.registered_domain`*:: -+ --- -The highest registered url domain, stripped of the subdomain. -For example, the registered domain for "foo.example.com" is "example.com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". - -type: keyword - -example: example.com - --- - -*`url.scheme`*:: -+ --- -Scheme of the request, such as "https". -Note: The `:` is not part of the scheme. - -type: keyword - -example: https - --- - -*`url.subdomain`*:: -+ --- -The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -For example the subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. - -type: keyword - -example: east - --- - -*`url.top_level_domain`*:: -+ --- -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". -This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". - -type: keyword - -example: co.uk - --- - -*`url.username`*:: -+ --- -Username of the request. - -type: keyword - --- - -[float] -=== user - -The user fields describe information about the user that is relevant to the event. -Fields can have one entry or multiple entries. If a user has more than one id, provide an array that includes all of them. - - -*`user.changes.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.changes.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`user.changes.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`user.changes.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`user.changes.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.changes.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`user.changes.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`user.changes.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`user.changes.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`user.changes.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`user.changes.name.text`*:: -+ --- -type: match_only_text - --- - -*`user.changes.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -*`user.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.effective.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.effective.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`user.effective.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`user.effective.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`user.effective.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.effective.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`user.effective.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`user.effective.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`user.effective.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`user.effective.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`user.effective.name.text`*:: -+ --- -type: match_only_text - --- - -*`user.effective.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -*`user.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`user.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`user.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`user.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`user.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`user.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`user.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`user.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`user.name.text`*:: -+ --- -type: match_only_text - --- - -*`user.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -*`user.target.domain`*:: -+ --- -Name of the directory the user is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.target.email`*:: -+ --- -User email address. - -type: keyword - --- - -*`user.target.full_name`*:: -+ --- -User's full name, if available. - -type: keyword - -example: Albert Einstein - --- - -*`user.target.full_name.text`*:: -+ --- -type: match_only_text - --- - -*`user.target.group.domain`*:: -+ --- -Name of the directory the group is a member of. -For example, an LDAP or Active Directory domain name. - -type: keyword - --- - -*`user.target.group.id`*:: -+ --- -Unique identifier for the group on the system/platform. - -type: keyword - --- - -*`user.target.group.name`*:: -+ --- -Name of the group. - -type: keyword - --- - -*`user.target.hash`*:: -+ --- -Unique user hash to correlate information for a user in anonymized form. -Useful if `user.id` or `user.name` contain confidential information and cannot be used. - -type: keyword - --- - -*`user.target.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - -example: S-1-5-21-202424912787-2692429404-2351956786-1000 - --- - -*`user.target.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: a.einstein - --- - -*`user.target.name.text`*:: -+ --- -type: match_only_text - --- - -*`user.target.roles`*:: -+ --- -Array of user roles at the time of the event. - -type: keyword - -example: ["kibana_admin", "reporting_user"] - --- - -[float] -=== user_agent - -The user_agent fields normally come from a browser request. -They often show up in web service logs coming from the parsed user agent string. - - -*`user_agent.device.name`*:: -+ --- -Name of the device. - -type: keyword - -example: iPhone - --- - -*`user_agent.name`*:: -+ --- -Name of the user agent. - -type: keyword - -example: Safari - --- - -*`user_agent.original`*:: -+ --- -Unparsed user_agent string. - -type: keyword - -example: Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1 - --- - -*`user_agent.original.text`*:: -+ --- -type: match_only_text - --- - -*`user_agent.os.family`*:: -+ --- -OS family (such as redhat, debian, freebsd, windows). - -type: keyword - -example: debian - --- - -*`user_agent.os.full`*:: -+ --- -Operating system name, including the version or code name. - -type: keyword - -example: Mac OS Mojave - --- - -*`user_agent.os.full.text`*:: -+ --- -type: match_only_text - --- - -*`user_agent.os.kernel`*:: -+ --- -Operating system kernel version as a raw string. - -type: keyword - -example: 4.4.0-112-generic - --- - -*`user_agent.os.name`*:: -+ --- -Operating system name, without the version. - -type: keyword - -example: Mac OS X - --- - -*`user_agent.os.name.text`*:: -+ --- -type: match_only_text - --- - -*`user_agent.os.platform`*:: -+ --- -Operating system platform (such centos, ubuntu, windows). - -type: keyword - -example: darwin - --- - -*`user_agent.os.type`*:: -+ --- -Use the `os.type` field to categorize the operating system into one of the broad commercial families. -One of these following values should be used (lowercase): linux, macos, unix, windows. -If the OS you're dealing with is not in the list, the field should not be populated. Please let us know by opening an issue with ECS, to propose its addition. - -type: keyword - -example: macos - --- - -*`user_agent.os.version`*:: -+ --- -Operating system version as a raw string. - -type: keyword - -example: 10.14.1 - --- - -*`user_agent.version`*:: -+ --- -Version of the user agent. - -type: keyword - -example: 12.0 - --- - -[float] -=== vlan - -The VLAN fields are used to identify 802.1q tag(s) of a packet, as well as ingress and egress VLAN associations of an observer in relation to a specific packet or connection. -Network.vlan fields are used to record a single VLAN tag, or the outer tag in the case of q-in-q encapsulations, for a packet or connection as observed, typically provided by a network sensor (e.g. Zeek, Wireshark) passively reporting on traffic. -Network.inner VLAN fields are used to report inner q-in-q 802.1q tags (multiple 802.1q encapsulations) as observed, typically provided by a network sensor (e.g. Zeek, Wireshark) passively reporting on traffic. Network.inner VLAN fields should only be used in addition to network.vlan fields to indicate q-in-q tagging. -Observer.ingress and observer.egress VLAN values are used to record observer specific information when observer events contain discrete ingress and egress VLAN information, typically provided by firewalls, routers, or load balancers. - - -*`vlan.id`*:: -+ --- -VLAN ID as reported by the observer. - -type: keyword - -example: 10 - --- - -*`vlan.name`*:: -+ --- -Optional VLAN name as reported by the observer. - -type: keyword - -example: outside - --- - -[float] -=== vulnerability - -The vulnerability fields describe information about a vulnerability that is relevant to an event. - - -*`vulnerability.category`*:: -+ --- -The type of system or architecture that the vulnerability affects. These may be platform-specific (for example, Debian or SUSE) or general (for example, Database or Firewall). For example (https://qualysguard.qualys.com/qwebhelp/fo_portal/knowledgebase/vulnerability_categories.htm[Qualys vulnerability categories]) -This field must be an array. - -type: keyword - -example: ["Firewall"] - --- - -*`vulnerability.classification`*:: -+ --- -The classification of the vulnerability scoring system. For example (https://www.first.org/cvss/) - -type: keyword - -example: CVSS - --- - -*`vulnerability.description`*:: -+ --- -The description of the vulnerability that provides additional context of the vulnerability. For example (https://cve.mitre.org/about/faqs.html#cve_entry_descriptions_created[Common Vulnerabilities and Exposure CVE description]) - -type: keyword - -example: In macOS before 2.12.6, there is a vulnerability in the RPC... - --- - -*`vulnerability.description.text`*:: -+ --- -type: match_only_text - --- - -*`vulnerability.enumeration`*:: -+ --- -The type of identifier used for this vulnerability. For example (https://cve.mitre.org/about/) - -type: keyword - -example: CVE - --- - -*`vulnerability.id`*:: -+ --- -The identification (ID) is the number portion of a vulnerability entry. It includes a unique identification number for the vulnerability. For example (https://cve.mitre.org/about/faqs.html#what_is_cve_id)[Common Vulnerabilities and Exposure CVE ID] - -type: keyword - -example: CVE-2019-00001 - --- - -*`vulnerability.reference`*:: -+ --- -A resource that provides additional information, context, and mitigations for the identified vulnerability. - -type: keyword - -example: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6111 - --- - -*`vulnerability.report_id`*:: -+ --- -The report or scan identification number. - -type: keyword - -example: 20191018.0001 - --- - -*`vulnerability.scanner.vendor`*:: -+ --- -The name of the vulnerability scanner vendor. - -type: keyword - -example: Tenable - --- - -*`vulnerability.score.base`*:: -+ --- -Scores can range from 0.0 to 10.0, with 10.0 being the most severe. -Base scores cover an assessment for exploitability metrics (attack vector, complexity, privileges, and user interaction), impact metrics (confidentiality, integrity, and availability), and scope. For example (https://www.first.org/cvss/specification-document) - -type: float - -example: 5.5 - --- - -*`vulnerability.score.environmental`*:: -+ --- -Scores can range from 0.0 to 10.0, with 10.0 being the most severe. -Environmental scores cover an assessment for any modified Base metrics, confidentiality, integrity, and availability requirements. For example (https://www.first.org/cvss/specification-document) - -type: float - -example: 5.5 - --- - -*`vulnerability.score.temporal`*:: -+ --- -Scores can range from 0.0 to 10.0, with 10.0 being the most severe. -Temporal scores cover an assessment for code maturity, remediation level, and confidence. For example (https://www.first.org/cvss/specification-document) - -type: float - --- - -*`vulnerability.score.version`*:: -+ --- -The National Vulnerability Database (NVD) provides qualitative severity rankings of "Low", "Medium", and "High" for CVSS v2.0 base score ranges in addition to the severity ratings for CVSS v3.0 as they are defined in the CVSS v3.0 specification. -CVSS is owned and managed by FIRST.Org, Inc. (FIRST), a US-based non-profit organization, whose mission is to help computer security incident response teams across the world. For example (https://nvd.nist.gov/vuln-metrics/cvss) - -type: keyword - -example: 2.0 - --- - -*`vulnerability.severity`*:: -+ --- -The severity of the vulnerability can help with metrics and internal prioritization regarding remediation. For example (https://nvd.nist.gov/vuln-metrics/cvss) - -type: keyword - -example: Critical - --- - -[float] -=== x509 - -This implements the common core fields for x509 certificates. This information is likely logged with TLS sessions, digital signatures found in executable binaries, S/MIME information in email bodies, or analysis of files on disk. -When the certificate relates to a file, use the fields at `file.x509`. When hashes of the DER-encoded certificate are available, the `hash` data set should be populated as well (e.g. `file.hash.sha256`). -Events that contain certificate information about network connections, should use the x509 fields under the relevant TLS fields: `tls.server.x509` and/or `tls.client.x509`. - - -*`x509.alternative_names`*:: -+ --- -List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses. - -type: keyword - -example: *.elastic.co - --- - -*`x509.issuer.common_name`*:: -+ --- -List of common name (CN) of issuing certificate authority. - -type: keyword - -example: Example SHA2 High Assurance Server CA - --- - -*`x509.issuer.country`*:: -+ --- -List of country (C) codes - -type: keyword - -example: US - --- - -*`x509.issuer.distinguished_name`*:: -+ --- -Distinguished name (DN) of issuing certificate authority. - -type: keyword - -example: C=US, O=Example Inc, OU=www.example.com, CN=Example SHA2 High Assurance Server CA - --- - -*`x509.issuer.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: Mountain View - --- - -*`x509.issuer.organization`*:: -+ --- -List of organizations (O) of issuing certificate authority. - -type: keyword - -example: Example Inc - --- - -*`x509.issuer.organizational_unit`*:: -+ --- -List of organizational units (OU) of issuing certificate authority. - -type: keyword - -example: www.example.com - --- - -*`x509.issuer.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`x509.not_after`*:: -+ --- -Time at which the certificate is no longer considered valid. - -type: date - -example: 2020-07-16 03:15:39+00:00 - --- - -*`x509.not_before`*:: -+ --- -Time at which the certificate is first considered valid. - -type: date - -example: 2019-08-16 01:40:25+00:00 - --- - -*`x509.public_key_algorithm`*:: -+ --- -Algorithm used to generate the public key. - -type: keyword - -example: RSA - --- - -*`x509.public_key_curve`*:: -+ --- -The curve used by the elliptic curve public key algorithm. This is algorithm specific. - -type: keyword - -example: nistp521 - --- - -*`x509.public_key_exponent`*:: -+ --- -Exponent used to derive the public key. This is algorithm specific. - -type: long - -example: 65537 - -Field is not indexed. - --- - -*`x509.public_key_size`*:: -+ --- -The size of the public key space in bits. - -type: long - -example: 2048 - --- - -*`x509.serial_number`*:: -+ --- -Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. - -type: keyword - -example: 55FBB9C7DEBF09809D12CCAA - --- - -*`x509.signature_algorithm`*:: -+ --- -Identifier for certificate signature algorithm. We recommend using names found in Go Lang Crypto library. See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353. - -type: keyword - -example: SHA256-RSA - --- - -*`x509.subject.common_name`*:: -+ --- -List of common names (CN) of subject. - -type: keyword - -example: shared.global.example.net - --- - -*`x509.subject.country`*:: -+ --- -List of country (C) code - -type: keyword - -example: US - --- - -*`x509.subject.distinguished_name`*:: -+ --- -Distinguished name (DN) of the certificate subject entity. - -type: keyword - -example: C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net - --- - -*`x509.subject.locality`*:: -+ --- -List of locality names (L) - -type: keyword - -example: San Francisco - --- - -*`x509.subject.organization`*:: -+ --- -List of organizations (O) of subject. - -type: keyword - -example: Example, Inc. - --- - -*`x509.subject.organizational_unit`*:: -+ --- -List of organizational units (OU) of subject. - -type: keyword - --- - -*`x509.subject.state_or_province`*:: -+ --- -List of state or province names (ST, S, or P) - -type: keyword - -example: California - --- - -*`x509.version_number`*:: -+ --- -Version of x509 format. - -type: keyword - -example: 3 - --- - -[[exported-fields-host-processor]] -== Host fields - -Info collected for the host machine. - - - - -*`host.containerized`*:: -+ --- -If the host is a container. - - -type: boolean - --- - -*`host.os.build`*:: -+ --- -OS build information. - - -type: keyword - -example: 18D109 - --- - -*`host.os.codename`*:: -+ --- -OS codename, if any. - - -type: keyword - -example: stretch - --- - -[[exported-fields-jolokia-autodiscover]] -== Jolokia Discovery autodiscover provider fields - -Metadata from Jolokia Discovery added by the jolokia provider. - - - -*`jolokia.agent.version`*:: -+ --- -Version number of jolokia agent. - - -type: keyword - --- - -*`jolokia.agent.id`*:: -+ --- -Each agent has a unique id which can be either provided during startup of the agent in form of a configuration parameter or being autodetected. If autodected, the id has several parts: The IP, the process id, hashcode of the agent and its type. - - -type: keyword - --- - -*`jolokia.server.product`*:: -+ --- -The container product if detected. - - -type: keyword - --- - -*`jolokia.server.version`*:: -+ --- -The container's version (if detected). - - -type: keyword - --- - -*`jolokia.server.vendor`*:: -+ --- -The vendor of the container the agent is running in. - - -type: keyword - --- - -*`jolokia.url`*:: -+ --- -The URL how this agent can be contacted. - - -type: keyword - --- - -*`jolokia.secured`*:: -+ --- -Whether the agent was configured for authentication or not. - - -type: boolean - --- - -[[exported-fields-kubernetes-processor]] -== Kubernetes fields - -Kubernetes metadata added by the kubernetes processor - - - - -*`kubernetes.pod.name`*:: -+ --- -Kubernetes pod name - - -type: keyword - --- - -*`kubernetes.pod.uid`*:: -+ --- -Kubernetes Pod UID - - -type: keyword - --- - -*`kubernetes.pod.ip`*:: -+ --- -Kubernetes Pod IP - - -type: ip - --- - -*`kubernetes.namespace`*:: -+ --- -Kubernetes namespace - - -type: keyword - --- - -*`kubernetes.node.name`*:: -+ --- -Kubernetes node name - - -type: keyword - --- - -*`kubernetes.node.hostname`*:: -+ --- -Kubernetes hostname as reported by the node’s kernel - - -type: keyword - --- - -*`kubernetes.labels.*`*:: -+ --- -Kubernetes labels map - - -type: object - --- - -*`kubernetes.annotations.*`*:: -+ --- -Kubernetes annotations map - - -type: object - --- - -*`kubernetes.selectors.*`*:: -+ --- -Kubernetes selectors map - - -type: object - --- - -*`kubernetes.replicaset.name`*:: -+ --- -Kubernetes replicaset name - - -type: keyword - --- - -*`kubernetes.deployment.name`*:: -+ --- -Kubernetes deployment name - - -type: keyword - --- - -*`kubernetes.statefulset.name`*:: -+ --- -Kubernetes statefulset name - - -type: keyword - --- - -*`kubernetes.container.name`*:: -+ --- -Kubernetes container name (different than the name from the runtime) - - -type: keyword - --- - -[[exported-fields-process]] -== Process fields - -Process metadata fields - - - - -*`process.exe`*:: -+ --- -type: alias - -alias to: process.executable - --- - -[float] -=== owner - -Process owner information. - - -*`process.owner.id`*:: -+ --- -Unique identifier of the user. - -type: keyword - --- - -*`process.owner.name`*:: -+ --- -Short name or login of the user. - -type: keyword - -example: albert - --- - -*`process.owner.name.text`*:: -+ --- -type: text - --- - diff --git a/journalbeat/docs/filtering.asciidoc b/journalbeat/docs/filtering.asciidoc deleted file mode 100644 index 5bfcdd532546..000000000000 --- a/journalbeat/docs/filtering.asciidoc +++ /dev/null @@ -1,36 +0,0 @@ -[[filtering-and-enhancing-data]] -== Filter and enhance data with processors - -++++ -Processors -++++ - -Your use case might require only a subset of the data exported by {beatname_uc}, -or you might need to enhance the exported data (for example, by adding -metadata). {beatname_uc} provides a couple of options for filtering and -enhancing exported data. - -You can configure {beatname_uc} to include events that match specific filtering -criteria. To do this, use the <> -option. The advantage of this approach is that you can reduce the number of -fields that {beatname_uc} needs to process. - -Another approach (the one described here) is to define processors to configure -global processing across all data exported by {beatname_uc}. - - -[float] -[[using-processors]] -=== Processors - -include::{libbeat-dir}/processors.asciidoc[] - -// You must set the processor-scope attribute to resolve the attribute reference -// defined in processors-using.asciidoc. The attribute is used to indicate where -// processors are valid. If processors are valid in more than two locations -// (root and :processor-scope:), you need to add a conditionally coded section -// to processors-using.asciidoc. - -:processor-scope: input -include::{libbeat-dir}/processors-using.asciidoc[] -:processor-scope!: diff --git a/journalbeat/docs/general-options.asciidoc b/journalbeat/docs/general-options.asciidoc deleted file mode 100644 index 32c39676bfe7..000000000000 --- a/journalbeat/docs/general-options.asciidoc +++ /dev/null @@ -1,64 +0,0 @@ -[[configuration-general-options]] -== Configure general settings - -++++ -General settings -++++ - -You can specify settings in the +{beatname_lc}.yml+ config file to control the -general behavior of {beatname_uc}. This includes: - -* <> that control things like -publisher behavior and the location of some files. - -* <> that are supported by all Elastic -Beats. - -[float] -[[configuration-global-options]] -=== Global {beatname_uc} configuration options - -These options are in the +{beatname_lc}+ namespace. - -[float] -[id="{beatname_lc}-registry-file"] -==== `registry_file` - -The name of the registry file. If a relative path is used, it is considered relative to the -data path. See the <> section for details. The default is `${path.data}/registry`. - -["source","sh",subs="attributes"] ----- -{beatname_lc}.registry_file: registry ----- - -[float] -==== `backoff` deprecated:[5.6.1,Use the option under `paths` instead.] - -This option is valid as a global setting under the +{beatname_lc}+ namespace -or under `paths`. For a description of this option, see -<<{beatname_lc}-backoff,`backoff`>>. - -[float] -==== `max_backoff` deprecated:[5.6.1,Use the option under `paths` instead.] - -This option is valid as a global setting under the +{beatname_lc}+ namespace -or under `paths`. For a description of this option, see -<<{beatname_lc}-max-backoff,`max_backoff`>>. - -[float] -==== `seek` deprecated:[5.6.1,Use the option under `paths` instead.] - -This option is valid as a global setting under the +{beatname_lc}+ namespace -or under `paths`. For a description of this option, see -<>. - -[float] -==== `include_matches` deprecated:[5.6.1,Use the option under `paths` instead.] - -This option is valid as a global setting under the +{beatname_lc}+ namespace -or under `paths`. For a description of this option, see -<>. - -include::{libbeat-dir}/generalconfig.asciidoc[] - diff --git a/journalbeat/docs/getting-started.asciidoc b/journalbeat/docs/getting-started.asciidoc deleted file mode 100644 index 75da26ee1414..000000000000 --- a/journalbeat/docs/getting-started.asciidoc +++ /dev/null @@ -1,175 +0,0 @@ -[id="{beatname_lc}-installation-configuration"] -== {beatname_uc} quick start: installation and configuration - -++++ -Quick start: installation and configuration -++++ - -This guide describes how to get started quickly with log data collection from -systemd journals. You'll learn how to: - -* install {beatname_uc} on each system you want to monitor -* specify the location of your log files -* parse log data into fields and send it to {es} -* visualize the log data in {kib} - -[float] -=== Before you begin - -You need {es} for storing and searching your data, and {kib} for visualizing and -managing it. - -include::{libbeat-dir}/tab-widgets/spinup-stack-widget.asciidoc[] - -[float] -[[install]] -=== Step 1: Install {beatname_uc} - -Install {beatname_uc} on all the servers you want to monitor. - -To download and install {beatname_uc}, use the commands that work with your -system: - -include::{libbeat-dir}/tab-widgets/install-deb-rpm-linux-widget.asciidoc[] - -[float] -[[other-installation-options]] -==== Other installation options - -* <> -* https://www.elastic.co/downloads/beats/{beatname_lc}[Download page] -* <> - -[float] -[[set-connection]] -=== Step 2: Connect to the {stack} - -include::{libbeat-dir}/shared/connecting-to-es.asciidoc[] - - -[float] -[[configuration]] -=== Step 3: Configure {beatname_uc} - -Before running {beatname_uc}, specify the location of the systemd journal files -and configure how you want the files to be read. If you accept the default -configuration, {beatname_uc} reads from the local journal. - -. In +{beatname_lc}.yml+, specify a list of paths to your systemd journal files. -Each path can be a directory path (to collect events from all journals in a -directory), or a file path. For example: -+ -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: - - "/dev/log" - - "/var/log/messages/my-journal-file.journal" - seek: head ----- -+ -If no paths are specified, {beatname_uc} reads from the default journal. - -. Set the <> option to control the position where -{beatname_uc} starts reading the journal. The available options are `head`, -`tail`, and `cursor`. The default is `cursor`, which means that on first read, -{beatname_uc} starts reading at the beginning of the file, but continues reading -at the last known position after a reload or restart. For more detail about -the settings, see the reference docs for the -<>. - -. (Optional) Set the <> option -to filter entries in journald before collecting any log events. This reduces the -number of events that {beatname_uc} needs to process. For example, to fetch only -Redis events from a Docker container tagged as `redis`, use: -+ -["source","sh",subs="attributes"] ----- -{beatname_lc}.inputs: -- paths: [] - include_matches: - - "CONTAINER_TAG=redis" - - "_COMM=redis" ----- - -include::{libbeat-dir}/shared/config-check.asciidoc[] - -[float] -[[setup-assets]] -=== Step 4: Set up assets - -{beatname_uc} comes with predefined assets for parsing, indexing, and -visualizing your data. To load these assets: - -. Make sure the user specified in +{beatname_lc}.yml+ is -<>. - -. From the installation directory, run: -+ --- -include::{libbeat-dir}/tab-widgets/setup-deb-rpm-linux-widget.asciidoc[] --- -+ -`-e` is optional and sends output to standard error instead of the configured log output. - -This step loads the recommended {ref}/index-templates.html[index template] for writing to {es}. - -[TIP] -===== -A connection to {es} (or {ess}) is required to set up the initial -environment. If you're using a different output, such as {ls}, see -<>. -===== - -[float] -[[start]] -=== Step 5: Start {beatname_uc} - -Before starting {beatname_uc}, modify the user credentials in -+{beatname_lc}.yml+ and specify a user who is -<>. - -To start {beatname_uc}, run: - -// tag::start-step[] -include::{libbeat-dir}/tab-widgets/start-deb-rpm-linux-widget.asciidoc[] -// end::start-step[] - -{beatname_uc} is now ready to send journal events to the {es}. - -[float] -[[view-data]] -=== Step 6: View your data in {kib} - -There is currently no dashboard available for {beatname_uc}. To start exploring -your data, go to the Discover app in {kib}. From there, you can submit search -queries, filter the search results, and view document data. - -To learn how to build visualizations and dashboards to view your data, see the -_{kibana-ref}/index.html[{kib} User Guide]_. - - -[float] -=== What's next? - -Now that you have your logs streaming into {es}, learn how to unify your logs, -metrics, uptime, and application performance data. - -include::{libbeat-dir}/shared/obs-apps.asciidoc[] - -[TIP] -==== -The {logs-app} shows logs from `filebeat-*` indices by default. To show -{beatname_uc} indices, configure the source to include `journalbeat-*`. You can -do this in the {logs-app} when you configure the source, or you can modify the {kib} -configuration. For -example: - -[source,yaml] ----- -xpack.infra: - sources: - default: - logAlias: "filebeat-*,journalbeat-*" ----- -==== diff --git a/journalbeat/docs/howto/howto.asciidoc b/journalbeat/docs/howto/howto.asciidoc deleted file mode 100644 index 14a26a59c1af..000000000000 --- a/journalbeat/docs/howto/howto.asciidoc +++ /dev/null @@ -1,35 +0,0 @@ -[[howto-guides]] -= How to guides - -[partintro] --- -Learn how to perform common {beatname_uc} configuration tasks. - -* <<{beatname_lc}-template>> -* <> -* <<{beatname_lc}-geoip>> -* <> -* <> -* <> - - --- - -include::{libbeat-dir}/howto/load-index-templates.asciidoc[] - -include::{libbeat-dir}/howto/change-index-name.asciidoc[] - -include::{libbeat-dir}/shared-geoip.asciidoc[] - -:standalone: -include::{libbeat-dir}/shared-env-vars.asciidoc[] -:standalone!: - -include::{libbeat-dir}/shared-config-ingest.asciidoc[] - -:standalone: -include::{libbeat-dir}/yaml.asciidoc[] -:standalone!: - - - diff --git a/journalbeat/docs/images/coordinate-map.png b/journalbeat/docs/images/coordinate-map.png deleted file mode 100644 index 8ac69fe747cfda15ef0eddcf617e18914409b970..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370029 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

VC(~Wk}*sj{oYoO>%PA;~k!E#ln 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�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�Y)=cFN$-E4 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͜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 mfguYFSzyQlLly{F;Qs+MHH%8#Dv;>_0000( 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

-^jh4b!|u; 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 diff --git a/journalbeat/docs/index.asciidoc b/journalbeat/docs/index.asciidoc deleted file mode 100644 index 4ace63c41fcd..000000000000 --- a/journalbeat/docs/index.asciidoc +++ /dev/null @@ -1,47 +0,0 @@ -= Journalbeat Reference - -:libbeat-dir: {docdir}/../../libbeat/docs - -include::{libbeat-dir}/version.asciidoc[] - -include::{asciidoc-dir}/../../shared/versions/stack/{source_branch}.asciidoc[] - -include::{asciidoc-dir}/../../shared/attributes.asciidoc[] - -:beatname_lc: journalbeat -:beatname_uc: Journalbeat -:beatname_pkg: {beatname_lc} -:github_repo_name: beats -:discuss_forum: beats/{beatname_lc} -:beat_default_index_prefix: {beatname_lc} -:beat_kib_app: {kib} Logs -:deb_os: -:rpm_os: -:linux_os: -:docker_platform: -:no_dashboards: -:no_decode_cef_processor: - -include::{libbeat-dir}/shared-beats-attributes.asciidoc[] - -include::./overview.asciidoc[] - -include::./getting-started.asciidoc[] - -include::./setting-up-running.asciidoc[] - -include::./configuring-howto.asciidoc[] - -include::{docdir}/howto/howto.asciidoc[] - -include::./fields.asciidoc[] - -include::{libbeat-dir}/monitoring/monitoring-beats.asciidoc[] - -include::{libbeat-dir}/shared-securing-beat.asciidoc[] - -include::./troubleshooting.asciidoc[] - -include::./faq.asciidoc[] - - diff --git a/journalbeat/docs/overview.asciidoc b/journalbeat/docs/overview.asciidoc deleted file mode 100644 index 645aa87ca48e..000000000000 --- a/journalbeat/docs/overview.asciidoc +++ /dev/null @@ -1,11 +0,0 @@ -[id="{beatname_lc}-overview"] -== {beatname_uc} overview - -{beatname_uc} is a lightweight shipper for forwarding and centralizing log data -from https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html[systemd journals]. -Installed as an agent on your servers, {beatname_uc} monitors the journal -locations that you specify, collects log events, and forwards them to either to -https://www.elastic.co/products/elasticsearch[Elasticsearch] or -https://www.elastic.co/products/logstash[Logstash]. - -include::{libbeat-dir}/shared-libbeat-description.asciidoc[] diff --git a/journalbeat/docs/page_header.html b/journalbeat/docs/page_header.html deleted file mode 100644 index 0f01f3bfad59..000000000000 --- a/journalbeat/docs/page_header.html +++ /dev/null @@ -1,4 +0,0 @@ -This functionality is experimental and may be changed or removed completely in a -future release. Elastic will take a best effort approach to fix any issues, but -experimental features are not subject to the support SLA of official GA -features. \ No newline at end of file diff --git a/journalbeat/docs/running-on-docker.asciidoc b/journalbeat/docs/running-on-docker.asciidoc deleted file mode 100644 index dbfcce5b489d..000000000000 --- a/journalbeat/docs/running-on-docker.asciidoc +++ /dev/null @@ -1 +0,0 @@ -include::{libbeat-dir}/shared-docker.asciidoc[] diff --git a/journalbeat/docs/setting-up-running.asciidoc b/journalbeat/docs/setting-up-running.asciidoc deleted file mode 100644 index ef95d59b8ffe..000000000000 --- a/journalbeat/docs/setting-up-running.asciidoc +++ /dev/null @@ -1,47 +0,0 @@ -///// -// NOTE: -// Each beat has its own setup overview to allow for the addition of content -// that is unique to each beat. -///// - -[[setting-up-and-running]] -== Set up and run {beatname_uc} - -++++ -Set up and run -++++ - -Before reading this section, see -<<{beatname_lc}-installation-configuration>> for basic -installation instructions to get you started. - -This section includes additional information on how to install, set up, and run -{beatname_uc}, including: - -* <> -* <> -* <> -* <> -* <> -* <> -* <<{beatname_lc}-starting>> -* <> - - -//MAINTAINERS: If you add a new file to this section, make sure you update the bulleted list ^^ too. - -include::{libbeat-dir}/shared-directory-layout.asciidoc[] - -include::{libbeat-dir}/keystore.asciidoc[] - -include::{libbeat-dir}/command-reference.asciidoc[] - -include::{libbeat-dir}/repositories.asciidoc[] - -include::./running-on-docker.asciidoc[] - -include::{libbeat-dir}/shared-systemd.asciidoc[] - -include::{libbeat-dir}/shared/start-beat.asciidoc[] - -include::{libbeat-dir}/shared/shutdown.asciidoc[] diff --git a/journalbeat/docs/troubleshooting.asciidoc b/journalbeat/docs/troubleshooting.asciidoc deleted file mode 100644 index b32d1b5fca20..000000000000 --- a/journalbeat/docs/troubleshooting.asciidoc +++ /dev/null @@ -1,31 +0,0 @@ -[[troubleshooting]] -= Troubleshoot - -[partintro] --- - -If you have issues installing or running {beatname_uc}, read the -following tips: - -* <> -* <> -* <> - -//sets block macro for getting-help.asciidoc included in next section - --- - -[[getting-help]] -== Get help - -include::{libbeat-dir}/getting-help.asciidoc[] - -//sets block macro for debugging.asciidoc included in next section - -[id="enable-{beatname_lc}-debugging"] -== Debug - -include::{libbeat-dir}/debugging.asciidoc[] - - - diff --git a/journalbeat/include/fields.go b/journalbeat/include/fields.go deleted file mode 100644 index 0e063a35e4e7..000000000000 --- a/journalbeat/include/fields.go +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. - -package include - -import ( - "github.com/elastic/beats/v7/libbeat/asset" -) - -func init() { - if err := asset.SetFields("journalbeat", "fields.yml", asset.BeatFieldsPri, AssetFieldsYml); err != nil { - panic(err) - } -} - -// AssetFieldsYml returns asset data. -// This is the base64 encoded zlib format compressed contents of fields.yml. -func AssetFieldsYml() string { - return "eJzsvft7GzeyKPh7/gqsZr+VlUO2SL0sa+/sXkWSE33Hr7HkyZzE84lgN0hi1AQ6AFo0c/b87/uhCkCjH5IpWXTsjO/N8VBkN1BVKBSqCvX4C/n5+O2r81c//h/kVBIhDWEZN8TMuCYTnjOSccVSky97hBuyoJpMmWCKGpaR8ZKYGSNnJxekUPJfLDW97/5CxlSzjEgB398wpbkU5DAZJIN+xm6S7/5C3uSMakZuuOaGzIwp9NH29pSbWTlOUjnfZjnVhqfbLNXESKLL6ZRpQ9IZFVMGX9mhJ5zlmU6++65PrtnyiLBUf0eI4SZnR/aB7wjJmE4VLwyXAr4iz907xL199B0hfSLonB2Rzf9t+JxpQ+fF5neEEJKzG5YfkVQqBn8r9lvJFcuOiFElfmWWBTsiGTX4Z22+zVNq2LYdkyxmTACp2A0ThkjFp1xYEibfwXuEXFp6cw0PZeE99sEomlpST5ScVyP07MQ8pXm+JIoVimkmDBdTmMiNWE3XuWhaliplYf7zSfQC/kZmVBMhPbQ5CeTpIXvc0LxkAHQAppBFmdtp3LBusglX2sD7DbAUSxm/qaAqeMFyLiq43jqa43qRiVSE5jmOoBNcJ/aBzgu76Js7g+FBf7Df39m9HBweDfaPdveSw/3dXzajZc7pmOW6c4FxNeXYcjJ8gR+v8PtrtlxIlXUs9EmpjZzbB7aRJgXlSgccTqggY0ZKuy2MJDTLyJwZSriYSDWndhD7vcOJXMxkmWewFVMpDOWCCKbt0iE4wL72/x3nOa6BJlQxoo20hKLaQxoAOPMEGmUyvWZqRKjIyOj6UI8cOVqU/O8NWhQ5TwG6jSOyMZGyP6Zqo0c2mLix3xRKZmUKv/9PTOA505pO2R0UnlOTzq6kyJdXhn0wHRR9LhXJ5dTRBFjDDesYwVEGf7JPup97RBaGz/nvgQUty9xwtrDbgwtC4Wn7BVOBQHY6bVSZmtKSMJdTTRbczGRpCBXVDqjB0CPSzJhykoSkuMqpFCk1TESbwEgLxJxQMivnVPQVoxkd54zocj6naklktPniHTkvc8OLPOCuCfvAtd39M7asJpyPuWAZ4cJIIkV4urmmP7E8l+RnqfIsWi1Dp3dthpjp+VRIxa7oWN6wIzIc7Oy1V+4F18bi497TgesNnRJG05nHss5uv8bchCy2s/HPmKvolAnkFCfhj8MXUyXL4ojsdPDR5Yzhm2GV3I5ycpYSOraLjBJxYhZ2I1lZaux5N3FLQcXS0pzaDZnndgv2SMYMfpCKyLFm6sYuD7KrtGw2k3alpCKGXjNN5ozqUrG5fcANGx5rblRNuEjzMmPkB0atSABcNZnTJaG5lkSVwr7t5lU6gcMNEE2+d6i6IfXMyssxq0QzcLaFn/Jce95DIqlSCLtPJBLIwhbhp9yQixlTsSCf0aJglgMtsrBTA6og5C0BhOPGiZRGSGPX3CN7RM5xutQqBXKCSMO+tRuxV8GXWFYgTjEZM2qSaP8ev3kJKoo7ROsIuRWnRbFtUeEpS0jFG7EgziTzpAMJDDoH4RPkFq6JPWqJmSlZTmfkt5KVdny91IbNNcn5NSP/SSfXtEfesowjfxRKpkxrLqZ+UdzjukxnVmC/kFNtqJ4RxINcALkdyXAjApM7Dp/QMjdXsMyRLlJpNNWuGZc8zxIvv9zszZ3etddv3e3NHXb2wTCR2RPcTlUj5cTxA66d53Gn66AYt0qPcAMYGXYnFcuO8WAHUlwIVFHCkHZnFEre8Iz1rM6iC5byCU8Jvg26EddBg3OUjSTQnBnFU8tTQWV9mhwkA/KEzrODva0eyfkYfsavfz2gO7vscHI42R1M9geD4Zju7u2xPba/lx1mz9Lx4U46Hg6epgFEi48hO4OdQX+w0x/sk53do+HgaDgg/zEYDAbk3eXJPwOFays8oblmtWVlxYzNmaL5Fc/qi8rccjzCwvo5CM+sRJxwplBacO32zRM+gQMHTiW91VxibpUYNQfF0OvuNFVS24XQhiorPselISPkEJ6NYPvZjddeoUO6Zwk9qRGiif7j8PQ7wX+zmu398Q6alpVIKMfgvQWodGNGQGrxDgZ06GU19Oy/60DQKawgTuMDoLWCmlB8Ck8/1Dim/IaBxkqFew2fdj/PWF5MytzKTCsBHIZhYLOQ5LmT34QLbahInQbbOH60nRjOIMskTnsilfbECqpAMoSxuSaCsQzNz8WMp7P2VEGQp3JuJ7OWVYT3+cTKD3/QAKp4Avmv5MQwQXI2MYTNC7NsL+VEytoq2oVaxypeLos7ls8fbnYCQvMFXWqijf030NZaAXrmWROX1Rli+K5V3pKKNCIc0YGq1bPI4m6iMaseAY2FT2oLX61YkwFqiz+n6cxag20Sx+N4OjvBvQZS/90dCXViN2A6ABeHSndirVXXVNbSSCHnstTkAjSAj6ivx4LQ6hVUGsiT44st3JhOGXWApVIIBr6Cc2GYEsyQN0oamUp/7j85f7NFlCzhNCwUm/APTJNSZAzPaXv6Kpnbwax0k4rMpWJEMLOQ6prIgilqpLL6rTfv2YzmE/sCJVa9yRmh2ZwLro3dmTdel7ZjZXKOijc1xHksEIn5XIoeSXNGVb6sTkCwaQK0MufpEuyIGQOVwSKYfLJ+JMr5OOi1dx2huQzKW22J3FGB4xCa5zIFHdtB2lo+p3aGr8NGcKvrBnpyfPFqi5QweL6sTiKNNlRYEtwr5zV6RCw53B8ePKshLNWUCv47iM2kfbx8ivoA1upVTOVIBHozn9zpBOhYvkr5aVD+dYQJzNLC/kcpLUe+eHES7cg05w1D8qT65g5L8ti9abee506qHTtyw+3OwI3gF8dtSKcJe+DQQlRsSlUGloM1DKTQveh5tBrGHF2vXAqak0kuF0Sx1BrVNb/F5ckbNyqeUxWYLdjsF/bxCDLYjpqJYC/aZy7+6xUpaHrNzBO9lcAs6OoonEBpTYXuRavo1Sb1hq4CzZtpC4czxTyVjKJCUwAmIRdyzoJxVGo0Mg1Tc7LhfaZSbVRuFcUmXnY5UEQDQY0bzv3snAC4smMWjGBwAkQEcJvRgiWmfpmrKWL40Z3hmMhPYM+yUpeWIG7UyvrmwoL3r1LgAoAxjua192h3DFbRV0jTGtKqWbhefdjH3pUYHJA43rafJ7iMYfOg4kazjGg2p8LwFE4C9sE4HY99QO29hyqVlwM6aHpGkhtu0eW/s8qzYhFlCuw5zU1J3XKcT8hSlirMMaF57pnPnw9Whk6lWvbso15F0YbnOWFCl8rpo85PbdWYjGlj2cOS1BJswvM8iDFaFEoWilPD8uUjWNU0yxTTel2WF+wCdK04nnMTOi0piJ/5mE9LWep8iVwO7wRBurDk0nLOwG9Pcq7BmXn+pmeNaDyNpSLUHjMfiJaWfxJC/quieNAaKx0K94eiCw+T3w+jxH0xQpLVdVFBuIlUzaxE3zIelKOEFyMLyihBsEY9krGCicwZA6jJS1EBAX4et5KVrpX82x3nVCf/tid65OVaGqY/ovZHK44+ofprNUB+sD+goy/cu7md6BgBBWl7gQ73aoAhO6/BIHESHcdPanNOmUxSbpZXa3IenFh9vnN1Xlr7gTk3Yw0cKQwXTJirVGbrgOlyIfs5M4bZYyVj9TvRMPum7ob71fF3H2HUbmTWROBXkVcmTNYGWiozI8dzpnhKO4AshVHLK67lumh+glOQ84vXQPQWhCfHt4K1LtZ0IHWu8gkVNGtTCiT8x70GUyavCsnD8Vq/9JJiyk2ZoSqSUwN/tCDY/G+ykcNtav/pbnIw3DvcHfTIRk7NxhHZ20/2B/vPhofkfzZbQD6uWG84OzVTfa9SRD+hMePJ0yPO2YMKppyQqaKizKniZhnrBkuSWh0FNOpIBzjxR39wpSGHc4XKYsrsoefsikkupXJnZw9cRzNeae3VIYvg5aSYLTW3H/zNXepllI5AeCVNFKkA95IcHSxzOOOnTHps2w6nsdRGin6WttamkNrQfF27bPMNDI9ijWotU17d4eHdtwO5QvTvLiag0nrdVUy4dgkXiWNGroVcCGvjUGJRgYmkIr+cvyERTgRYG1TKG6qWZMEzq8nA8eh2NV7gwMc2/Z7tDfYG9xGzik25FOsUYG9hhrvkV/9vJ7fBtSYJ5mDqFGB/K9mYtfnPave/V7rxox6r1vrmc0Z+B3/gpMZwvXB7eX786jh6rhN4d1BtH6spHMt0+4eSCamvjrmKlLCPMAYvPoJleKCGx/mbYK34cxX1pyfnb272LLefv7k52KrrUXOarmM/vzw+6Qam4bwX0oRb1Dl1iujb5yfk6WBvB+6hMSqOZUfkzBoRMjXMkCdgGHPdI4f9Ma90cKvrbuEVqFONXNDVQpJfy6JgKqWa/ZPM2AeasZTPaU4yPuUG7kCsGmUhhWijMKYDHye2AkSQUmg+dcEobMpUQi7KFO6+b9yDLlYJ724QBhpGnC2LGeuQvoNBfzDo75/Bv7v9nd3aSglqkiZndJ6P3dyxeamo0OhJOX9jsXJ+BQxkfHV8GZx05AlLponzP1upXLkOCXqkvGu6dhkaDp3IL0WMonBhIaYklzQjY5pTkcIZOOGKLWieox9QydIejQ1r1yJdSGXuZ+x600cbxbst4JgadvyvhR7o/7qHFVjD+g2+/SCbb6cOR2tNVjFFb1+PN24NYkERz2fPI22YYtlVl7X5eHqiFUozPp0xbaJJPY1w7h4gUhQs8yDrcuyN1LD+z6tbYdT3ouGcX8rqKxsTKRP3XJLK+YYVXxvxF83ragy+dNfQGTNMzUGrLRRLubb6CqhNFH1hEKsDQaflOOcp0eVkwj+EEeGZJzNjiqPtbXwEn0ikmm4l5FItQSxKVLQ+cKtFopI1XhLN50W+JIZeV+uKvrOcagNiFyMvUacS0hBwAS1YngP2ly9Oq/igjVQm5fVGWzBG1KhxRSD7OrkhTAJMH0yGSWm39m8lzfmEV0uK9+cY1xap8HnuWQX0dcI+pKwwVfgZvFbdUbbYPYF7aUoKqgyPHO6kBQEID45z2f9zv6M2U9k1YICUdk3szCkVlced1PmqF1EgxKO2EBqzXC662bx7T9T3TUzbjcVikTCqTTJfuhGQMXBnUG02ott6BMKNMqO6CicFXEH9CNNU2tyGLsc7iS7Hw9rm69WYuAIPDQrn2vXxW9UYGz3cc0JaAc9zuMxlisuOEBiLwKqaoJHFFaDxGaQem0zsIXXD7KyOURz2T9jli9OtHhpTwZKq6B6IhqKj56/lQAhYlvW8Em2SpC0gm/OGYaMAG7tKwAdft2QEqXibUKxWYjXxCN/X+KbUTCXrZZnYf4c3uFLhvaidHEM35gzuBeTktmORCvLi9PgNBIQixqdhqJhXNtvYsTnl+ZqQe2cxgAm8EZO0AbDSs8NA/opuIiyam7o6BsAJRW8oz+k47zBu8zFThpxxoQ1zjFWjCFwz/mFsB7Ovn+8QybUFpLaDMn18MeLn48bg4m27yKmxynUHeyKca3SpxiuBk7WBmFE9WxcnOEqBtLHzoGNOKWatulaENnViSRAqpFjGqTNon0Ss8k4zF9k5Aix4hve28IfFbhRUgFSKCa4VzWtzUpF1aFUQadjBVGsJ8L0lvhdJ1trdF/1hf7+/M+zvDHb2dvaeDXeeHj7t7xw829nbebY32Ovv7O4Pn+0fPD086A8Hg0EbicdzFn5mOXgxs9YnuushG4OLO0lFE3arDFQyb17SPhrLHytFIY0KWBlm8vcV4JesJ1g1gN78deOaj6mgVxC7uNEjG4qB1i2mV3ZATES6g25VbJksEfAQWua/uD2yDFNSCe7OEGkAQ4HBIiaKhty0Cg30o2EMs3cmQCQzuTXLZkJeVlkOXMfh1lSQs5MdtLjsBp0wk86YhruZaHTCjXaJTRWQdnPX8/FqiVVchzDeOghuXFUKlzGl2FyaEPRLZGk0z1g0UxMyhIkSl9LjEfKsI6pX3b1SPXUQB60GgtwlN7l3+Nhhua5AdQSL8nY9cC5aa06XVp5plk/6Lm0TrVd4yqXiJN+jGISvDFVTZpLvCTGyxtxj5jIPMYvMPuVh2tzUEfW9aPUYu8gqObFEqLGIVJasU2mxcCF5ukcU0wXq1fkyIT/JBbthKiKZZkaTDgTcoA005qU126Vx2ZATuGkL91VKSuNAD4MT57SGU8ALA1lRoeKACDWIx0lNSfOwUI7SmK6Gt2J2gTwD+9kaiNgVsyIy5Og6MsaTeTIGolX09Cmq0icgoVPchStiiGdYs/aiYQSRh+0Wiq4AYWtZK9huoWibozqge4RguRQuBdenGG5We9DNBWweBxPxLOShukN/STI+mTAVu6vh9phD9qVVle1R2zdMUGEIEzdcSTGv39NUsvX454swOc96PlAJ5D95/fZHcp5hpiiE0ZZN/aNtuR4cHDx9+vTw8PDZs2ed5FxnSECboF4FoDmn+g5aBhoGGn0aLdH4alEz47rI6TI2RWI/EpaP6GfsZlV3krPteM7N8qp9m/p4iko0D96Wch/eCCclnq2K4Y0LsEx1ChEXjdjSYErdZ1Sb/rB+O+xza9a39c59TtX5qRfJoEL4A78JKO8Pd3b3rKr8bEDHacYmg26I18jdAeY4+60NdXQNDF+2k7geDaKXXueI8rnuJKPZSeYs42Xd5+8OtG/y9lHk7QpCo0HwbxL5MSWyJ+6fSTCvjvbXI7ofgNMfL9xXB/rLF/+r4+JqdH2Wk8HNFcvcLslSkyNvwjs9cvx7qVj0TUfFhmXfTfJAMnweee0JgVFxq5IApWydCN2idb4kDyaDtVZXyZb55Ch2TwmYMPHIx8Wr6EL3CLX49sg0LarbZqkwDo3mMmVUtF2Oi5WjBx3iGMG5JrRdAOejHh73xM8XuPk8/O0R8eUR4nIuGdeGi2nJ9cw/pxtOOqiCVCkr/toGy2+BpuLZpkfYFDSRs5MdcqPJCzofZ7RHfjx5Q348OSM3lYZzXBTkTEy5CHvo7y/tK/Z7V1qnayfSoiDMvWY/O5B7DlNVih6ZUDWlhvVIDtO39yN+v+qS/buL5H93WfwnE8JxUOLXJ2JD8Nw3AfrVCFDnI//m9PhcTo8Gwb85PR7T6eGJ+2/m9HBo/6mcHk2cvgqnhwP6T+H0cLj8u2vYDTL8uyraFRn+TPr26oh/nRr56vh909m/dJ09BMnJjF1pPhXUlL7UuIuWkxkjF7Vfbg+bu5wxzZpVvWtxphB/NuaCqiWmz4dJ9acXDsz4lGlzRfOpVNzM5uvkuRnVM6hD5icLmq/FCBM1sML07WkfNa4MdMDGFBQbfXBNXPJuSBSCylFhSN85wjI9PKmgMKvLHKn4GWlTgdvmFz2jO/sHq25xLLNbp3ArgHYsZc6o6CLiD/gThEHTAsIoOVasdHSwqLus6HZ0qGWDj8R/Rq4DPrX7fI1lmS1DRIHLq3IC7zCXXEV03+WBzKkoJ9T1QBgvLYV8SfwbJjKpkmhMVlXwVixnNxQTZY8Lyzffv76AgLWujJx5YudkyYcitcfxh+XKtDXUlGsrunacZdyVWmxLETjPmTKYLsgcKN00npS5r10/hfJDalkYOVW0mPGUMKWk0lU4ZDzqDc15FpdTkcoKIW38fOQFozeMlCKqJjjxifnwavWK10Kq8cOwC2s7i3TG0uuuUuhnb9++fnv17tXl23cXl2enV29fv75ceY1K7JiypvIYFzh8zdAJoj1odVVBKp4qaXmYnEhVyFqx6I8rFozO17yP7RSPuZlhPKncbnVlef0Wdg02onjTyjlyvz189ref/vHL4cvD47+vTEvfOWgFamYVq9Yodmq3CBUZqXdUqp/sjV5HUOAazrS2XN8Z7Az7A/vf5XDnaDg42h38srKchz3GVmGOO86lzQsj7SEMSxft8469S9JZPV/473bDY3hx9fpt7/mg9FTOfd3FHpJyxqvjvZbJ68ONK0ljT38pc+3aMLhwcQJiBPUCFFItdrnfCQqS7BPp2n3gY2IcWFX1o/+GKcwTp1PKhY6SaGasUiCtih97CjtlMa0R/yOCdhXCVFozaLhOxgWFOf7yjuLF4cF6gVpXOrbVjCrqieP6aDggAxQhYt+EVmIYJl9FjkcZEpWiPmN5EeWiQe4FlhUJQ2uX1SGW1viwm/0RgtDXmUZWEYVn9dhRPqfTtZqksb8BJgv5HwiQZUDsOyJFF2iGTtcEWcVxDi46baQKR33Y7p4+6sd2R0e2pk8UZnXNzWrzrnE5KqSrGljhShR5eV0eGBzdqvB0iocC1xUjtE4/7AMXyRe7E6+0UYzOYwlzajfoRfX1R1ptRaP4HW/oNcNKB1xg5WJ/Zgm2cL18qvGJBQdyZtIZi3yH56LrlfrDVYWqkAYdPRo8BdAtzRNcNusR+pSi+FWXbTOReS6hjdycCsHUERn9d4QweMv/p1/7yn7WzDS+hbogBU3Z/4ySICQ5tAhzCXRRSzk4iENS7YxCP0jlT2HlVH9CtS8nUdGRgSYRYaIT8lKqRtlzxypYGmIiS+HSi7gOrTmh7AjeZiWp3B7ncrpNRZ8LE5q29Y3smxnrh0svamgfZ+3jKvVxlX61bzsYC6nNP8MaHwtyhm9rRlU6q61BKoXmkNVUb04xpuk1NvjKeMo0qjXBE1VnFSiDONe1uhuN913RSHJaMmQO3EU3VsmWotceV2O6G9T/QAaxQ7EPnjUV00ZxX4q+lmrfyftMu+To0AJu9H7UI6Nt+8/39p//1/6zYf/5X/af/8f+8//Zf8iIPAG2qthky0M86o3AAzv6yyjx7Vc1wy1TJzqU1GcixZqRtLKKb2GGackzts2Eb9qKw2yHYbbTUikmzLajcD9VjBrWByolMzPP/9L4hRa8X1Az6xdU0bn+NSbhPx9BF3CbcgVJbJnOUGGu7jhoNipXiN1DUQczM0NJRw2ZQwtAzYRm3r5zNtv7oE++j/QoL7yS96LVEnAkplx8SCiU1bPrXig5Z2bGSviLiQzq1I7ikZlJkflqnAugQbDAgoOKZrAdF3yfYTPgmVVyHcWIZiYedcFCjwYUu+83wPTi6fuNUJzBvwtPJGSEOdju25EzN+JRYcbgZ8SBqSajDrk6St6LH9hSgiXTYOR4yI4jI1XcMMWpRdJq/vZ4xYzXUYAN555RHW2DeNiYMY/eC0K+Jy997qvng1F/hL+8klD3DVVnQYaDQSTNN5rnc7zGq1pO4Vh5LM4+xnR6Xxs4jJ+A3gkfgyXh2kBQkICwL7mYxsRyJ1HyXry0qr0dWROaK0azpY+jYa4isBfG2DqNLr2xitxU2zJdeoCQC3+B4sYYM21IYYnNU4a1bh05E2LBiYdEyKAAkTft4tK54LkbubdHiesXFlohW6MK2lBCW4t4XHvSQLeD8O7tzFs/Q+q8Go/p2HYUliZmWtBmKvl9B7fGQ34i41ZtXFd2pawWZLAKx24eCyJvmLIkBNm7LFhNEDl+ietS4+mUL5F1WRbfz27kcqo3gPk2sEGk3kjIz4ywDwVLsT2KPfhplpENo+x+2Agjw1t6KcyM2XXdqBrHUEUmpSlVx8W2nXA1h0DU8KSmsDe+vkNhjx6tFE70ljQVROYbdddbHAXosT/MNtbgTOomP/geq1Y1WLGh1j2n54p3Wg3Fm3kQwuZ6oCBH2gWNmtbSzg5CfmE7cIt68nysGw+ew5PQK564G49b+s1EE4CamkGJP9QuNbQzjzvtYVMVN+rYd6oB55GoY6xvm9CToU5Mv13ihkq1tu7Aq2Fs73d2lz/1wsgAb9zzF2qqwAEpup/zVAhYYnXxQOmvqu1OrZvQSr13wrZ3ve0fqfdOGBZ68OBO/NZ751vvnX+v3jvxdvTFmEEy/nENeOID5lsXHvOtC8+3LjzfuvB868LzrQtPQPRbF55vXXi+deG5swtPrNd9Ga14Ioi+9eP5Avrx8AIcxxGffKQJDat1nykUv7GC9/TlL1td/Weq0pRfVAse6PkSRdY4TCHepqKNkXaxLCVOGeQ+PD6G62iqcw9j7vN11qnte/IFtdfJWnbmtx4733rsfOux863HzrceO9967HzrsfOtx86jAfGtx863Hjvfeux867HzrcfOtx47HXB+IT12shzPXR/v9OIF/Hl3YsIqlQLA5Z7zsaKKM02ypaBzdKJ4gkqaoSdN+sRMuNlwP0NYoyyYck0/QEZqjKe20mFDzyg0zK3Ns4FKYZU8DwaNNwTGPjzfWQDM4HjaxVoGW8qnJhx5aL4np4hAP+fi2s23JE9GSZbnoy2SyvkcUgvAQSQF+ZmLTC509f4FgvsaM26fjBItu957J/iHPiizLdxbsNTAWOZ83DXgnKavLz49WKheZiL5Vq/h89VraJD+Kyrf0ID8WzWH9VVzaJL6W3GHL764Q3PJ/jy1HhqYfSv98HilH5qk/bNVgmji960wxJoKQzQI/a1OxC10stpnMs/21yS9Xp7u4xT3gkfP6HBNAF38dDx8GESVSrsGmHb2Dx4G1b679l4LVPvDnYdApTPGVpHYD4Lq4vTs7M39oFqTylHz7zpbtXkA45GS50syp4XuqiAAxhkUeNTX7c18zZRg+e5O4h0ZK6BbULMuR+bzMs8RYjtJC/cG8CdH752f4P0F2Pi7O+8fhBBLIEfPsDSUelxDOY4370g8je946n3aFu0Wih8O9u6BhT04qViuCQFMRoG4U5imxWY9n+eaEWrgKZ6zPtTMeVT9uGBJBNi6sW2EPz8A2Tc0jhH/OHJ2+KsbpvRnwM5N80DMDpLd5NnBYJAMn+4N9++BIp8X67wPOcZbkFCLqJDKuB4Hb85wp5FjQRwUpN+HQBF4jERwEfuLu0L3ds6EiylTheLClXOF3K0bJgidGKaIYkgxl8fo+x9YfbEPeFZ6mqJCB/NfY6kBmUKFiqznUt0WGGUBGa1YY8QoWlXBsNBjinBdx1MCH6amViljwhVjSxAUWDfFzBSjpq+YK5SxMxjubQ+G20ZhJZL+nObWaOsjcfrOmQiVMjoCMdODw8Fuusee7ewM7YcspfvPDnYpzXYPsmxyDwZxHavzK9gMa7y6CzvhU6TZxZvj81eXydk/zu6BorOD142Xm+ZT8NsI4vr9h+Mz75yHz6+Dmx2P4I27CRDuTQQadP7e5NUF/HnHvclzvDFxCR92wtNXF+S3ksEGhDo7Qi+YqjaC/d21Q3fWIuOwF0OQM7htxTRnYawlKRSXcEMyZQbwcsO6QZ+MMqGhuNIRPD/aInh+L/0k8egQTuAT0vEe1N34mJCki9OGHHeNsS+0FlfmYECbdsHQiYJrF7I4YJw2lPjqaOsxMp5rlFi5SFqrKAKFu7sokZ4K9waG/NB05uYimmEmvGKmVCK6pva3Cc1S4pczRiBm4ZotHb2qZGO/MEh/zdys9Vzq8ZKcnVxU7ui3LJUqc2OBjAbJGntu5xU6+KOfXJCFfevs5MIN38w9smtseQ/LQUDgMYTUM/ilXvjAPud5nBwbMueCz8t5z30ZxvVIQSmoiN+wlszIAgep+C00uK4iXnrWoAhDQihhCgcqB8+cxYhqUkit+RijSDIoPGH1wqjMhy+7JiM2bgFKNUlLbaQvi9bM5nY4pzldW7o9FtOnmHoRFsRXrKtqkPkGAnDMq7b37vxVJ+h2tHXpOr7SXSwaMfbUB7LXNwejsOekz6DDVwsmMu0jaqBSCUgrT5J4QI976/gfDhL/XycV1pmxeFmPqLQcF3V/aIBOCqYgdjeizTm4wcANKSfk5NXxyzMCtXpc3TSZ31itLBJOm5saa92MIhFjouILUjCUGhCKowtpSRyuY6JBYF8m5DzIKiGNj5psjun0IjL6rWQ6ZPqP7LHDosoW0bJACPEtUeN+aYxZJX7wttSKkBMGWS83cK9lRTcgDBToXAXv7qXpLJbsbAKCqVYlguuUqoxlCfmFKemr4szBXTpzcR8oQysCjiuq4RQd+fndjLrGTkOXs6rL0ANlDPBmDe4ZoxlTV5OcTtd3aekDbnaIy6q3YhJnJjBzraFHwVJTK190RI6Pe+TypEfenvbI2+MeOT7tkZPTHjl93eFk/nXj7elGj2y8PfaxOLcVz33UpbE4YZpRfB1GtQttcFpHoeRU0TmyXrjVqQw7SDVgCmuxxANB/caCV2VEUCzoDst6Zzis94GURUfS66Mj78JmpMALLFSgsOyyuwK65gJyfVBvramyhMyZ1nTKkjiAhGsIFXK0cwLM+GtBHAZVY6AMRDTFY95Ko7+9O3v7XzUaBZn42XQF5bRDPCfQHPmoWlAT3es8EeEobIAWn3jBWexKRvqUFiFFH1wcVhWM67w+wdyW3R2oF2QhIMOdg604VUTq2huVEI9zS6kmTKe0sHuKakaGA58TqsmT96enp1uVAv4DTa+JzqmeOUPvt1JCVZYwshsqIZd0rHskpUpxOmXOanBlWHMeVQ2aMJbFI0BVVeXyGN+bHnmv8K33AviPuXvE+52uYZ3/8Ly9b7l6X1KuXuCLz5y0x2tOBYfhXZl2LWHxFeWWLRaLbqJ/SyRDEfgtkex+iWQVA30e88BZSXdrFsfHx/WSSt5UvfqUmgfHLQ9dnpPzN1aRY9BZcRR7NkYNF4P/ceQ9fY53+GTC0zIHB1KpWY+MWUpLHbzSN1RxZpbeNIo5dU6NtiZhVNQ6IWcfDBTRDfBF1RE9oGbGFMNCt0InEXFGlc4K5bC5Cd4sCGeDkrdmxuZQzSQaGvUCfAl+Z1RzCKoPI95wXdKc/86cumI13InsaHm9+etG5DSx9k7157Bp+Hg9+HOYAX6u7io4r15D4GYNujVuis14VwSvvg+SynqOwlYjBcarH1tLWaqomHl0KwDBY1N+w7R9KL5P6MEXcYwZVoMP42ZCh1EmCFvzYmBVKCoAvJff3QHUgGjML4UvDlow5fB/Igv0uuZLO4SWMpwozlbDbbGVkGOREeo8NGHMVn1bu6luv53wfnxrxTlh0OLv4PANzRPT2r3P2cnH7n1eMkP7sZPa9wByXuhP753ZedEeBfAo9lvJFYuH+SRmPju5CLfucLAFumM/CCMTMmKpTtxDI8zj9GBUUhFUJZBFpTbYlhKuuPPcsVbEgT/PmMC1hIVNldSRBucrnPf7zmnqLjQsQBAGnPPpzORRS/vK01NhA+9H+UE5M9iLdqrcDTfN/mVB9XVW0hmb0wb9SS1zq4OlhskgGcQclU9qHPXiOfkJnFIfYazOPKwXXJQfyNkHlpZo+r7g4ho+PMc6S0/OXjzfghZVUD7+k5nvM8Qd+d7mtdgjR2RLre64o8OD/uqhR+OlYVdSra+T9Q9Lw4hmv5XQCkRObgf8BTcmZ+RMZJyuHnBflFdrPL9O3ryrdZa/FfhzYdjKUWtwInAprqLA9IfErzstimUYux6UoFAiyYK6qSumJ+dWXFDjEsDCxuUm7vClfEhBBhcbVnHz1QUn9Bp9qS64BFGRSq8ccck+QETPClhPcmoMq26O6zU6OUaj43AsIyxn85D2iKHny4KtDhe6wxM65muO3/p7PWzLctRxlG31A4Z/QwzIhKaMPDn+4Xzrvmis04mKMrp+wdjcF6vCucbbVeg4hkdBBKSb955gMmHUMq4X+2gl2hwxqwk+laKur916eXhzY/BhiK15wq2mB7g6+FcGWV/RMV8TqB/fW57iqEG8vrgvxdd4/DjuuOsEWhXKzy7U7rnTXKTnY50LONwjnAsujGkVwASLMrYeFDrlY6Zaax1OamtPf0p8lC7HfdRmw5DgRRaMmhkZsXySeIyT70erb+XwUjrjq6SddAjJWt+HuhY24339W+kyEMd0zHNulpDarvi4jEnm4Lj38oKIl8UqAfj3Av1iRoWQgrjhSUrztHQRxkFNezDQ6wwbsMx34fgRdpWLFLgvjGu8KG2BGNcqXh1CX2/8Sk4mq/XzexRgcbZPAFfz31eh7H2aZrSADLXY7WT3h3WNZ2MLVDvU/SG84cqUNL9avSfQvfS7FpRuvnpFtocA/PDVfwC091z9qT1yP9eRCZP90UcmYnzPI9O9dA8V46EbxVHNEysw071hXfOGbsB5vy0NdYauQkWkNYHpNUxXhakq9ARpRhAqxXWEzMrwG5ZP1phZ5YcnejkfS5eAZLfRihZFcOAo5brreb9t+GLl2llURLkWrtgJXEYsIUYtbN532BV2jtsdn3PB/EXBoKdYzsiEGWzT6K91oEBeSjW6uVQchosee240yydRHWCBoz9CpsWaulsAkTGwrxEsjoDXbalsDRDcXtKxAwIXTPgRMLor3nXg7WMT6/vd0PT6CrplrrBlFjzPUhpw/sy1+S6xekUKTSZ9a2aukXSWW4scUj3YB1NH8jMFLIRl7MXBJVjrA/x8cQoaVv2ODJbgBf8XvaFJTsU0eVXm+RsJQeVn/vFYiNz4mygvRMIXdwsRt4FrrThdKhVUzPhgbinMVDWLB34yiqc1YVB1j7ePEmhQ5Do06lZDzUYLUejPWDXpRuFURXy8kEE0wX2fb8AdKh5SEzIeIGJGTKsxSOjbLScREm48PxT1ZX4sl0ExRGKxh6rsvajFqQuQxsCU0E7BjenTmCCGJ24Y0MMWk36QVArhlMQxMwsGleSiPp603vETJ+OCG+x1ZJcql9riduxX4uPkxl79fvdKBf0doQlNTuaM6lKBn0eHDs9tykaPwXWHodcs8HBM5pg9KhrP2VxCliHTdhg/XFZR2vVXveFBIhk2h6jsUrGEXLg++a51uT3pRog2xyQud6vsvUD1vvlhC8eJZQ5SKEpkqGncvX7S9WbaztB/nNoY0GwTMfRxID7C3NX8jFT3uFEYZoTHWW8ieoucG8tGwBpVpMGMCk/vlBo2lRDe4ccPi24FyQgI1adZ5prh2/3Uh/3E4CurJPUxmiMbYYKAD5MPIwoLXJ4vYwPCJbKjI5J1xBKVmql+QbW2xOxjyml9MaZMmCueXa25ut0Ud5DdXB4PF06E94pS+XJNXvsYAWgJz6qgLAwhcG36XfCp66SKzZ8jVY1Dq2h/SXNTLzlVb0qE/XoktHibWR0k9UxQL5FsqqbCrslwCGvAaLbKinN1ARSb5NCFe8aILE0q/VFHTQBJ3tb/wdV5AjJsbupYOHIdw+rb58wvX1x4IRVGdACnTEVNm+2456chkXjKsLRaJdDgcSvJuNYldoqu7nTrq+M5VXjKu8g+VyvKV6JqVveyC1gb0advWX0I6et2V4NFj0KRKwyCybIqcwZ7dYdhocrCglsDvGpLhqUXGq3UK9sdKlDXorSwd75bKyjkyZRlDEcWdx0ehSiPGZFzbgxrdDnu6N9+VD0wqtDqu4jJQOKI8ZFA0CElTqcicuwyxqJjlwCXRJEp1WRzrmGgj0yWSaYhbjYsS2Peitbx/HfOq7mYumldDTwh2/PHEtgur1uC2P0ysrNc+Vmubhu6BguYcMja7vl4m1d0C9odbo7z07Zs9eu1qhXuT4n1nHxYeNHx+USWCqKwTnBO3zUZ6yVgsCoPARuxuMDwPxcc7tbADuSBJzPOFFXpLK461TwGKxMcRc3GmE/JuIRWWxsQqVONyJmuB6hH0j43TDmFszHFkTtER2Tp9PUQ4EagwL0LGHePVeuaGn7DzdLlooWKsqA2wpkUGpe5Ge2ijHzhFV/aksatRXU59mA1FYwwvg+MdPNCODpIAwthwVSgxu+h1b0Ovd51JCepsZwFSxMi9SJKtoMta0faR/wJj3fenztbPo3SBkNRCpTS9nyDiFWovRxRLmpy74sflJoFvT1julZa1FnwmpQi6njfI4pNqcryePVBAYeniTUlS/tBKmLRAx8wRCKiri9vmAJFH2oC+SPZG9dc144uV/sETc1OWbF3sHdYJz4qex+RBbeFZ2263YCD1M91+852veyoa/hPLUOqqCikYhTrLgsUc2CNjZcYl1zwguVcsFt5Gut/p65v3v8OZVNRbFATf1W103Ww1ugH0LIQchZuL0MESFN7Pxdkbq0izU2JYaQ952k3C0nCtG6jjVlHsCpq2f7PNE4Lr5V28teqaGBlLIf8dLRN4/htl/Hr7hIaikjNcoRlgVfxbIE1CeX6M8KNkxINSOZScCOrShnVEFY7lNWK2T/9TbaR5JqxgpQF6ojwUry56lRNqXbegzodreKOOy6leS9e2Ybm1M5m2BkMD/qD/f7O7uXg8Giwf7S7lxzuP/2lnsdgz+bWDenjV0x00zRKPIgaRTBLCRJLsbaWtfSgbINzaeVyasntjhts7UnT2jmTy2nPueByOd3qxZPHBZLRnFy64wVrQ1SiLq6UbzdFDDYsOtQVm4PMhrr5VlPzMeEwvDUxa3ODty2Um5jLrMwr1sceR9ipwVdkz6TpVXpuPEzHYVPQdMaSiBZheUu1SvP0jivFxptcFKW5CtERVEhXUsK74EoTP0D1S57nvPMZzFUDHhl2Ms6pm7oWfU4gqy5MW+cklFNIdbvn8W8mMthAmM9nqvy5WoWQLlnkBQ3MLjLvjbFrylvdl5hYpQjCbUdKBWrrNGkeJMhv9uD033u1KgBuzxpIv5Nj8Nhldd/zGi+jfqJ6Rp4UTM1ooe3m0wauo6oKfRCWp+jCnWQGwo8ppnhF7ve5FNooiz54bSFlwWqOTaYf7uzu7R88PXw26Pp0/MPJaQ31dd6gnJ9abLxXK/Z7NWA+pHuT/cEgq0MmpqxdGHx1neQynAnYAsRLVaoUv2HBokuZMIrmrjKLkaqlYYBu4Tt/gDIwqg6cWBdv8KVXF/JlqJiYOElZncS5lq3Ra9pUPMGcuaLzvvY22vr2vLYARee7O8s1XXS6G8+F83vZ3YV+V2uGaV3OrcYgJLG4gbXTC5qCO3t9stdMSSFzOa11/LFHjbz2GbZcH9VoRf5XE7nqG7/co5XO7P1kOBiuXnL+mjeF0Rdm5/p6CA8ydNG/jjl6dqC+H6V5PQSF3rzaEP8cg1K7kNCYzG5fdlcpUWobthCA6u263syq24J2fiZvtaC8i9v20Jwp4xUZ2Au1C4qG+8o5miZtx2fV8AHTw2bY6lZjYRiAoFZ0MTrgyIyKDBJCLmdsCUlmC2sqQ9Mfv00VszjDfVH1JaoZQBAl8wprbmAU2OkzlhcYU6ONZYbFjIH7L5SGSuUcfUCEGkiom5Y5VaFmVWU6Kqtcdag8loI11q/pVGtTZHGWqFobVBECXJqaosszdeYDGCgoq8oCS+A6toKGy9ZEhqHRosjLKWgCbU9KlehKYScIrz2jPnwMqiCcv1s9v29w5FGjlEPNFKxug+HGxT5/m55Zo7qX/feie528b63sZh9M8BFYrhWGq7DJ3jkuv1U5iNklxIdgwU/7nB/4iStnpoucYz1RbqyFFjt1CqqM3rKcHG8Wr9z3CFB5IhVRDNLSbzXTrU0AT7gWI5lMryoHtBUHVvcJCVlYJI1g6V+WVdvK2hcu2R4AMYqzG2+tj65w9UdwL1NqBj2GsOekvGFK8cwxK42Si30+vQe3R4qcWQtUM0ZGz1FcQbLNsmB65MX06MyqljxFGMlb5tTmjpPsghVk+IwMDo92Do6GA7xLPTl7fjT4v/4y3Nn7vy9YWtqFw78IVj6eU0GnTOF3w8Q9Ohy4D5WSa0WdLkEMYbdzbWRRsMy/gP+rVfrX4SCx/39IMm3+upMMk51kRxfmr8Od3Z3vImI0Aj3CUnWdse5C6Ys+Zq0h+dBT1uE38hU+Miakyy8MMhzPzsjdTP2CQGBBZT1Tnlv9LbiWCqZ8AadwkgoDHhN7ZmN9ZLzhaSlzr6RxRdBcrztXLxhqd9NwQ+f18Ky2r1FuYs3IhgpgTy3fgiU656pTvEGYnj0Cne8StQNeeYciBCPQj+2hKAL8XiWnWG8DjsNClt5yJU8Cbu4eBgtXoqYSBq2K/qBy6nAEr0fVGLKKjg1dZoIfAjULO3ok7HSo5oBHlJUjNM/jBV5pWW/i1HS3sHE5iOelAn6qyCJcEV53xoETEYr8Wj1fa5m6cBNch1uUL1OTwlVPDjt4RYJJI2bIcoafFWKAwyXEkdWtRr34iKFiGZQ3OHE41CENV83R7d11tTqaCd1xqDqy1kSMKyi9rgzuzYtQ+6Jrn6E7HXYVKiq+Ps/FUjsfXNv7/kJOI2/zHNXGmopRFdzwJmpIRnZGcxySFjqU3VHX0W0WOJIvlnpu9dSZMUW2BR517HRWjl2ogr+HbvQiDSM+wXYlvaofRt+h2PfHVf+4tEakmG7d1r2ltoyKUb2+jM23MDpZzJZx6QofZtYWUm3Hc0cwjh0N6Gb1IJ6CUu5Eq6WoY/AQ5VOL1wnj/gwqmA8jgLdHdZnihgzyw11NuVeQbqMKtOrony2rXmIW+RD01eijThZsTKDrpKuIJRrwREPa3Zsxwd2xY3U9KwSDMRPOhgZ4QYzW1hmBRKYcjXMJwRiaGzbqYJpLKODl2tCRUoRL/rra/1G7X7G6C3MNzOYmIO/eviA5F9e+NNjd/TM9Xza5zo+C7Yoh1I2ncehciKdFQXEcWcy9oPTUStBHToIjMA/tQa0Ynq5zKeA2E47ccCMK9Gyviu/SgQIirpW3DXNs/2UwAF/jysvD9fWVjnTE27TGSS5pZ9T0W66vCYwA9qHiUnGsztUUhNrJKqJlDomUOirf+U4zd3sGqMH9lbvrQ13A7tzkFtivhFSrdEe+FYnNV+CL47+zDIb9CEI9jMPUKYUr4IDEwPLMcDDo8F/OKXcNo12j/KUsYd3rN0ruREBJAvWEdQSQrl8g2iEWzh9pDSTqXIqABlLN1fABLQkbXDfuCHy5lBWod6/0rs0LX4cFE1ZvO9IhWr3xKFQyQvj9zRtmR7XiAHpwDUqv69XP2QeaGgKVZlwNe6cTRQEBcTiAh626www3QS1q3bDIrL/HrdUdlIISvBhgHCao75/agXnXhe3Pocp5MBbCiHE19KjWHj7l75V8fEVslHvppBN3yVgW/uCOQk3DSkDAspuVO59CKoXm2sR6t+PM2NVoQuPvrpYETscL+IyZJTP0axrlcppo+D3xvyepzNgo8cLXf10dr7E3v8oQwhxpN0VLUandCqNUm3DFFjSP3I3npxdbIRq19kZQvx1bE240kQsRZsRibvZ8r6q0hXFTWWCA7+3oRmFKAeH2KfK0ztOGqlUSke++J8RLyI/eFLoQ5/iuMOIIvDOs4lJuuSy0+/R3KdZYSPBuI7WGkt0QleCwKxwQQkebS8BwMNd1kVwxmnmdzB3WntGrC5/omMQN6JmjimeNLfo0ZQUWowmT+tqYUGGf2u0vBZh+56du8o2zUsmCbR/PtWEqo/ONqFw3HY8Vu0Eb1z9+cbmxhSYn+emno/m8Eiac5v6p/mD/aDDY2GqI0Xam0RfmpTIzrh4Y8wjhgXUHVCOUb0OX4z4GP27ASd9DlsJAwujsIJUi3wqojGJydY8wYddbRxGSTq5mEGAgI8cXIgV1cwtllxSUTufU8SVJm1HonzF20fmVoHBKnWtKtUr3kQcxTtN0EDA2NEbzGpkE4cYFRLbfMG341GNX9/CsYFUIDDl3Q+O9ABf9jBVm1hodjyR36Vc5e/A+W8QJfq7eqQDDkxQ5Tdmt9sktdkm15T/JPpkvOywUmGJ7f+fpMGPZuD/ZHw/6ezvDw/7h08mgv0fTvcOnA7p7OGF3Wy+eHyaU1sqEPqf0Y3VCrR5RaqZ8Ul+IjOhO5JuUAq15ql2mWZRuBe7Seif6hsfh03J782zVk/mOduG+W7hPyYDVhxs/mMHFDoFfxSN7j/J6LC3bMVyPmjQa5oiyU5DxTbU64aFWWAudPMv2Kd3r04PD/f5euj/p052dcX9vb29yOBjvpunO4aroGsWn05U8n7dXmjitZdTVWMwNv3oKv3veOYWu1trwpiK+mzb4onr+DrPnTWNm0ttDou6L3RpzkjcuI3RCe+U2T70XXX2K3ov3QVa+J+R7EH3vhf1UlGNdjvEzhEeC8o9/W41M4Uc4Aza6JOiK4o+7oAIv/vzfd2Q1H2Pb7EYKLDTeacWjQHaxJmNrFtaD012Wrv0VYvV9XiqU5EO574+/59BX3BU7cVZndGEC+g1cwfoDyif++r+pyLalqpAltSjbnuskE27nxkuc8txfwJOXVZTDr8/PX/7TdzrVVYqvE+x6K8GX3eHg7joaabDgJIYuASxDajbwCedDFYXmLnQeJVUWY8I/wV7bfEFdtJoLXssxMcoP3Xmv6S/AqiXWGEYOLYDhAME7uI4wVGqwdNrayqRUXcdwPcJ8sVUUvnTl+UBrvaFqaXmmyKmxvJ+Qn5jCcHnobsQ+zGip4fIwd7VYUAbUlVirLAUHOY/zQF3t5hvWg5tU6A2Q9UjGFUuNVEuruqdqWZg4sAJlD+uRGc8yJnqQloH/SpEve05x7JGF4qbj4m7z1w3/7EaPbODTvk/AKnlpMmNXmk8FJpNnfGoPGJpbld7MVnG0PrwrEXaOJmGyKjCeT9EQcxcQtzcgiePZAhbaX817Aeh6tQW7A8ztMKRvHAveKPukgnAX18Ok8pshbSpwO25RZ3Rn/+CBpMdUqI+Yyiuof1HAKoe7Rz8DZK+ipdo6tDetJHoo09hPXEzXp5ZsNprmrconUa5FyBgDmR4Vb51TUU5oGuoF0OrS94aJTKqk5pkMhnFsCxwXlqu+f30BnSG6OsfMEzsnSz4UaQIXgg8l9XoT9e++RqulcBMEpZvkkxJb7ORyOrVbHMSenCpazHjqKy4Fh0c8KmT6NoLpjCq18fORF4zeMFKKyknHfbMYfLV6xRsR1fiVt4VqUgqXpt5eMehmcvXu1eXbdxeXZ6dXb1+/vnzokpVYOrldsPJRHGEXOHwtbAEyLlGUNRELYQXkRKpC1tJr7ouZYXS+5k1vp3jMnQ/jSeW2tgvO8PvdaYtJtdHDoPfc8Gd/++kfvxy+PDz++0NJ6x3Cn6D8ndr9BMmHtXzQwBx4KNiNEAJbMMcITsv2EbEz2Bn2B/a/y+HO0XBwtDtYPSegiZ/dnyuptneceJsXRvpYjlhGdOx77OMcccnf6zVBbpMXrv+z70ss53hwQGQLpHVGycC1WwRoEVS7SrBqhpS5rkJHbli+xEoZqICggGureJ9yNoNQ/EQyd2sWePU45QbqeEY6hi+N4It/RPozI2Osle4SGaIF6RTrtLYWH5HZ96RTVw72/YwrMCB90w20hla1pyD1CZmt9n7dmkqjPKPHMv8qi8kZq1gZA6sDdRuE+Fvo2Q/DuAVE06os4P5vNLdTjdxVAbd7hWkyAiyiUCeXlY0J95ZNTKV/20d7RHORhuH8LYSH2+9SqC3ZyCOOa2Q9euMHGDz4guvBhAGglkmQ0TqI3hpcF5R+/DgFwZlBuQTRFbeVj2vGZYrfRMHb0NLbXVdFV0gtDLdncs62ae4pHzC1w13hMJ+KbCdznyqw1bH1+B3Y1i+0QDD7s7zSMoWPJO1Me4ry3IuCqZRqhgdA7doXDtc8BJLEDdpXlUosnyR/jg5QFpOvvQuUxeGr7AQFgP87d4PKJ8mX2hHKwvYn6QoVofLFd4aKYP3Su0NFoH4NHaIicL+mLlEx2F9pp6gIhS+8W1QE6ZfeMcqC+qV2jYr7KK0A3L9z56jai19Z96ga7F9TB6ka4F9wF6kanF9sJ6kalF9HN6lukL/cjlI1eL/YrlI1KL+WzlKdQH+53aXifkuf6Wj9WjtM1V78CrpM1eD9gjtNAZxfebcpi8MX3nEqjmo2TKzTUoUbojBLj7APaV5m/tIxZxQ+Z/KOAiPBpQ0X/DOqo/QJP7AmT3zwvaEqmf6+1QM/dxgTZoOKjCJ2ZocM+icb0983euDN3sARNjryxAsnf0NUqlTXHWENjxiPAlO4Qv8+MgWuq5pxpXFAamDZgP5rgbZ1D4p8uVsbP3QIKYArueZErdHDoG4W4uJsab6gSw0LRI1dWkdtmMaHHMOQ1hYEboCmNs1GLHDiXWu4coaQsDoery6fX/R8HWpCBc3lVJYu1YQc55DJYhg6oi6MYnROnhyfXmz1Qh1ity3CqK4WIzwKvWHCFcq/SijDkucsI//n6fHlcUJ+kYIl51VABlYem0uX8FzLhfe1OYx0oaOhfF0mFyKXNIvrPYNTRDADNbePTy/gks3X8qio7u7apJofkdHJ0fuCmtl7I99bmEG7DrviSMs5uwpMOkIKjBrfhpHdnV5VjcZvlKryQvVWgm1b6hOOmgXuojetWIqhaL3UfLh6AOJRKu4o85xYpF3nmMR+HvXwWjW+igLG6y7VGy9iZB1+RFpO1xbq80bxOVVLjJOGPMUfz0+37rxX3RwOBsP67W8VZb1uCONYq07o2reh9pBK5tn+muB7ebqPU7Qn1TM6XNOsFz8dD++YtoqFXcPEO/sHd0y9P1zF3/PAqfeHO7dOrTPG1sWEFxenZ2dvoqlX2LRcrK/Rw7kdu0p/9WoNnh6V5uLTRJo7eGf/YPdwt76H53zO1nnd+vL85Rl6sn0ARBwdiLZmvLOJVP5olJOaN4KQEhrI+DTIxWKRcCpoItV0G8t5gMGxPWcZp33w88afkw8zM89/PT9+dRwdbhOecpqjV/ifPRfV4K9cE/Kz1Qg76tJbVQCvGcY569XSm7FVQqgjG6Ee+h2tyErz9XHSS8tIMdm5IDI1NK+4i3Ym/W0ODvYGDRb6xKCpjpipEOxEoSwpRLfVN/8ateBXjcPGHfKhT2tlXfjawRiZ5+KAWiTzlkJTm5cLsbY4DUwNsxNsgsKtYj/oHaem1W0eD6TP3Jz1udfU4sC5XmP5gmnXEZVVM9+yKNrpflFZ27eteME+R6zRyZt39TgjQ9WUmSoNszPWaPVAowIyzgsq1hVSh4YJVG+HaVrqX8+nD0Isowtr6WM8aAOvTwq/L1gSAbZubKNvH4jsG1rFLayCnB1+zbEDAbub+j3xPTE7SHaTZweDQTJ8ujfcvweKfF6s0TO2eYzOMIeUu8WG+ubkzRnuNGtdOyhIvw8d8eCxuC0Hsb80irtHPTQwiJszLENB6MRAkjhSzJWyUK7VYiozhhXyK2mmqNAhu0hjcVXfs8H3X1i4tgdUTH3dNEWDawagx+zMegi5cuoRNTXFbMIVY0ssTTHO5XQbaz33rWphZdP2zmC4tz0YboOfgotp34We9ZE4fZermFidrW1PD9KDw8Fuusee7ewM7YcspfvPDnYpzXYPsmxyDwbxES1XsBnWqFaEnfAp0uzizfH5q8vk7B9n90DRpdmsGy83zafgtxHE9fsPx2fenwWfX4cCrheYcrsqAe5/A9bhUraD2G0NBknNQRgFN6OSgE4irFTENdmwf260WXh4sHu4VwMUj+mrr1oFu0RVA5QwKH20nENlns/WDB9WC4yuJ8h7GVdQUMFBstXiuVD9IJRCWmu1D6iQc35KnrwDj5uqKndGWXdPLhruONTlV3HKfdgfPEuoc0vzGxRpa7/VcjmR0bwu5OrJxfGrrQRtKjCyQ1mAriRRWpoZVgSlIqulIsGSjktTOb/dZS85f+NvypnukdNXFyTGmJAn0ImE51lKVaadW57NKc+r99qE/T5h2PYgSeXK97RAe+jhrBKEc50Hiie+qyMFYvfJySvgGwsE5AFHJAzEbWHr2qeDl4/8xKczcqx1qahIGblg6oYpcnL8MCKUwqwt9aYiAMxCnpxsYcfSJn7vLh4CfFTqgGXrXMjTeCK3jqcPWceTv7676JHXf/XreS7SHnn97q9WI4uKhfXIyau/3rHmYet80trnMqV5q5zroy++n8bLmxdbLaXJsoeVFH/nbPEQTKSaUuHq7a0Zm3gqTZ68/oTNfC7ST0WW5lel4OtSHLtwpjmxM1rU3z0A9wajPwR/bSjkUF2B0rq+2urh6LTzYTFsnC8cnJc9cgGqy5sWS5/QnE+kEpzeC0UhzRUYjyvgdJu39pLPwdpDq7GZvQ0dkECXBlNUaJ4xhcW9eDvDfWewM+gPnvaHB2SwezTcP9p99h+DwdFgcG+ssMXTOtHCmrkroDR81h8cAkrDo73B0c7+A1CCEsbp1TVbrr0y0HGrGJAvToDlHgASO3IL1bcX9zsXIqTSUt2sa2NdYhXDGxaFVjHC8tw+kLqfKrSi8kKQuBoOP66jQkn+PqdFBMG1KfZ3hg+lBPtQSMHum23UyBfEIcICZgxc143lC3U6VsDqYH9/96mn+qqdsh6A/Sfa5lDf3lrmzlKKVlUXNEWLnZu2er8z2Fu5NCXArJniNL+qRfc/NuO6trI4VVWuX5cVF3efgtAEJVSBT5dRc8ZJ3AAZ1r6YUVcPv0d4HOSKDkIf4CXB1MqtFmLtpZCFHYZOZxSyVFWbuvv7z3/44dnJ09OzH54Pnh0Onp0Od05Oju8nLUKFi7VLwCi4amIJGZdcCmU2IinxM6s6geOddCAKHt0T6OnFBflRkhdUTMkJVGNyQZ/LhFwwFrylU25m5RgcpVOZUzHdnsrtcS7H21M5TIZ721ql21jOadsSBv5JpvIvL3Z3n/Zf7O7vtuiPwRr9+8pnZ8T/MZarDqarB6OJFUbOJtNcjmketDzBVr7waCD5R1imn2iYeuC/BMu0VZ3MuYCwr98tpunF5V8r1bVHXvz1ggry3BqdXKcyMl171nxJwFB93HX/YqzSGuYPQuWPNktv26i1JfxkzL4AG7SB6P1w+TPbk+5Od71qUZRgbCd1ekqL63bvhjzErDLcbK6u84/uzzvKOv/IpC9anEJ3H6WWLiYeyjTSKtgLKuBYWBXDiloQJO4hrbUuAGV8ymR4Ja7/6DsIMWzljxHbLJ2Bglg1ZrSQnb/x2p5U7vZY9XVZFDkPJbs+qVQ+N8t1VVI88QKyfc8phVGM1vsqYosIJsxV2gqMexR4Lhey76obpa1AyzD7pu6G+dXK2laFyJoI+6pWmtJN1gZYKjMjx2AL0AaAoLZccS3XResTpxmdX7wGYrcVhuNOkNbFig6czpU9oYI2qor5bfsRUKZMXsXFROoSW4opN2WGNSNzauCP9lXUf5ONXIqNI9J/upscDPcOdwc9spFTs3FE9vaT/cH+s+Eh+Z/6NeA6s4TeWRnj0x4bUUs0kKbn68xhUxw5IVNFRZnTWut2M2NLK1MZStPoav3EG6aNHrFcofRNoTOa7uEdaS6lcjZzL5i97U6iCF5eJS+jutoDOYcnZT0zrMqIQfcKF9bwlnMQ75H8bl/wj6U2UvSztLYuhdSG5uvaVZtvYHgUX82ULVgLD26tMCf0XWg0LYoaKoeWqGNGroVcuJYtFhWYSCryy/mb2MDBFopVFfgFz1i+xIPM20TQ9Ac+tmn3bG+wt7LHVLGpVULWKKzewgx3yar+3066YFqTtHLwdAqrv5VszOo8193S7XGOTNfZkfzu2oLFTNYLmsr58avj6LlOwN1BtH2spnDk0u0fSiakvjrmin2kJW47I8nrd+GLu/sWYZqRU/OsNOroXgjP6KopQaOm4eO2KMrknPK1pcnGCkIIXIe/kBDQJHTOXG/RuHt7rd2yIC9Oj9/Y/X+MTeCrYpgIf5wOFxJk1hVd4/ynvO7Oq5CSmCGD2THboSvF5zo2Y5oDQMl39VymmG9/8n/fYZj4lg6ebStOjVqPcrPg2j0XfJhxC1I8URuhndDEL3gzlXfU2VGY6w5DXp7u9yAhbYtgSR7mVIKEHGeZB2oSGsFgeKobYrwkuVyAS9kH5tdBxBOfeg8r1lHAxsGaFVRBeUI3Mq2fXk+0oNfYU61HsDnyjO5e7Q93tgKCVc53dc5pZkJ6chtpeDgqS11CZ56bYPZSoiB01uo5TEC/WQwWJGegYvSDlegG9LLxX3TXBQUjBYJUhh5zWZXYhSBCdm+4pVw6U5M8MTl66gvWI4rZybDe9dYjGIGfO43y82dQ/jHJk39M3uQXkjIZRJ90Fcu96PN/39lqC/paNVtt4c117vanFRtcaENF1O747OQC3k2+9xKqswut1ZfbralgUimq7ed1GGhFNaNFwQTLwMcGqm4VTDBnVJcKa9EtqIYmkiIBXF1YZD0FaUZVtqCK9UJtnTlWENY9cirTa4yuMJQLMIHsxv/Pcgzp/NAFOQuFGT9l39+erPQoymMV0u3qSMTzdVVDvjqoR0ynRZmUmk5XObKhn3x2dXuX+jdMWZMS0qfgDMDVg4iW0Pjd3cNWbdft09A9vmb5cIOngeu9ja3rIzXqIqW5xXtCrbZkKVTrax9pWUfwByVmIWEe4MFefKtb8S902rlhik69olGZ2e513QvdyAcA6TAYXxphuophWtUEy7i+ThSjWRJn7D70St9IU12A+yxg8mRKyynbgk5d9vBMmdaT0hrmT+h0qtg06i5AkO40zwE0veUq3IeyLNgzjqQyz+9ZcQ9Qxd5g68fVzmOY+CPR/Xx2CFoMchKJTS/lvTFymyVSVZPHnZHGW8IOsrmpb7NRwohSkVfM/HD++qJmvcBMWCm2PXYFdDRTGBGsI5f8ojqK1L9+dfn64vWqSzFlMvmC3PEAzp/FJV9H5gt1yyOQX5xrPgbrC3HPW5C+eBe9BfKbm/7LdNPbtfnmqn90V70l65foro/g+jJc9hagP7/bvu4EWBPlN39yY8daWrSpzo0z8KqcQk0WMycVRx6yEfgD7V5RzJRKaO9PBh3VWecfcXU/Dj7Oz426cdxA7FgHOqLZanyRxBJe6VnZ6Push2uMOaOCi+mkzK3UXMpSESZuuJJQTika/swvuYuwVxhz7qzN0ZhRgxX3mlQoPkIFXnThCb4RXjSTNINPkqbrYhby8vgknjZQwCIupHE127F2FQjKt89PyNPB3g70Pi6nU6hVfETOaDojMjXMkCeujVmPHPbHvEqstvbeFna7dJqt8zIsJPk1RF3/k8zYB5qxlM9pjk0ANZnyG+87hzWtDBnkc5yYQjO3UriWzFwYNmUqIRdoUvIb9yBeeznfuuvMG0acLYsZ6zg8N3/dGAz6g0F//wz+3e3v7G70SOvLPd8g+/Z7lsdZvld37nOI33Jpw7DDo90d7ep3gn9wLimvt4Dh/VtJcyhFFcaM7ETw+lHUgJyrv/IXldqSHNIVrHKniF3KDPo1WVO3vnxG2ucbm8i17k/YFGqCP4br4TanA1whyRI8nTTP/dTAOtBEpdXJG0TRo7kcGqgWNL1mK5UIXw1ZN94Xhy4X61taxVIGoYQe6S8E13WvbcD7D8JX6mRC5zxfV7j56wuC45MnXmdTLJtR0yMZG3MqemSiGBvrrEcW6CBrF8DAJ1twl3n+eFB/5jIkrZsFlND1SnChIpXzLXW7vmhqqfxS/ovetNb2minBHpFKd+OAswWwwbBTdOEaNbQg30v2kkF/ONzpu/voJvSP63v4MlY4rsjoCHXbkv6jSQ8fEfK51tPP5/ZuyoSRukfKcSlMedd+pWrBW/t1jTV1Nt9plIYjN8/IeRugP7VhU6n47/iEbCLJhZGVYloZm2MlaQYmFVNQgRXkGG8UV/KPa0YmMs/lwo7sDJh6UVXyxMeTsK0jkmPx+TlNgaKCf6hyIhettrPnCNLrC2v9bG5CTw+8nwNnjDOlXBxGzvH+jdXbj9snxpUOF66SE/ImZ1RDIUlSanDK2LNGFsz3KYEUT5zq7OSiZ6laKFlIzQg3kU/MFa5va+GA5j2OpPVW/Gvx+aoCazhIhnvJsAZtm6sfx064dL31GjbCc6nISS7LLNza+AslzMiAq3zXyhcqEuX8mpGR2UnmLOPlfJRYZrqZV9zWvjIK9/Y9bE0T7rB8Bb84E6QyzsOIXUZ63VYoixUr8t6mVF2wVIpMVwrRjGoyZkwQjFqrL9vuzn4czmFMLQLzp8vLN/D37eEcz338WkiasS9hx37Ibw7yp1S5lz2amdBEwiNlLS2VexGj2G8l048Qi+kHGsts+RD1/KO9tS7i6nIN8AnM2iT64eHT20F01ZNXANKXxfpjzvBLZ1njct+J708szyVZSOWaPbTwXsOqXMLVvL5rbZ5YYMGBjj0vO07r4d5u91KtLQ5289j5+5qhsNAFq0ZrcOwrF0KYy6n20SFhLdOcQwMRi6OGclBQ3hRKilLfFio8bVeUZ1WYJEo6vI4hQoq+NlRkVGUIBhKt8jeP/tF/i5D1z0+rRiFS2V9OHKBcCvtrR0XFnV22t3/wtM8On437w51st0/39g/6ezsHB8O94dO9ewS0+EWaMzOTa1uo2lrgVHd1w1cMPFfc2PMIomJDL5fQlxfDz+vREaMfzy5H1ZE0mjLju6L8yC5H4Piz1nGzuI3XtOp3TG3Cv3l9cdlNvTU3F9h8yV1ZwaBW2v3YlP8RRUPU1LyEUL58WQ/8G1ON3gJ/UkcN42IBVVHTKn7u+dEJvtC/BB3ZtcElJ3JeUOWtznkMMg2DWvUvUhrCbJubmsTDulG9QjJjeeE89xkzLHU9IRSjRpMQek3InOtUigmfQvcpt6nbK8nndMq2p3zlArqexopNmFJrywF+64avWDHeOi2Z62trjHM5jeuBbTdg14UUmn32cx2nXfVgj4H8Wk/2uzC+/Wj3mH/us91B+7DD3QH9R4s+B8bjyb5oCR9R+LlRO6Qf/vIQ8VeTdWFUp7w8isxzxNWGmlJ3RDF8eovV+r7BibqDGfYG9Zjo9Rr3ANdtjrUhGO9VIyTnY4+twfPal3fn5IUB4rw8X+NMsVQqq1jCRQLW9MWP9XlJzZyGAt2Kuebw4yW2iUXWcGlNE67YguZ5jyhZQuuPXFK7OXIqUqa2wqjVNvkQtkkYa0ZFBh4kGu4cUimEuz4g5Ny9TrXdCm5MSqxSl0fDVCRA4PxYmgktFdxqEF1QAS0Ot3BPx3D4i5YOUnSkPXy6pUxzTtdVazqwDs6Cdx3VSlapfb2OYDC/qpUXxbLs3Lc5Qh0XSMxBB+4RWRr3QZFs/ru1jiASrVoSQeddbiz34qrSZG1mYEWv89MmsWpsX1Hr4tXLN639Q8j5acfJt7IptcYQx/N4LdjtHNFuyWRmH4G/KvQwjeXXC/fnHblJp620IbDJ7EmWy+kUTiiWzqjgem6Zy38JJrWFPqoRA0Z5lapkBWC1Wh9NV2pN58b1MjS1ZgKEtm5btdrPH6Ux1+1IvdS5nIaJxiw60iA/k4wsuPhY8v2ohoh/q+qMJp0fE5KnXI/YOoZWvbBIsCwe//tgy45LQxR1TlMyQpi/H0E6pXDe1LOTC0e+R0iICv0/16XVtVpYWYJDAwCwepBWqWV2a/o3bjTDhr2rx9VKva2qrT+puIEsqBabmwYzcDDjJMDXI5mE9QpdVe/yGGzfULWdy+n2pBTQCUQnfqOtIFHi7jaPeivw2ntRLFYhHtovQ72AU6CN41wZU8rdHmhHIDeUAlMLGuWzG6YgoNk0Ss7C6S1cbvJUQmIgsj0MghcMsG/cvJlkuCq4sZb27UpBX8oSvHFFaeLdFva6lUoeGAK9D1HRuMCt7n/ainPX5Jz5lUSRNFpQJUY9MmJK2f/h8E+la9C8w1vHlHL+iUjUTpsehEeLdo0DQHEid9Lbs9C1ckTdzJfJLXUJQijeWPEoaU61D+DighvuUgSrGUB3cJYKJWmpjZx3RxlINfX9JrA/UjKW0mijaJH84D/ViIUOP+jgleS8GSR87xAaO0QUR1NrxEi58Pab4zkIl0DMneMxzkVr7JcGqns7t+KxzmSIJg88Fnbh+66KAv7qOBQTcf3fa5Id4wLBDZ8afK+arPsVOy7IhKofdXuDBb5J/kVvaCfRS5GusXhki+RuOrsr0NndovJHeIf7QpAhlR3E1ArwY+/426B00m7ODIWclViWuzSV6AxE6TnnJmaLG07dMOHGXzNG3j4/0WR/b2fPIr07PNhLOuBPJjTlOTfLZB2uhM0IQ1f5mfgJW8cbYEtvKM/pOI8VgePU2tuwU2SElbW7LVq3ZCRT4QOOq7TjMKR9d2e3zbg7u3fSaI1SIqKUPan76BFbmVgNPCCF6WkXLoXiUq1WhPZ+S91YZj9Pm6EfuMSsGpJrcki+r4jzH0FZSMKIcJSGQub2fQV9Ggj7ULDU3fX7gGzquKeRn/5s2HHTt7vfRdYAwP230Ud3TFCSVt4xNdXZHS1QoB4aG0YCI9YWq8o9zYkrSQNUajqrzk8vtnqxYmg1uxbwbmdOpSW8s5f8j6PkTtCtngmHmdczLbDacJGaSJ21+qbVeGSBil9ewZ3KAm3yhm7ZCUpryTtlQljwdWsOfzQzhAnrmQIrMQH4J2/hgMiu+AMXP4Kite5nzkxoRJDHPplX0VcfKZcV4r9rhWPQkTufl8IZAWiByxumnIZCqyo1EI7gx4kLv+iau8NHuj+kzIwf3QdAuWGbSaJUODXpEQq9VAbQurYRdNKPaiVHU2IXRHXDU9BsQ9SKczLES4685B3pgXZPkE+3M6YNOX+je+AQ1724Qr0Gc2zBlW91sdWI0kOV3enbyBURkHYrVXBuhpIDYYyaq6wdk1GhpWuLHGEzZj6mo9KRKoIt2LiikiXlCK65Rx0j9Vxc4oSmbCzl9SgOBRiZhVVd1agRaoLoRzeEYxZXvjEyVGzDrOPfSqaWXEzbe5byeY27Oi5wW3b9fS5vN/H2Fm9tsbkxUwod/WNptxSU+GjEJp1PyAjZBG+URxgBY1nGGh/W9vffK5c83SMjv4/dT6jF8Iqaupx3HFYHhzUCOOFillfrDPrynai9K1VA1r9Hzm4LLBCHO4NqsmB57uRfwKdQ0shU5lUafV00Rm2EiJEy79OpkNrYQ9GHdhnpeb2S/5O8HnLd3Tk66oViGSTn05nZDsTr8wyK6HXog0ez1/+hX+399B8vf9x/+V/bh7Nz9Y83v6V7v/zt98Ffa0sRWGMNfqaNUz+4Vwz81jSKTiY8Td6Lt75zDAvhVVSxo/eCvA/EeU++9xeb7wUh37ubTfzMxViWIsM/ZGmiv7jrxOxe+uD/ikcm35NSAHO/F+8FCOU5LQoreEBMae/YtQeeM4DmUnAjlS+5wj6YXjxkh8e3CkyDkjiaQIUNS5UbzhY9V9MxZK5q8n7DI7wRDy0Veb/hsN9I7oTXk1oqUjDF58ww1YI/Htujcjf8NcCbyxomqtGjEzlcpo0eeb8RFg3+Cou24bD1yxYRInkvKvdS7RXnYEqV1DBrgIjAFNA0HkP9uEY3VAwp9ArD2hsNBcgbYWYhYQk1qBzu0jtMkqDXi+Za1oZFMCtMwuS1Gd2m6JjL56bHg/rR/MVIBMRlFWMfRdS7zJBJmcO35xdv7AEeD/n3N6/CiRri/ZONttcJaFkTIxOpFlRlLLv6lOz2qnUx3sFETsjoJ3crUCj5oR09NXy2kwyTYVL3qnIq6Hq7ckBpiDf+sHiFNv4TL8gXi0ViYUikmm5TrfkU8hT0tj9e+ghc+4vkw8zM863KHLlwxwooIblrcuLf0m7xac6nwh1ooBu/YuZ5LhcYtgyfXHZBGBeinVG7L116QRdO7dZ4dUILsRKJb/c/vgopsYKp+KKXZpk7gV3ij+V8r47c5FS4h2NncbW3IH5GMDW3fPb3F8evkMN+63PR/w2/MBSvh7kmrvRAQo5zq+RFdeUQHn93aKdNeAZkhc/ukhFgj2Bq3ONaXSIMCXBoJjJ36Q0yABYNghTtzj0c7CTD3wgTKS10mbsQDSMjMY8RMA1L+BfGrnvkZ66YnlF1nWwFgn8sCMMikDjs1rRjgObtUIxauE5rd68cZRFhsEZnyGtn2SMytwVd3IrOPUNj1ogI1ImY8hsmXDIeFpSGjCJnOlR1rPyma6LzI0Ru/8wnvAZ2Z1L7XQZPl3HjM9kfYt64dzsMnOqXDhPH/xiG9MZOt5GzU4879CJ5DXr1pouWe31xTl7KjOWoqS3irLrjyJ3wgi6ZCgAl3RY6WM+jHhllQo/ANTDSerY+ozjkxYWwa38Hvw6KXbitGQouVApBD8JmuNCG0SxSVv8T54l3XSglU8UG5UDbJ2VW9IhJix7hxc1Bn6fzokeYSZOtddHPpA3yrSkzdAVec0c28lliKbCHdIgarxaapT1S8DmQZV1EsVPXqPI1H2F/hsMr3LC7UeBp56d+HX93V3HzKDizWeEcvIE0FDLp2dOqRO+7VB1u3IyBdVN1hjYsNT0/PgaoYBTgR0fs1zVoZ33bIwbro+h6b7uQ8xwiX3xNcxyUipRhySSHKhh9IdG4FcFvJFGlWJ0ARMuJsdMlvnBZs8a6vzfRPfCtWvsKrGUujCq1cy/jQbtdKMAXxvWFobwqWrkX3MCom7phY5D+f/bev6mNnNkX//++ChXn1iXZr21sfiVQ9dS9DpAN9RBCMNnds8spI8/Itg5jyavRAN5b971/S92SRuMxxNieLMl6z3N2wYyl7pam1d3q/nQwI+QZJDIF27s0tJFq++KjL1r4H7ny8PszuFmgSfLExYLV4S45mvcJFb6GA6SOfKZ+X6QuJxT3Rprb3U/IG7iwo2KGh+JRg3xkKUDE/ZmxDAcmJ1dnANEPXctTH2kcKwmIZHloxw/jO30ohvGOvFLRyQMS5U6OOiu4DWFhzvxiXp171y2IFRlKdKPy/HuI0AfJ5OhBG/EAkok/MIxWxA0BGIzhEFpiEhrvT1zxgws0EtLBUgKqRoUImB/X1dxOu1RTRQXu3gpKC4yjPF1aQAJ8jxAMxBIyr/K3YF9eII11KcGz/aWSDH/42oISx99nsUGJoe/ZjAtZ+M6tuRJTZTje1UUkrBZ2iLzulsCHyJ7g7jEdDGUX+Q0gVQxyG4tnhe2RdWovFWrkxEba8zPo+OPvNfLhskbO2MA8YRy9aYFeZL2ER10cZv7m7OumBuumBuumBuumBuumBuumBuumBuumBuumBvPhMEz1NCjaufml4AojGc7frzyU4QML32ssw6Fbr4MZy+AilIT4w0czyix/7+EMx9H3HM8o8PDDBDQcV98wosFFJEdh0s9iEY0cKYLiqFOnhdVWpWgGRDH8oF+JZhx//H1uSS6WAJgn+OXQY7NP8Yo63RSa3JQp8JJaN72Z2hsrbHqzOr/4KEcXeHItXe4+PAjLYwEKMBlKy/DEc6m1RbC1IMc2Nxv6efaev+X0N49mrhEkU3gIL+PLCiLVgAr+17RLeNonQoaACZDnzFjM4hB63dKVsL4mbDTWMxy5VhfSZjs/FxZi3ZbD/uFlNG1Yt+VYt+VYt+VYt+VYt+X4XtpyjJWMs2geHOJFA3l2hkcMmikS022L7O7xAZjiNKm2AsYFxuxkNuxVNN0ra18yLGL/5m7TkOENBWTgjVw9cdGcV7Y9KBkr5q5SXGVNPtJkzNLGLLQvV/ukQkx5Z/QB9Fecwn/G8B8wwOAHmSQMAMIwOmd+ypPcZtT+F4JTOb6tiGUVKGG/wMDzbbjOZESFngpvz3x/V0Ka32rB2ZljOUVDlmqoX4DvumzT6c+/2n/FpgIGFUSKobPtCqV865rCrE7HjaiAXrCK0EiTbOzO+OWACXi3Wr3Yvjj1qhAL8D08JlVqQpzZQsOqYb8R7lo9pmlrXi0fJVmqmaoyjFS4j7fTPZe8TFVlPX+5PHPEGcE7UdutswzN1e6Sq9AxWUy4cME7zqPFVSw8jE+gu615X/N9C7U89BZKhBMalR2q26zH6mgZzG2yBM57VWdsMAWh/T6CRtlYIcJqvOpLhV5OXTNBhS5rRAI52Tobz7DaLerivDw7jfit3mA3n1VNFPjPVWtYH8NSXR/LuB7F0f3cZqfnp0I/xfVam58XW5Q9LxMV0h6eou6NR8sLK07Na6MEA3QZIUc0hrBFIrO4LzMRq0l5x+VfeZq/R18zf8BPff4V7KNwHFc6wIQyegIsRnSqgjvZHJAokqMxFS5aJpXNXClYm1PZHiEYUuoR/IcsGQNMFFWKCjQW+jwxQoVxoJubCw5yEbMHcMoEPOgCjJ6MnJ9VYDtXdj31ZWYzLj21JI3SYbE6cr51ECjcaS58lzu6hU3svdJOfvY83Rbik8Pz9siBszftdMxjeWP0u4wZrwPGXwkYf8fR4u9bS6w4VPwdx4nXQeJ1kHiuCumXHiEOITDogIUn/UXw0ZMHfG4tPn6+g3WYapokLPaFvm5WR9+pdiOkBLQnZKmVhnJfyzNEUREFx0rK/wpHhVxkP7QlBMe0Nbf5WJBoCl1eosDMWyokpqIh1yzSmapKadi1KkxVWvWHt/vd/SL6QC/jSVxxvG6zbd+lmasJ6slQMR2t8dslf83dbvGfBPggHhPKaDmuSedDGysMBBbCMwCWc0PMAIDs7/bfsLcHcbzf6jUP3r7ttbYZazabvYO3B/v7b/ffvGk1o3jeFz8asug2zao6247s8CVhOQ7BY7ljCqFUZx3J+297O9sHMT14e7DDdnabBwfRm/gtjfei3kF0sFu8ngkmr4ij42JlCOCnFbWDp/zTmAkPyazkQNER3JskVAwyiEpKu6VSSI7dUizhtJewLdbv84jnVe8kxxwoepYozm4aycrO+VMRw9KIARnK+5BhaFngV9RW+2UpU3UoR6mRQSJ7NCnJBT+exQibx1OOqZ5p9l0ZhQgYYDPpK0ou4RETaWW20RkOb5tL5THTkDL3sgd6wphU1BgPStuzAmSKFgaOGDr7So5I5+L4N+KmO+OpNiJQoc2RpryXsBxCLx3HDwCfZ4dMt16X9Ux7TKMh8wNvN5oV+gczj4hginznyKJhXl2/rAuqhyjJwrrx0oYKe09lqdqCrb91xJKEqq2B3Go1WtuNg+n+wIC+XlnA/oMcGZIxCuYnC69IvGUD9itPc1PFdyslTzSg8LC60ugys5nmPW+MwTMH189qTuF2TKHpbvkc2d7eaX0z58iFpsu2ACQ+Wv/A2aHhFsOebJMxq7kOdHpIi4/gpVZ+BQFxCQ9Gc0jUeFQj8fh2UCM9xe5rRJgPBmxUIyKDj/+bqvI7r8Zz39BUa4m5BS3OEnaD3W4chE5B0R84IR+gl+8iHsGv6AeSC6m02frk5IFFGf746uLktW/l812Y20cXXwrTEE3VgGkfJoYuTyXze393buuxEL6vpJBEQNEnTFPIoMDWgBZcNyZUw1M8YdD1rxzY4ZGSRuuRI6nGUhWhrL7CZvVWpWc1LpuXz+T0gobV2V/hzIxdsVvlWZvym57J1n5jp3Gw32w2Wm92W3vz8sdH4yFNK2uqmUPjg3MzAgR8xLa/OLE92NrCUUHqdWggCo+RgC5i/mJzzl3iQp+LAVNjxYUmPS4Abxsupgnta6agTbURl+9zgU1JIxmzetjGkligT+fOpmRIoUghypQyVjsapwhDGA3h7gzQ87Wi3h0G6jHC9lWo/fv7+0afK8YmDPD2e4kcbOmhYlTXFcMmhFvbzdbuVrO1pRWNbrkY1Ec0MfZIHYVTNxNyMWgM9SgpH1TNaP9tcyfaZQfb2y3zQxzRvYP9HUrjnf04nrvfuuuj0YXXoOqSOCPIZTRY56J9en7VOPntZF7+qk2m9EzNyqh8JnMbXj9fP7RP3CkMP09f5G08zX3Ae+QqlJ1hEHz09JX2XJFCN8XsC2nzOvtLaejBCJ0ALOpcsXc89NxxwxEebwVbMeiGO0LAuwZWTt246cc8viGyr5kgqaaT1MWkcSrCdcqSPqHCr67hasxRzZgH0R93/QngsgvJzePKy9k5g6oqlDfbStGJxW0H4VE1yAAQvmaEobSP10PGUi+VSaaZ64Ocq8ghI8wbeoGK+0gnRiljJgFKbKyksaagEJxrflcoN59Z0wV+YY+LrTQdbtTIRj0x/85Spsx/W82G+b/W/nRRl5FbF4AknucwTUUimBhof0S5PWPGhlSJybRnUiiACrocOKhY2wbDcGx+62XRLdOECppMUp4SKchQ3vshR8Zs82tC7o0/7ZWClrhGwatEPsJp4r8wQvlT4UfkNhyFhkSapWMecZmlvqdVeQmeYc7GrJvygaAQl475gKW6S5OBVFwPq4qRQg6NPfCIn8wbAoaewtpNLRii/ZoFw8Zpg4ynQ+K5sA0gqG/vaisXfVEdNMn2Q7oKbaPK4UkFoM5WReV941A2ObllqadDur23v6Do2QNPvwp03pMyYVTMkuk7/FPY5pb3Cc3FEvYmKL2yRp1tLki5+YmLQYX9mMx2CaKA8+4TnvpHXROl6U5k5nXN+hRcRSxZzQNFmB0fduBkeStixRJ2Z7uwtMdmV/30qQNoGOV9EclRw8zJGg/jqAE5/IuKWlOdVXe0fO02KOgAR5CU2SJ3GjSR2BUjUpOxlgNFx0MeYbfyND+jwlHvaMLjEFfKuO0qS7Wbz5jgd4xkIgfotT2F3Vfzr7jk4nx8P+w9TUkm4CqIzeipf3J5+emy++X86vJL5+rkuHv56dPVokuWARxMVbBBHRy+YIlC5g6qspUGBaY404yOKn7pzRSrfPNhPLh+g/oUuIXMr7zRqG/kL3p+BD/vhT/5/OG3399+fNv+ZVHRmhNK09F4DuE+djl0bN4nKmK8Nvc9kfzmwEPBvAh4oW9eJWjxA6dl+YjYbm636k3zv6vW9mGrebjT/H3RIwPez7muvp448TY7WrrmkqGOmPHeGzefTwGl8Rh9rPzrj33P2WTGn4ODg8UIvaSHPLcjCmkwAItUgBE3ZoaUiWvIZUw3lkzwNhoNEFRwZXN6mbMZlOKSYp5tWUC+Mh9wTZOijYFX22YzDSgXqS64HBDXmWC/uELL/5lqnRbW4is6+7lyGo2oiLsJnwuz5Z4ncUS9CltJel9Ryu+zJHFUEUMVbhRwF2wzf6vspnM2nY/nJ7W+3pSPh1uWJknubATyh9rEkheyhBcYuoCkDj0wFfGe37zLxJJ+4xvcGnyk0dCIvHBzYNXBydn7R24N3u7X5784MJz0Jpp1pYorq6N9NzGWGfszg9tP2X+c+DOudcLIiYg5ndsAMDxE46xb4TXi0cWXQjXuowycCu0jvvMRrhhs1W5wYC5yrp48aIX1Nph54bINfJtLQ+5mml+buXwS65jmRoUGldbLeKIx4RrChXEDsu2o8DidfXqLB4gNGWMrCZn3spiLf/YAsfo5OO8nVGsmWDyL/TNb3IzDsZgwxLjDmjw8FqHc+Tm0DeH2skF7VVeo/lK8kTG7K+x29Q6PpxzP7VX73enrRVgBBMaKmMC7XgR5fOw9eQ6tZpdWROox1ZTgXXJAqJ13AVKZ0GoSojGvLKXCCjWfYBWSRSjQqrM4N5oPrQ1wuH2bdEd0bk8+i+y0S3u8InK//r45yZ9xkT2QT51FJF/hEWV3ylOn1HMo/eYKb4G3z97zrurswOFWdHa4HpNzECdY4HWWGoXB5YC7/rI1CfgCI0wbjYauoWV53YP4AzMLZf28vDjDhl7tVRUA5pqhEQfEIYf0JiTNevWpZrSQUimYsepvQo4bP9087/X2X4yGfHsxBVqAgZlKfOb19M/MRlJ6tMcTricQole8l4Vis3QstMxwBMjxPBk4zyK/M6RCSEHs8CSiSWTb5eam3VKE9xNa2bWg2YgduzfhLYPJFqOzwqyAEplhfeHzqHTI/13Z76esqhv/EsE425IkL54SComecxHqOyOEBTfPo7fCM7RErhlqMSrvuNIZTboWf3XVdmGJUjufw3tdjugqkoMfpXiBnTCAcNA3Olphsr/7aEWOFzha7RefYY4s+uJYyTmB+U21EL0Vv+RTtD7/NR9SxeJuwnsKEgIrItVZpjgd8dPhNRKkCPA0YOhZPGiW9CvMyXTDk3Qy6kmbumheq+d7JWKpaiTXMySIVRP4+qzLpNZ+vblX3965ar49bO4d7uw23u7tzH+hhKgpFV4/Po40MuvOkU01e0AthjeR0GYXbkR6AcwLVslhA/E0BAb0o8o+uQdQ6UJ9NxToQJ8lR0g9v7/78uX0uEY6k3QkhUv+Iz9/OT1O87pv6BPsknhh5gxYTSb+rhR7p/mmsnBNWub6SIpUqyyCWzRqc+qSiR0ulBygZEdyZKgaKxppHkEp4IhrPgiv5S9Oj4liWQpw/fcsSaDsN7jEpU6akd9hEhAW+YjVCI2UTNNpcBvi2pwY6clUz7hji7aj3b29+KB/cLDzZm/uUtL8cmV1u/AbI0e0pxIEiy9vkCA4JbHwemdKJnxWs7/npfBdwc0V13hbXczky9uCwbbSTI1cU0ZAMWvMahCfGwu0h7YCjOnRO/PJ3FtuEdGgGjHMrDX/wKXcjBLC1s6bebeOeQEbo3ivIvX18XgPpyhPmg49xuKqZ+18aLeemDZPjqtg4u29/Sem3mvNE+9YcOq91vajU6cxY/NkcSw0def45OQimHqOffddw9xsuiMNwwb++x05YpAyQyJbao+15zYrSpGUj3gyqwBwWnuNqTIqZJ3A/bwE7nkqM3LJrlO8v2WKtxX8OtP7b8v0nr0C31HC92wG1nnf1eV9PyLxdfr3i0//fmTlfpws8NkMrpPBV5cM/oiEf7Sc8EfYXKeGV5QaPlve6wzxr4lrnSj+HSSK29X6cfLFA4a+97TxgJXvMns8pP8fnEQeiOGl5pIHJP4gKeVljl58ZnmZ5JeeYF6m+HvIMy9T/T2lm8+g/jvNOi9z8sKTz8sEv/Qc9IDil5qKHpC4zkhfVGLfW2L6LBa+p/z0WfS/4DT1WeS+2Gz1WcR+H0nrT1L+cnPXZ5H9YlPYZxH7vWSyP0X7y01oL1C9zmtfTGLfQ3r7LLJfcJZ7SO53nuwesPLd5Lw7mr+f1HdP8ToDfp0B/zdnwLu9+FIT4avJdX+OYNbZ8PNL65smxT+TrG+XNv98wr5hYv3zifuGqffPJe6lJedb4l5gjv43SsOfX0Zj9i3u+avuJpMz8w/pK5Mz/ON2mMl5/NF7zeScrrvOrLvOzLNPfvj+M57Tf2InmrIcBnOFJ54VDT7NvWrLLzRpCSrqbOKv8+x6zIxvvOjnGmLjaepLyfrP69ro292U1mB3e3f7mcSB2zWHcJ8Vs7JZpNVFrUBBxY3Vb4srGJicHq9CtpbKCvWTJTe8UfQE4+z15nOJ5vplx1+83wCUTkUmzA6Ez2sYkkNHwtfr0dTvUZAZOQpyG33p3qEfsh/0H6ekp+R9yhRJmQZtxrUlwkWB7lkP28fCaS10MiFyzESQRT7vKmRjQ/nzdnfRcWSRFHFRhQ2pUWNMkGxc2i2tne3nGmz3UhljoBtzxSIt1QrdjtXvGrM5LMHEEzxd+jstlK2hHLEtmvCIzS2bH8Oj/Oe4kj+0D/kPcB7XXiNZe41Pb5Af3l38x/uJL9FB9MR9e/fPTf2SnDtvvv2NrtsUDS/BMfMkvUC364k378fxyZxU/j6Py1Hw0v2p+bfDCpwtR51iA55qKwvbj/oy/OzxhtTvgV2CDaTB3rKHjR/A7AR0Fyw5yP5i7ZqhwDLMTl65JfrJFUrBLOReca2ZbYPdoynb3yVMRDI2RlX+Cr6XyjOuyozXSJpFQ/MWdpj+xZh/Jw9QuHLJBp8zpib2s1oRjABaXadj3PEyT8eCYjRM0bpJxl3z2U3DI2jIsTU2e5l2JkOArMS0s3rvmHIVFoAckWez+rp9owcuT37uvjs9b1/+J3LOYmfBluzJ3z+/y9pHzfYvn99dtdvtNvyO//xrXjsDlhhPoK9BLk1V8BcX8ghhCbBq1yyjeVFwXFcv5IVy4RmmKaEuWXjWN0H+di3cQjdg+VMuBkEal33ebwaYkrwywuz8XgOhnvx20T4/7nZ+f43rHib7eBq4zp0bKZgd105p68Ah681OCBvVjP7xy9nVKcwFY7vhkoT0cirvqOJQkZkATBsOK7IRUzwCXvOda8Y8/vXT5TFu3JOfu5/NbwXSg10WbCKPHxSziI9oQhSz+dLoc71ijQG52Wht3MxITdr8Y+Po8Fppeq1Y3NV6fN3j4no0oeNxgz2wZ8DawcYqZxevBtVHUxFTFRfXG49Rqy0cTkY6zSFuiXm5GPK7Khho93qK3XFYL3A8XJTLzFc6Rj78++zjvATfskkF9H7gd6wOpw6/s1mCsg+p+SViO5/eX/3avjy5zp0ip6rPr66P0GKxhY/XpyNjxrznCSMnkGZoNugnmDS9vufCEGr23dxeE9XDCtgHZBEzdggcYpaqZoaDNxR09KyFu15aIP41nyGY62PWywaDoDLuKxIK6VyliM4D9xnBCe1ZXtog81GcG0ug1Yq2Uv7R46bSZoBvmTJtjuoRs8hUfRqZg5hqRsb8TmKWspKZiAklY84A68PRZ/SYO7sA4wUegEMgRIOzcbDUmMYAfyQmZJxQ8yQX5oQ5OerYzFNyFZJgh8YIk6HE6oJRjaQaglTudJJ9AJ+BKdAmsGcjV4HxkvuSFptPkBsrxcaN56RtFGSkmPbZ5UZCpxeu5omlLsTmAnwiZgqSpGtE9lKm7piquVT1fEdom2RbI1HCmdA14h41b4lg2hjRjb5U91TFLO7ycYOc9slEZoSOx8zi65xeOL2tZU49H9/U4ElDkjbmAgoNJEbJgN8xYVjQit9xmiSTGhHSWP7GBLsfMr/NuYbJKAQSe5Mc7TSY6rB1sN1oNrYbrT1XGbSMKV1hOLedJHh20HTIUtweUhhBKbfhrMWFeEfutaiBDL12yVJ0NgE5LperHdWIfMiSsdlOKdeZDcqCVM1Um8pskRRQ0oa0iFwFYdgc45Sn5BUigTHF+hK+YTaaUaVwGHoC5kcDgeT9CuVrxscCeB+yNh8FlQyzBX+C75YXR/g8HiWMvP98fJ7WSCxHlAsss6+Br5lai81+ZDZ5wmn6jNp7Pk8Sr3+oxLXV56cXM5krxhrSykCY3P4G/KupRYDPZi2Cz83/iqz8OZPZVXKHjPv9iRPGPGNfdii7cXcgDuoN4kG2JgVLZcTE604inbzowDhOhgBb6OiKdghNmNIBt0IioAswlntUdpPBFEEBkR0Nr0icf4CuVEC43YWHTjc7ouIRT+HqyxjSSibmMNPmuEtr7lFDGLwFp8edrdOLTv6HPlfsniaJ2cis54YMkEaCBzKVWJS0tEaYiBH7JWbaFrYaVYFHW8rIq5Pjy9ckhVi6L1xiOlqBhqaZHsqq9rAxj8wbPKCC/2UPSKnIOGVZLMVk5F41JAJedfjJaFiJiFQsLihVWEO34/yOAe1e2Peha9fRVNXPpIqf4cdFVLPBSiN3xZfbTWDFYo1HO1RQeMlsZxt7TjkReJmYsyrfNK7GbrYo2lqz0dg4X6eBBXfG6O3c3m3lF+xX4MGX7tZh2e1yOznMZvJdIqNbotifGUs1WIrjrJfwiByfd7Ay7sPV1UWHbJGrsw5gE8pIJuncR0tV5ZVt5PH0GNUXT13V4D3XQ6z4JmkkEebH2MYDMDO9TZrHb5zanLlxnrVhWs3WvHJJeMREWtUlTOhm2ZmsZY421NOawYsGq9aMS0RjRugd5cnMAr/2mEZDRrYbc6fcVXoBxQq3tMAnhAIdhOp878XZp6N/d4/PO13zEnSvzjrz8qYYXNxEVTG4eekmIF8uz8zq0a8hj4dr7Vd35mng/2rEaIY3Fj2etTbAinDPm5spiWWU5fXKxdnAXTNv5uZmvp+E1PkuqhknIkRYpCTh4hb4wbQLJDDBSywUQc/5JvkhZ5G8wAgqRypd3gYTjXt+y8cs5rQh1WDL/La10PIaC6wy7JnzqZ2bMl0jY5nwaFJDiwUtAkhE9KeucbfgzX7W2Y8lryM26uVQYnmAzgZPuxdW5Xffo/U1r5yy7IXofojrSOWzGLyM4EhI8zMBnafgMEBMh68fB0WFWT4WWs0m/v+8sqs2be0K3mLMWNsiit3xdNp06DHDNewdiJrYTi5l1hpf4cknZICEQ9epk3/yhPPUts+ZRXaQLTS1Nz0QyDJ/E4R6pyKSQtjl6XtDHV0hotiAKgjLpgzclrQWPI/r3+N4cYv6tJ/Ie7iXU3HuSb2XilwdXdhRaxY6zJGJtEWM3+UZNFxwzWlCOv95TsY0umX6VeoQE+2gZsCcFrz0wb3oja7pmayCTCYlefyPXAs4uUCiHLWDQ4TS+keERjpD3IWUWWR/NSIbfrwNoz/gVAuGdVSIKcJThPy3f7beo1XeRotrypM0PyzsiEgKYLeLgVvgfIqQDxsy6RQmQL8auLAjBjDn4Jz+dyZwU8DFF0Yd7bdnDZaLVkhdGrIPKtgsI2YjTrvaRzj8lmOheLeGYTIaxyRlIyo0j/Aa6gHOWCoIe8BUxVpBqfMUQmv9LDGP3XHDLv+L5TfQhlGmNC3E3lzcVPk5+sahdmMKVKHuIMHAqb3yTDVPEsIwXIfYShAxAF87COKCwPo8SbxuouOxkmPFqWa+pcNSTvfciF4LGVTwNuCRaBfMh7cLWFF01OODTGZpMsFdDt/x2h/ucVNfxJ3wVJvVPL2oEeridhCCzgR/IKk0+6dByH/mEqfJPZ2kGNAvHuX03tHk3oebhv3gBkVWtN2Esa7yq+s4c+0VIFTe4OMbQ8pNA8m6qZGYjRncChBpbQkiRRCRNMfsVOIQTRsFvMVFcocsSA6OQ2iSSE+lDXRIIUcyS62KQLnnH3sCrQaxA71qd85fl2BpIMmYRsM8MoWixCxPNuPk3mvtH0zzHIZnXiLWwPzZSp8CTmZn7P0s5SBh5OzsqCCFGck+8+R2Popg+A7SegBKJcDihDfRbgRU2OUFertbDLjAdv4KZQvlEiA1OH4xpj1gshFxPamqOdER15PZq/NRCq0YTcrkSKG5YGIWds5KaLq6l/UEk5YA58YfcC6nAmbfTGfTfd6e1xAuMlORgM8LXZ/sZGWipdJD0oYsHDqDyExoNenyVFYl8yOcgpx2PoHQSxQetR8lq6qtaUmaucpHVNC4LCnQ8CXnpkTOgMluCCBfROCTYsB1FqMpklANv5Rj2f+XbCRSbByS+pudxn5r9+1Os0Y2Eqo3DsnuXmOvuXfQekv+32aJyArjU5tfUqbqzqSYit1S4sRTIxSjKWhgyj4ZKCqyhKqwv5sesgmJAMzNWNQFbDV79OtiPIwrNBYjJvAuBSoZEokpZj2mckQsZ7XnhyySl+QAsxgzrZHI6agwge9cApSjeRCdC7DFzdk9gjN+wKTjthy46clUS1GPo9LajGWqaVLVW7Z5AcOjWqNpKiNezJfzJBdaXmXGVMytXpud4VNLRnTi41y3Qt4LyGkkhhUEJVPk99MLEvBEYGuDSXlH1YTc89hYMnA82rcaLhHxx7L8Dnabu3OHY41YFRtwKapUYJcww1P6q/756DG6KtJglqaZCuxzxnqsvP+Mdf+XnO5mtZpj1ZWdmPF9AN9rBJf1edo+bwfPzSTeHlRbbTWAY5luvcuYkGm3zRWb//pm/BUuZ2cF5AlCOTI82E+vTi/uds1uP724239dtKNGNKriff7YPppNzFSwW0gbyEZrFd+0y/dH5E1zdxtQOLPBANCMD8mJcSJkpJkmr2wIskbe1ns8t8GNrfsaex1a08heUd5L8kc2HjMV0ZT9FxmyB+pScKHbW0oG/M7FHMM8POLIx4kxKToTtmcvF5oNmGqQThZFLE35nX0QXdiUjaly3fKoH3E4GQ/ZDO3bbNabzfreCfx7p769U1gpQXVjiZyRzStFRWqDM1BXFgYTetQcFOftKx+js7iJ3Hpp+eEnyVjxO6Nujz/+/jpYzuKhA6o7kTQmPZpQEcGxF6QWSEWUzMxpOOXgGj7Hcq5CsmcVbIUCgGrZlysCjHI9w9crluzhtxfy7IqFa+VlWLKY0Io9VAeETFffMMXi7iyfcsUNvvlgyFIdTOpkhHPXgJHxmMWe5KznXFG/5O/z8rBaUAoBw9nok7FKNvpSNuxzjUiONoyS2gg/eLyLOEZwASMV4AlZxFNjldgW4BDxSvitLZvEPII06/f5gx8Rnnk11Hp8uLWFj+ATDakGrxvkClMstURz6oGP/KVVb0JSPhonE6Lpbb6uGCFLaKpBuSa0x5IULSchNaTIIRKw4f7q7Dj15+hGJBvZ7UZZ/QXSKOwKL/Yqd4OfBDa9dwz6mXmb/8xoglDQQSKgy84KDPU8LQ9T4dhDxMboUEAuFnwNUwKKW8Vu9wYhp8JYqFRpHoTVSYkCUB62Xan5f/t3m8HlvRdwM7LEVohHVORxdVLcV7VAArY1QFpmqMcSeT97m89+J4rvTSjbjfv7+wajqW6MJnYE3Bj4ZtBUb+TdzE9tY1YcZUhzsGjkFct+3DS5zbaRZr3tRpr1WoWXr1bYxDl5BaBhK4VgjI0avnNCEq0oT8wrM2aKyxltWw0D89p7Wo67wMY30Hqs32fQq9fMajeK5f4Vuzo7fl1Dl8n7S7ncvdBQddTctRsoAbNl3V4JXpJGWUFOz+uHDSptzSrBPvi+NSNoxceUYr4S86lH+Lywb7KUqUa1WyaM0uWltT7jN8hlILL/2LFIBTk7bl8YldVGjo/9UOFe2Sxzx0aUJxUx98VwABMUm8kUCDDac8UYHt/4vsGwuZnmxwCEmp5IK0t6TGlywkWqmd1YBYnAZeLftu0wn6TyfYdMVpZL83iXCpsvY9Np4Hpty2V3z9ieSGeFgdNwJXCyMhFVwiFZSYG2gVoVCL8prAUqJN5hoRGqJUGokGIy4n8FmdkoQv/rl5T1s8S8DDfABY/xdhZ+MdzdeBMgkqKPazWd7CfiGVaVcf5mbaqvIrOsZivZ1YIpp9/uTr1V36tvt+rbze3d7d2D1vabt2/q2/sH27vbB7vN3fr2zl7rYG//zdv9eqvZbJaZWF1I8Bvrwc7QeJ/CoroncsDFk6KiDfaoDlQyqQx3oe3qCWErw0zuVgKij5bmRwsJbnmPCtql8YiLjRrZUAysbjHomgG/Wl0Q5o45IMIgecx99GRxJ3PfLqUi6fBvWEwBEYo8Qzpou3xPUxLJJGERAADZT6+gq5gdGMreJjIjfS5ifB29ckjkILVawXefcXNDWTBm49k3tS+lFlKzQzKD/hGdYAFp0q9jczXrxtnnLOZX4yeEj7AfIkpi4yeSJwB7QeAXDP8WS9F+yWeauMQhKGWN5AiSRBSRmR5IhFPA4oEagRw0NCWTidsRH+Q9g9JO7RqopBgTmofeUWacVakNz0b3GYXm1sSY1ugBSqmn5MR0nhtqM2ALK485b4WtZbu+2XRQvOPJm76kuWByks1iGDXgoe2KErPDhnLzhRZS+azEadosahsiXFiuXHImfr2Rb8Aydflaf4U8M2hpER3N6jHq7CZ5krIXnOvVtlcBWJIKV6EuGZH7TVl830EvTLt+ASwI+XJ5mhe1ubuGV3x8t3uI4V1F/uDju/3/gl9fYxKYYphN54cFvIRXmBaWzuoH9Ga7sb3faDa2D/d2d+aGZGbijispRmyuXuwLyfQ0T6/CCiw/oxVzqGt5SlQmRBGqx0ZVABbLPagyASrII2GFA6fklYXkw5sxTQdcDGrkc7sWHMd3LJHjERT+MB01XtdK9Bnf3fcGw3Rbc9RSB+DiqMojDvYty8G60E72StOosaCGMQ3i3oa7YPLyEucszb264yEbMUWTChvZnbg5SqZd8Ma84n2AwmEPPDXbd+p14TERxlZNkonF4UxdszXFAFgvxU52N07AxgiOJUuN9i9L6i3d7e81m/2CMCqxamf08fOZ8rCN8y1x2p/e6ZEcjRVPA9Nf9hH0QciY2eyLAsu5XvFbBgwHCNzELJ0hWPuVUhO+kBiLRDWit+Zc12Qs05T3ECzO2yl5KMrYK2Yjj5hWPELbBYCOpqyXInSCMZwgYBxlCVVArx+SjbiGxM7cYPR/O5faJhhzxHgQDI/slLH8C/ZNKpABsWxZEHv+/gepzFg5jM4s1eTGfM96VsbRgl+N9MHMpjOCqPHOG7bHen3WpGw/2j14sx332EG/2XqzS1v7O296vbfbu2/6+4X9WFHOQiEm4TYbZoA/eWoV6+KCXerfTLDzASDD7heaJPIel9/3ew82s1d6IFWVQU29j4cD2kLRS0ZLweXlOz0L9535GyJ8mD88IazpQlPg4CShqeaRRaAovEXOYQ4j53jRmKXaJyuTICj8jlGdzhoEQ6tWCUMHyrFH8/OPmoW8yV17RFPpmxcD72aC/p0zgvMhH3X7uhU3kYxZpflobjdRvyVgyik9E+wEfS9RF4UHZHhsC5tG7v8Gr2lQehjiW0J6FRjaCPNRCxbBse7VYp5O1nNdR/2g9jjxlDmoFzfafHtpSiUHJJR31BQB5llc86AOrbhR7R5sGBLM9OkMA8kcemJzMw8rAKS1tdvhFg+Y87PVpm71pHJEWiCMEHw7j2RIeKO5GGQ8HfpVy19KeKXNeUGyceGot+ecTA2pJAw4WVxDKxcBVjDkLXiVULatZu6aXMG43fOa1FEreBlbpkZUYPFSymaYCW6+etP+0ypqaOvJrX2O1focVqxr1+NHdj3cIq89kOeIa+2jrH2Ul+CjzL9j117M2otZ2It5xjZb+zlrP2ft56zWz5n/9UsDkNmVlggicjGB8aekMTdApaWxIpxwuCZ2OELPPo3gi1PtrdAun3EHXLBXvKVQuIREToJJTtwin/ZxEKn8GFSxKeqm3/JHFPy9s+BuCrr75iu6/ZkLNhPHZjVr9kux5ZpbMndvP4c3bTW9liSR8pZQczQiLibTeG06dWMfdHnzZ0hZXjuN7cbc7Qb/vrfOp7fgbfE6ArLaCIgV6zoC8iNHQNwiryMgzxHXOgKyjoB8JxEQu2PXEZB1BKTKCIjbZusIyDoCso6AfPMIiH39XnQExNK4joB8LxEQu2DrCMjX5LTe0S9hRz+JPP0P2a8+KJdHiFy5Uf7JE9VG+JQr1HHtfUqQxyRlWGfSD1CrHeTvFgKuBAUeaaF5UIBBbDYGLcIi1yxeSwhkDrC21kwIwVCQqgIRIUR03ssuZCrAWf4KwnKIZ2NhlnOeHgMSDmaJpEh5DKgORmbGtUi4YGFTXETLtaP2HAQx1BSLIt/pYxM6MRSF6fZ6iJh9GtS6YejJj+1iDhbywiFJIga0q2ryDguU0WFTtdnPOSl4LhE2zov7+8JTtnJf4ymv8ZTXeMp/K54yvomuZXmuBP9GUGUkaQ2qvAZVXoMqr0GV16DKa1DlNajyGlR5Dao8L6gy2k8vBFQZiFmDKr8YUGW7O74CJmy0MkQg8uNPepzhmYDCQa8vohWFGJsYvHiA5UfF0VhSHi8QYHl+V+8boixb/UBeEspy6ICuUZbXKMtrlOU1yvIaZXmNsrxGWV6jLK+MiDXK8hpleY2yvEZZXqMsr1GWZ9D5QlCW9VAxilK2WU9X+SePZz1tvMdsFfOaJjRNeX/iCkGgGCthyvwYRRIb7xvDys5FNH2QQo4m15bCa28UGYY/nl5dnpD21dX/Ovr39UP7hPQVHTFjUzWuRSkxymgDw2+BknxgSwfm+XgvhysbAnAxsdPjTo2c//z+V1uz5vK7KYnkaGS0tCW5kQ8N8WVgqKFppHnU+CkkbMSogMbuLiFM21iENYpd63Ui+/mY2o9pCbve4KMxjfT1xutGYUYWDUEhPD1pPjKmotxyAVEOsHFpNPQ4yb2Ju6bSmIeH89Rg3aJIjsYJT+HOJh9yIGniyWQihhtGEjNhtKfx0zDxzpC+8T/IkqlLTCgeDaEKcY73ERGyZ7516AkYGeT3UVzExqWWKiWy998s0qmdz4WObZYdFXHB+A8AlSFy7YbkUmzlBM+d7B3w2PAkzcEt0jyL20/wlyAN8BGuZ3C7HNWNf1JS0zJCeulZUMslOi0sGWeJRVXZuxt5/fR116i17h0TsVR1wTKt4M7aUXDdVQDKft3NUvhPoAWNHjyXgm2dyfutjyzm2WjrAx8Mr7tpRJM85ZEL0h5DZuADabujvXN1+hvZbrTCEy4Y9xckyGc15xQRGNw3BaBxzGJzfEZZquXI5d1ei5OHMWjzcNQ7e7+u2OG1IOQnyCzouAo395Fg+NOZvMcfkDf82TC4Mb3y+MByqx6sUEXLfuzSMPCotYUCmOxrBBxnkbtbzA/baVZPL8hDA/4PktexcQDknyT8jimnRttikDBFTv69pCqF0EXFSA0BmoA30zwF9nq0EEIhr7jKuz74/SX71o/nUrwuCW485Onw/0zH/xcWTJ8nrEHhhpbN48HHeaFX0fk8g+sNY3RDIJ0niEnhhp5ZDC2kBovSPI3nS0puGRsTrWh0i7vKfB3GbXzFGJ+PU20LeKuD63AuCYggny8QQNt/aK8K8qya3oT4CAb5wBTb3EyhjFHU2cOQZimEZpz5hXooMKeM/aQYYVZnYX62S/o5JFRFQ37Hali1D+tSy2NGNcJEpCZjzeI86M8eWJRpViNDHsdM1IhiNMZ/m2OuZu2CGrlXXM8oENn8Y8M9axwsfPqrjtVcaxnJmHVTPhDUmOmNmA9Yqrs0GUjF9XBU1QLDfShNwdLzk/lSJ0MPhtCVjCBM6kU5FZAPC0s9F1Dqanwm2D08JTabwl/hQD5/HkCZBKXF5kkFIBQ2pp8DkKBscnLL65QO6fbe3GWf868K4ml8JQjSkzJhVMwS9zv8U+gEcqhIcjMYIdmElrKHb9yhCraa+YmLQYWYJWaTBWGqeXdX0LKngJER4LpALXCfRoYRTL4hqezre6M30HxrBGMyV8yfEsUSdmdd4/bY7MWfPnWgdGzW/cuoYeZkjYdx1Bgr+TCpYBU01VmVsEvc/DgdxfSlaBFTtnKJESRl9mr0M7zDSuRgANnoRsXKgaLjIY8IU8o4jz6bMxz1jiY8DrNrpTIOfqrdfOSM0TtGMhHUk/VdnhZ8Nf+KyyfPx/fDmnM6E9GQRbez8BlOLi8/XXa/nF9dfulcnRx3Lz99uqpgNTPws6vKq+zg8AX4D8h0RbVZssR5pKR5L8iRVGOp6LMay8zNtGZ0VLEWMVOsUpXAeFJZXWHLQ50CsThQQe8vP+gzNcjJ5w+//f7249v2LxVI3Zyhmo7myRh8zN49Ni8oFTGavPe+ItFtKTybzJs1YIJhpiPUKcJ5Xj6ptpvbrXrT/O+qtX3Yah7uNH+v4OQCXTCXof/EmbzZ0VI59y/QRzN0DImGxXyXX4xiwv5s+dcf+55zzjF2CoGrGgp9yHMjqJCJ4nq25RrR2EhSJharg9oOewTUHVpPqEzLpmtF1gPo5iVXYLZZhFfAA65pUjSQjEcNGVF0QLlIg7DVkJEeF8b1gEBsAbVq5ulCC8v0laNjdSI03vRyDup7Y1HDOOYcB49yXp8UimBxixa+vxLOzEgrdrxzr9OCI1AssYEy+dmuuAO1s3FhGMbuCHRPs7GhgNyMzFQ3FhuLm/eSpeQGuAjgFMw3IKr236Bv3KUcOCrm0RpJuYj8cJCkIHK6fT6ekdAqpByzAFJi9QExi8aATTODNOKQjZLHFdNVMOa896p481kgOQaT803tXUKDnPr6bpvniZpIhVEtrM6sWf82r0wqyWVrKEdsiyb5ei0lH0NEFydfVkQzX79jBREZZhECH5XRVV58xVM8ppw9lNv3gvzKRSzv06laEIwa5DX0vl4Dj0Ojs0LJRzKZVcK25H0CyJMl/QaEkTQDF7KibfeRRkOArAimcm/Tydn72W/Uw9v9+v7c6DlfYbI30awrVbz8tnmExXcT4ziyPzO4jZD9x/k641onjJyImNNVOCGGvWicdcv4QStj7ujiSwFC6FHeToVmyap4sodzNy6hkT3rSD150IpC/BSUlUcS9UUiZsbN1B+sDXKKxNjwXe7zaDCQehlPNCLOjcY8sRozcji8PUb69BYt1RFNwJECVqRKl7z28KJhD2Op5rr27ydUayZm3/yf2cAzDsdiwhIGcMQYxwbTfDJmKyN7yGjMVIP2eHcmutLK9usUwJLZru0gZvYOTWS4x+7TiJFX7Xenr1fMJWTeVMTfB5gCk3seeydXxEbQ+n3lxoixYjU172LAg513tVwwodUkrPdfWYGdXYp8gorXAzNbKn5/NjeaD60NRFHGFuyJ5yddiQUfcpR2aY9XxMnXX3u3XmdcZA/kU2fF61XhqWy33lMH84qY+ObaerVKgI9WelzicNUfl6mtLZ6D7sez+zbbglC4xA5T3oTNkMNyHBoNiZ2svJEKnsstm9jIW+692Os6ix6WMp8wGAKc9SYkzXp1zMPxQ0JBoGBUD8lNyHHjp5uVaRk/ZjTk24tp/0LaXtEwHvJ6+mdmg+U92uMJ15McWbyA8hiFhccrY8ucPHI8T8DgWZx1hlQIKYgdnkQ0ibLE1hv48uqKeOondFCV7WR2dsdudnijYbKVs1BhYUqJgzDvcGUMOBCeruz3U1ZV05YSLzhbddyk/K951uU5GHMlHjx+kZls5axUaFGUOEGw3hUzcMeVzmjSnT9/71kWeYkJO1+x1LECfhbfWgsws9qtNVi+jGB+QwMm+7sNDeR4tYaGHfMZdtuiL6kVqpOl34qrZqViXTPFxkq1zZAqFncT3lNU8coSRJ1PgNMRP12xhijndVXsaZb0Kyw+dcOTdDLqyQTrT80rvFIH01BbZRQD7oj9LDXCHqIki12yQsIo/BzL2b2dfBYIXP5AplEBfsMPnJJXLoFbU9UY/PW6BjdCfkyPigB4+F6f2av+mLzaGPy1UYN7nw0cYWNG/71xcEIsLvS+VLcrruqfOgbMPrmFK+A85w77HE7BHdLgVt6/Hl5onwSGZGpBr0I/tE97gqv86YlKo/tB7SykbW/WERXbLCvVZkPYNYJpXF06DGnhW/CCLp/PD2y+gdUnkCJb5OP86n2nhpoAbsZpIgcyg9t5Kkg7AbQtzTAg2tGK0RF51T7uvHbpMcwtuR8Vwf7xUSz/dleU/52l2nhrCYvJ/zxuX7Ub5HcpWOM0TxrDRm8juLUsNMjpTdyNJWQOQNq+TRtISSzvRSJp7BD3C6VgpC1I+7gDF+YODyyXur03l2p0SG6ODq/HVA+vtbw2NIPz4t+lw1SOWNdv0huUwM3Up35kez+PF6qhueCSXMhN/q0GuSlP6Nos+SGDb5r3JaSi9KXph/MHIGcu3x1ZkkB/zZp90Px8U8PEivCqFzZegMwQvP7hIgYu++KaYFBZpuKF4iOqJhbR4fSYvPr59Pj1k+kTm61ms7UKSyyvpa2arzD3dCZPq0p6MIdvYxTvVcTVx+M9ON9XcaTDOOmQtiqitfOh3Vo5sXmlRAXkbu/tr5zgvdY8gcwFCd5rba+Y4DRmrKpXstM5Pjm5WBnBXJSwiVdXUChKUPZ5alFuadrC7ZKC3N7b33m7swoVOeIjVmW2yMfTjyd4K+XSyMKMc4t/GyhOIpUzZWS/EGYjBOqLyVDrcXq4tXV/f9/gVNCGVIMtmqZ8gF2Yt0Ys5rQOty/hz42HoR4lf5y2fUsAY4z0ecRpgnc1/1WzWV4uLaRBfjV2/whTRKkAexCY4akrvOlZQDc/5kimOu+1FLLuMHFWsWzVbc2PABLeL+xHGWma5Nt1NmrqZnN/t7mSPblk3uyMtFmf72qcNhlju9IVkPqNIKfsOoQea+DKGhfHlS75pNHS8ji3dDWuo7wXlaXPgasOE2yCd6dmYimsyqIy5vfqGFk9qsR75y+ECdy1qd3gwxIzMnYLoYc4yGl9Xsbu1mo30Jh9i2TTo4svxURTbEDp/fnZyaYryTQdQwn/mIqq8rdPPTI3TlNyQmquIS0k6dsMxTqWR0yxXFVR3Jh9A9QKL4ipDicLyOGChm1gluLb/Lfi1CzP+F0xa+aZTO83dhoH+81mo/Vmt7W3Gu75aFwlHmIbo9CWX5vTA4CH5OIE32rSFsRSQep1AIqGx0hAFzF/mepo2udiwNRYcaGxfgqgj+6MouxrpohiKEzb1tB1lIxkzOrAZ65vFRWpry9OsY+1jKJMKRbXLOYYtifFGh1raSrqQ5hAPWJBFKu3lDVLqS4YxH2uGJuA5tnqJXKwhWAldWO3GT24td1s7W41W1sQz+NiULdpyXUUTt3CHzSMrTyjV0O0/7a5E+2yg+3tlvkhjujewf4OpfHOfhz3V7N3XJphF16hCk0s//4sozk7F+3T86vGyW8nq+HeFtpWzbKdZhnWN/ypAUCENloMP38aM0SFIh2EBVmBbJ5/pT7jBsgMYvQEeJaFyHxQtYN2EUZnzaBQxLZhfp0BSN3a33m7CnsBLZPuSzdHr9CAAoPUWFHpZJRwcbuS6+YK4xCw+OCMv8JdHnMF3QMs/WU0JvPYCnjKKousXzn48dNj8uoLBNUVSVmUKa4nIS7Aq85UxB2dq+ri7g97zYMGtVdZ/A51eOW37hYGIpjXJuO+6rTPXzfQoYZAjwdkmgWZQTM9lCBCgDUOKqJh+/QynV+YOWTkvAkVS2vk+LxDQo4JeWUbrMURVXFqr/IKgGF5pnC+HD81bEfyRiRXtiw8TTOmGshClYerWxcLEQvnzKujc9iIhggATAmk6+VeEoRtCw8RdEDXI+00zRQVESMdbA59NHebz7nlA83uKpcNdtd7dfQaDMh0mvUvnRXzFUBTsbjK5T8OJ7Krf7zI6h/960unRj79y+2CUxHVyKcv/4LGKTlWXo0cnf/riZ3i38Wqdgy0q8whfaraMm4ap9vOXpcsUrOpjFb6hbP7FTMZ4rFWzGg4VUpefVpCcZyKqEI50KSbCV6VwT5LHDQhZkYjlS8LiGXqzVmxaFJNoby6C35EdRC1/tw38xnTx83nT/2rGumAjXdRekeOaML7Ugm+CqAG4F5I3YUAwRzsPnZxccVH4NFjZGAaN4enREhwbyDcIFIeQ+MpAJ0pLfJ2c7tZb76pt/ZJc+ewtXe4c/D/NZuHzbkbtc7DcI/15Vyx24U57nOV6nm4bR3Um2+B29bhbvNwe2+13GJPpO4tm1QOQ9kuIU86nKmwgdMtK7/Yl52VHWoBv1Gm7qp6iY0PA+MHObKMsCQxD0T2TznHAcwloG74Q52nAWCnu3wtyUfwVI/3tlsVCIk9jKVgzy0pnsImwCH8sscMLmumFt1juM3B8P7e3s4btyAiZg9TjUFk1MXg4nTDkNUJZsmoDTQl5H/5EFWwF9IxjTCWw3XZe9pu7r5dFTspU5wm3bkR+5doYINTOSx+OFL9azH7dIdmT6AgU81ENMkBfl1zdcyIhB0zHlKRQbvmGuFhPQWGqV06rgQnNzGGl/FUPSaNHzoaUsDRUGXB7+29f/fu4OjN8cm7982Dt82D49b20VF7ZZrJo59VrohPi32pCqigHoIt0Ei/MrwcGDEjszTshYcmSV9mApCbf5bkjIoBOQLAUFspMGmQDmM+nD/gepj1IJI/kAkVg62B3Oolsrc1kK1Ga3crVdEWIo5uGcHAvxoD+R9nOztv6mc7ezvltkeQglZf4TFhgy5/Tzgh9fEER8Y0w1iJ0RgkskcTb/MKtoorvin+/45wQXXRAsfXSwgXlBB5baDPvJyPxgs6V//KbfwaOftXhwryXlER8TSSQTyhZrzDBkQPvtlueTGhgoJQVs3l3x0reEwpFBa+SqZfQGBgSgYrY/Mf6uTbPItqLcEAAsVMak2z0jbeWZYplepuytg87+aj7juWRE3DJXOhjQs3wGY8tloLHHnswscALHmoi92CjVfjyZvmdhPiGa1Wvbl31XpzuL13uPum0WwujaQ8YLIRcT2pCpz8yOnfcuKAFFoxuiRCHtAvhebGc+xGpbTglTBxdS/rFgYzKuWt+9k309mMni9pbRZZrGidzgvg8XayMitS6SFpgwO1pFJBrsCe6/JUVrV0R9ZkPO18grUrm0srWR3ko6p3yPIwc3cdUUGXhds1PACaa8lSKdE/YLIbYscVTyspBlxnMerDhGr4pazL/i/ZSKTYOCT1NzuN/dbu251mjWwkVG8ckt29xl5z76D1lvy/Fai2Kot7v6RM1R3UwlTqJSVOnjUHEI19PWWfDBQVWUJV2P5CD9mERNT40z2ZhSWzRy5CYcYIkpW4wrrXiAnNVIpN9fuJlMoGT2o+/hG7rmZ+UCQvycFZ0Jeokciby8Uy8LyQFaNzXEAjxREUMA+YdNyW04N6MtVS1OMlb6DMYo5lqmlSlabYvIDhUcNPl2fDAjoeC5D/0C0vzyC3mdUeEHlEJx4K9VbIewHd0ohhBSaSivx+ehF6s4TYZAnbN+uexyyZYJmxc4Ch+zX8WBb4wW5zd8mwvxG2YgNj6VWomi9hhqc0c/3zkrjOASMV6WbLxEzV/DljPbaCfW8My7+kqMSyce2kzfju/M9Vl2u8fNo+bwfPzeTWWgVbbTUAy4huvcuYkGm3zVWAFbWQFPg8JZP+oWe3LszTl4p9C4ns+5fyib6FrcZ2Y6exZA5kQr+pOwIQHC/OGxlRdcvFoKGTqmpkN64U7fd5RM4My+RCSS0jmUCk1FjzloK0QS5dKBsvXfOuqGG7VPIT+fXD6dUJdj79+fLk5Bx/bH98d3KJP16eHJfaof465HrJ2yZXxtel80RYVrVl3Kxh5zAvD3/2ffudYzbyHGJ47Jrt61oCUE98j+gFtMTu7pIRC5uXXlXY5apoX+bsb6YuJb68nIn6q5upZEizJTW8YtDPsbJA2qUbn3y5PCMJF7dQOihDvJxZzfCe3MzuqsqWqQc5RVv+S1vNZrO1vbPk6WCMmNSYewDKH5aFr9yt+eRArmEWaH6qmUAzuEdTtr9LmIhkbPR0bgm/l8rD5ThiicQqCCnS3JToMA1W88kDqJxLNvicMTWxn9WK/a8iCe+ZFLFv32MRiIyCgovhm2TcNZ/d5IkBcmwXtJdpt3WDxqIYyFEskndMOZRaaGCWo+v5tlBGpV2e/Nx9d3revvxP5NwfCDOAaT6/y9pHzfYvn99dtdvtNvyO//xrlTsAQRK/1nzUZVzPXOcjVxJu9L1ZZfNC4LgOutnL7MLLAw0mxDac9U1YHrtUnmTYHSkXgyR3cuzzfq9gYvorI+vO7zWQ+clvF+3z427n99cWMCpfoJwGrvNiNoAUg3HtlLYFSYohdJgQ9rEZ/eOXs6tTmAvGdsNBdyc/4h1VHED5EyYGeojD2gwC4DXf2GbM418/XR7jvj75ufvZ/FYgPdiEwR7zHmbMIj4qAQ2QV6wxIDcbrY2bGUhom39sHB1eK02vFYu7Wo+ve1xcjyZ0PG6wB7Z0P+LivitXqKymhaWmIqYqLm4HxMm0usZjb00LAHfMipgc8ulUr5Xw1+71FLvDeAKcsa7+2sxXOlY+/Pvs44r4uWWTCtj5wO9YXbEEi0ygFEr2Aaa0nHLx6f3Vr+3Lk+u8Vs4dE+dX10eZUkxoe+NzfTqiA4alSifQnNvs/k8waXp9z4Uh1GzqFQmnXGq2Eum8zwHOcpACbE4OKXzCHh+zlv16aXl5FTNDbtfHrJcNBssipnkBhmxUdRmByVvWCiltr9UwlEZUCKa6qaZzAf8+5kVAoN4Q3v5l6+T40jaSddi9GTT872dJMiEx09jGfkQTHnGZpWG9HbRD/nJ5VvYhluTTuvnL8HiOHpBZHT6CTqmhiQwAM7KXMnXHYqOy4yyy6E7gU0GP0llZK9tLhiwrLJ3cuLJNRQoOoT+j0Qw9mhipfALOwWDggnSuTn8j241mI4wYlMMKhxgmoJmWQo5kltbRn7AfK837NNL4m4e3KYUhYjmiXNSNjPBRKK+r0zhW+LvZX/gTH9/tBn/g47t9++vUmCMaBc+NMs0e8EfjC9ufsMUy/uKaJeNvmUquBQmH/AnqNes0guA1PnWP2q3ulEr9lk3wLw97zYN6kPhUCqJ4PpbbOplKGii9qlyqYxjdabRMJbnVuAHFKL7McSMwuk8FSeWIkYimEJYwjuuITgi4yhYv9fTCnCdbUmF4ArdHMskxkSgpsEYcSI7AFxcbLQJ6aR4DRUiGgXR2/A0OcYNXGiGFyJAhzFaCGjoTrpmiCTm9uNv3YzIRJdKmuN/8cYMYov91Q16dnly9J5fvj/yg2292tl8jTeGDecatcwPctYqHDrbAcY7cPCwFZJcs56Lkl99DlUM4+87jubR9RbOfPMej9d2qlHGDgs7IsAHnwX++Ko/uGnymTBPeJ1wjxm9aM5tZSE3YHVMTMwUiCU99f2pwN+2YKS5jMspS7FLcc2hfLEaXi7mctdwkgId7jGyMxWAjT/oG4OiG+eyfAWRtdl5fUQCNr2rjXSDgc6DALBYMvG7/cROoMy3HG1OLfPMfN1i7pcmYqhzt0BK9bM8BEECWJHMwPxUPWT04xGkf4Y2/XJ5hJwZElaFCG106kZkyJ2CudSfBxgH47jxCwAW5cazdAFIZwOzoQq9dxSIpUq0ysCUhPTBsCwGwPTkbGMd/NIpZ1IeHu7s7Wwia87///Jf9HH//Dy3Hy6+ZU08vYd02vwh/seHVJmzzlKQM7kNyeXo5zlAvXBDB9L1Ut2QkBddScTFAreWtYneO95hRj3a7WOhNmoYbgILHQBI5sPkd5qtGA/c1EwhuHpqheE1B9bDwAob7ZcTsVvRf88PS1PV0dYTWAP0mYZh4KqQua6+Fto4Z7ZE/L7+rxjRNAwW3ctRrO7xTYvZoXTK/GAmfC/fmqZDuhQ3EBIQFmtmKfGMVtD77su3rzX3MGfMo8bu75WKepe/TDCd/ZqyyqhWw12AC+wL6PCxgEv9io9KzGPfvsFm9qReldMb+bzhj0agLmxKEszTM+USL5rqQ5rugXVQefsBS64D2hrX1FdbRwXy9TPunasFkyCyahX5EbEMhCBuNdU4PkI5P3thvT6HRxbwPF3cakqt6TN+zoAu1mVTfS3SRVmFIoBfKFIu71bqEVxD8HQwZ6HA3KZw5OHENhDQeM69r0qyHf5q6divYxsFY+DCEmjf6UobXkxsA6BV+MH1koI1tFyNmmqkR5DmOFYt4ypKJayyS8FSThN8W6nTTrN/nD35EeOaVOSwOt7bwEXyiIdXgdYNcqYm7jR2PlXzgIyz25im0sOKjcTIhmt4WM1Ss+W3WP6E9lqR4e2PsTDiA71mSAPdXZ8dprgcj2chuZ+CYrQwRwuyjNBqy6jJPOzD646oejuVp/wdv+G8OZxrjSO8jB/wKxOG2bpWvk5/ENajBRFwMuP6Z0QTtO/sMuH7WyQwSY5PEiQQLbNhDxMZoJQ2lbS+JHdSmXjerLxoQt6EgXF5o/DJNARTtcJwLlSf83fZn9tnC4CoZIxFmjqgQMjdwC+9mLZBAHo6ZZqjHEnk/W1XM1itF3RPKFmNXNNWN0cSOgC8Xaheaam9s+FiRHaXgcwOvqS3X8trPbeY0622bDdQqKLBaQRHk5OHhY70qB0+Wj7GBkTFzbmlFeZIHH2YoBJouWflotr6W4y4w+A0OFNbv25QkY2bjFrJyecWuzo5f1zBo5hOR8xXJnURQzDXXTQhUbKgpgtdnRmhmet48Bpc/adYPdsj3fe7AmfPYkZOvxHyHD3y+/GZzYPEVbbIvdvjVej9rtMSXhpa4BkqcUzQ/BEbiGh6xAnjEHx0ZcQ2KuMZD/KpU/lEoCf8kFMR/DADiPwj7cA17+Dz5rBEPyzL5fsEO1ziHLwPncA1x+DIgDv/B6IY/ILDhGtOwyj3yYvz7FcIZ/tOQDH98EMN/Ln7hjwFdCGmMLG5QLUc8qtoewts/nCsofEETE1IdLT0eS4qJO66kGIUZp0zEUKoNCYQ2LxJyKEsi6dG47u+QFwpBOfnAw99GPHjZbI+zkqxmSSmQjJfWM6QESJzQ3z8d0u29/WXkVFlftikhdXlcgpQwfmhmeTeU+abes7nuH+xQxvbqb/dpq75L91v1XpPt15tRHO20duJmq7dQ11YvCeMnfythmLmWlQdPWI9RXX/baDaa9e3mdqvR3Gts79SbzWaztVCcw8miwjq6KVFoW1UHM+PLElEMhPhMaw0FPkhnkBvvC+YH/A6Ss60YpwXl/9DFHHCVzd/SsK/oiJlXsSJphDWutjjST5n34s0UNtelmhkf9C/E6YkSmqa8X6xF0TTSPEIcHxYNMczgL+ot0BPO1DBWop3KjsWjIpSPzcDwvVB7rmYVsB6gPjGtEWbOA8SF0ISLAUs1lIXCga6YVtKB5ISFM3QwQPZgkcuRhY+nV5cnpH119b+O/l1Yk4GS2bhBE06rSg/YuDKa3EzwiqXeU4F5IUBAofBJ9glUv0PNmVYZnPmutDUseIRdTbGncXSLYqSFi25bWODbVpq/Getv0rgWvw6hRknqcEjF/sw49E+eyAyWKUsZoQWhQQtaJNrz0iiVT27+QTY+0gGLqNLkZ3h6f4PMjxeBq1HZMQJLkZ8dz1oDEHwoteXXIBd8OO5ca8DjsvB/bjZ9nHZOSVfoqW9Mgz99xzseMtNK8n5/ej63tYTirhqRCmSuCrBUzxB+YXOHu35x4edDztj088m+wE55EVzck2pNo9vGiGvFjLO9Bd9Ot+Cl2Jp3mXIHj6aNud26x+4ebFzeBuRpAiCYeEyBde+r8+3ph8UL+cdeePhnjxTX7py/Nv78nxlLgq7EKWE0GnpzX+K6YHdyVjb5Wnut/YOFBBNGFlasQlZfh/cpIHY2yujPUg4SRs7O5kaGzaURSdE3C1DdK52buNddPWTXXUQAqQuWaQXYwo6C6y72h7/uwi0CPh680+dSsK0zeb/1kcU8G2194IPhdTeNaMKIw5zmgrTHYyZi/kDaTnlY0IlWbk0W4Cd+QYLc/WFAEYHBU1+aGMdYUhhlqZYj9HXTxrU4eRgDdEk4agEfk5CfADK6g3Ow2H0kLDDEmbzHH5A3/NkwWFIY+MDzVzpYlYqW+rhQy+V8GQrYjw73JL/Rs2b3NHunF+ShAf9XxE2JWcLvmHJeYFsMEqbIyb/njgDmkoC00YZNG63esXsUYreQvlrEz/T7SPafws8cD3k6/D8L5ClNNTLBolo2j9n6WNLK5hm1jk4OJWAW0A09szTYHKc0SeBp60CRW8bGeFjj7oFyXzPu/LVs09xprXgvqxAfsg1AebKPbOfzBUy3/Yc2zJujmfcmZJxQ3Zdq1CAfmGKbm2bXCCnq7GFIsxQysRMbNka9Eri51r5hVgehPeMqnA8JVRECbUVyNIZE6biWY+bUCBNwm8ri/PKcAXAWq5Ehj2MmakQxGuO/zVFVs+d5DSCoZlRIbf6x4Z7dqJENfPoZqHtT6xfJmHX91XMj5sanrvwaHMsRaQqBJ1rKQTL0YEIGov08XrQR3C3mF+gpom5YLBCewl9YnBcAAZKUH9LqzNTYq/CkgjR6W/fhC0IJyia4nS+tzfOCpE+vRKGe9TGws56UCaNilojf4Z8Auh8hQgjvGwPfpxnw1ME3lJP7tcrYiraU+YmLQbcyx30THXefWDHvLuKpf9R+GzcCHY8TVxY3oiLr0wgRVsC7cZhTFmytEYzJQqCMhN1Z7IP22Oy5nz51AM9lVi3OqGHmZI2HcdQYK/kwWZHkNdVZdXr5aSDjqft2IGX2CvQzrGFK5GAAScSQgDJQdDzkEWFKSZXmIdhwVEjNDNuaSEWMv6rdfOSM0TtGMpGDn3IP8wdfzb9SzhLww5qzNhPRkBknt7yAJ5eXny67X86vLr90rk6Ou5efPl2taAXx+rSqZhIdmwUhCs2YYqcGS9axg4gkR1KNpQojuEsyqhkdVawhzBSrVBMwnlRWD2Dtr1cOYyWNRd7ItYIf9Jna4eTzh99+f/vxbfuXFUnanH2ajuZpePCYPXpcBvAvbB08X8xb47KJYwS8hnN4JkZ/q940/7tqbR+2moc7z8Dn/wq75t2ey/h+4izd7GipnOsV6JdZmUXRsFjZ/ItRNFQ73+oxXYPfc84wAOHA5zFW4xVQygs1x1DpV4B3NvaMlImFAaX2OoSA+kJLB5Vj2bRc4akP+nVJqc82YaAomA+4pknRmDEeLNS70wHlIsCfM9/ocWHcAQvqHKzPzBOCFpbmK+p/ObEZ73U55xDweGEcc/6CNzevPwgYYLgVC99fmBvz7RU7urnHZ7TtiGmKfciGVAwecX3xbx7CH4aJHPy8cQ2zMfQguRmZqTySv3nnWEpugIscztFitBMa/zfoEtdgDRwGvH1MIcXIDgcZ0SKn26MqGAktKtmY3fHK4ojHMLhFFEM1Z3uwhKSXvJ352wBOM+M85Kr4ceMjyFm+CXhKbJy9QU59mrpF5UDNosIIETbhrFl/Mu+6VpLF1lCO2BZN8jV6tkzMxF2ccFmxzHy1jqHUw7YVfUIuRQQ3OF6cvZLb2cI135jChULPPE//9xn+eIwZHRRKG2oByhp1gVg7yJAl/QaEZDQDl62i7fWRRkMuGAmncm/Kydn72W/Lw9v9+v7ceNozGOtNIIOyuoY87ybGUbMtLAw/j/JyxrVOGDkRMaeLOgCGpWicdStMADq6+OIj5U+uzanQbO6+wLP4sIdnNzjXFjn+Th40VL/EqHDGMk15L2E5upqZcTP1h2CDnCIxNuSV+xiIrNjLeAJZfsae5InVepE5nCyWcZ/aa9sRTcBxAVZkXn6ziDjYw1iquYDt+wnVmgn/6cxcXhyOxYQlDHLWMMYLZjH2jVmc1CGjMVMN2uNdm7Bb0V4MMnXdVmwHcaZ3aJ7CfWyfRoy8ar87fb0CziDdqiKePsAUmNH12Du2BOlmh1dlIEDXIMDND+i28y5PORNaTcKuxStDrbQizyeoQO4SY07Vvg+bG82H1gbE/TwAruPhGciKT3CRdmmPV0T9119dty5nXGQP5FNnBetS4Ulpt9VTh+UShH9zzbr8i4w42is7wnC4ao6wFC+w56FVsCAWNhXNdw3OLGgUXMwJgroAIcZoNCR2svImKXgBt2zimtDkLe4KSOEps0MjbLnLMOlNSJr16pj74YcE+EPBqB6Sm5Djxk83S2kKP0405NuLaepCGljR+BzyevpnZoPBPdf3L+YphgUCKVo6VrEJ4OiR43kc62dx0xlSIaQgdngS0STKElSA3jpdJR/9hM7VNmgRjWF2bcduZHhDYbKVkF1hzmyJ6jBfbSmiXVf+ruz3U1ZV6WGJfpxttRw8HxDC7f2wx+nTdLvJADpiJeRXeLKXqDdDrYToO650RpPu/Llez7J0S4Tb+VxO10p5WHzbLMDA8tsG+ph8qwMfJvu7D3zkePkD347zDJtp0ZfOCtLJz2+5VZBfsb6YIn1pjQGQCF1EJOHVI63CdMRPF0A+8TTgbxmWNEv6Q5rO00BjEVbc8CSdjHoSOlsN4ZVc2imrumXY+0L3rfm6fv0QzbKmBN2X6rZKqJPNttkPt3DVmOdhwcUoTVMZ8bzRMw1ufP3W94L6JDBEUSOUKGZv/dzQPkUGromnJyqN7ge1s5C2vcFN7ukkxf5s2mwCuy4wjetMbPusA9g7Xhbl8/mBzTewYgDSI4t8nF+979ju13ADSxM5kFlqOxe2LfAyw+BfRytGR+RV+7jz2qVYMLfMflQgKsVHsT7KXZdBM6SIJgmLyf88bl+1G+R3KVgjAHjiaQ7FnKVBOXFv4lvXa2nTsV23aRLLe5FIWmiq4st0SFuQ9nEHLmknY2OEBnve3dVKNTokN0eH12Oqh9daXhuawVnw789hKkes6zfpDUrgZupTP7K9Ew7AGOwr5ZImyE3+rQa5KU94M92QPPimeV9CKkpfmn44fwDyq/LdkTdCxgfNzzc1vMAPrx1h4wGB5Yb6wSLO3+Z36u0fVJbJdqH4iKqJLX87PSavfj49fv3kNf1mq9lsLWo1wTzfhJcwB3EmH8tcrgOExSjeq4iTj8d7cEYveiw7hI1WRfR1PrRbKyEwz26vgMTtvf2VELnXmieYtyCRe63tFRCZxoxV9Vp1OscnJxdLEclFjgm38uItM3beD9CZhniu5tafLXotKbPtvf2dtzuLqrMRH7EqMw4+nn48wVsUl1oUZgxjzCBUckQqZ17IfiEERRDtsdDxkFNBoXyZpikfAJZPujViMad1uEUIf248DPUo+eO0fd4ODIQ+jzhN8M7hv2wLSJ9m0CC/Gvt7hCmBVICNBswYcwpvvHq28YofcyRT7dFhC6zbpmqL7sFRdVvwo9mB4SpwQWSkoXOx3ZY0DGTnu6+5v9tceO8tmRs5IzXS5zQaJ8n2E11U3hU6K+dTR7u1xTzoUO4uOoxYzPG1SXylZXCu3+LumbwXlaVRgQsME2yCB6Vm1pUvY83M2brzb6uqf+/s8DABtza16t7Fn5GJWXDj4yBv8XmZmFvLb5Qx+xYJhUcXX4rJhJqqAdPeN56dULhwNuEYypnHVFSVf4v+KuAPwDQl476WAz1R7bLT6pi6PsXmKouOxuwbVOp75oNPF+T9guYpRAvwav5bcRqPZ/aumIXxTEb3GzuNg/1ms9F6s9uaG1uvzDEfjSsMy262MRLr0PQwRwQaZ5OLE3xLSVsQSwWp16HlIjxGArqI+ctU39k+FwOmxooLjbUqANlyZ5QddL4HFPAxt1fuUhGJQG0yZnXgM9eZiorU12OmZEjvGJFRlCnA1cHGF/fYrxDqJKzFp6gP7wH1WAtfrJRR1jykumCY9rlibAJaZauXyMEWgjLUjS1l9NrWdrO1u9VsbUGsi4tB3aab1lE4dVsK3jA2azkm04z23zZ3ol12sL3dMj/EEd072N+hNN7Zj+P+4vvFpZ514VWp0ATy78kymrBz0T49v2qc/HayOMe2MLFqNu00y7C74TU/AD7ZiCn8/GnMEM2GdBD+YEF5LNk+Am87oIEEF+i9FSLSQeUE2i0YlTSDQpHQhvl1RnPG1v7O20XPdrQcui/dRLxCAweMRGPlpJNRwsXtwtejFfr0sMjg2L7CHRxzBXiTluYycox5bEE+ssoix1dDOGwUBI2/QNBY5bhsQV30q85URBmdmdXGldc9OIn4u3pwzlqKf3rzzSdl8p113XyCl5fQiuM7a7f5hDRfTB+OhfpsPsHY391/o/IGm3Py/gJ6cXyTzppPiOMHbdwxi+MfrpfmY0z+OE00Z3H4o3XP/AqP/9y2mV8RzD+rX+ZXhPE9NMqcxcK6Q+Y37JA5cwHWrTG/XWvMmQvwg/fEfJrn76sZ5lO8vATX+/vpgvmUJF+M271Q+8unOPu7/e6V9r2cl9EX4GQ/t+HlU6z9gxzm77LFZciISnU3ZWyed+1RVxhLV6bhULnQxk0aYKMLW1UDTrFvjZbywVCHVgtWrnjypjnchHhAq1Vv7l213hxu7x3uvmk0mwshpQ6YbERcT6oCFj5yerN8iS2FVowugLYFNEuhufHIulEpPXQlhF/dy7qFyItKecp+9s10NnPnC1h6RbYqWo/zAsCznaxMvlR6SNrgpCygGJATsKW6PJVVLdGRNddOO59gjcpmy8KrgLRX9U5YumfunCMq6CJwmoZuQG4sWQwlmgdMdkNMquJpIsWA6yxGPZZQDb+UddD/JRuJFBuHpP5mp7Hf2n2706yRjYTqjUOyu9fYa+4dtN6S/7egSqqyYPJLylTdlZ1PpeZhs1xbeahtqeodS8zfBoqKLKEqhJnXQzYhETX+aE9mYRnikfPqdbHBHVdYSxgxYVz3Gl6uJ1IqG3Co+ZhB7Dr9+EFdx2MPPIH2eo1E3jwtltPmxYEYueICGoeNoCh0wKTjtpx60pOplqIeL3CTYhZwLFNNk6re/M0LGB4183SZKyya46sAvw2dovKMYZtV60FOR3Ti4RBvhbwX0EGIGFZgIqnI76cXoWdIiL2stz1m7nnMkgmWazpnUkv3Y1nIB7vN3QVC3EbAig2MxVWher2EGZ7SrvXPC+CzBsRXpF8t4TPV6+eM9diCe9oYdX9JUYm1MUQAaWLGd+dzrorSLBqazXjaPm8Hz83k0J7aW201AGuFbr3LmJBpt81VgGszN+d8nvI0/9Cz23Pl6TDF3lxE9v1L9kRvrlZju7HTWCBHLqHf1OQHCIIXYfGPqLrlYtDQSVV1hxtXivb7PCJnhk1yoaSWkUwgQmisZ0tB2rgWly5uizeDeSu/sMcf+Yn8+uH06gTb9f18eXJyjj+2P747ucQfL0+OSz384EsLCMjWT3XpPKGIVe0NN2vYQsfLwB9U32aLmF06B+uP3RF9/bUHeAffqHSB1353dwE33yYcVxWfmO5k7CfeTF2uc3nZEvVXN1PJkGYLqOaqGwVfFnoEJ1zcQs2WDAFAZnV8enKjunsWW9cbJKls+S9tNZvN1vbOAmrdWBapsbUAFTuso125H/HJodXCLNClTzOBNmiPpmx/lzARydgo29wMfS+Vx/xwxBKJaexSpPlZ32EaTNaTB1Ahl2zwOWNqYj+rFRvBRBLeISli3+vCwqgYhQO3lzfJuGs+u8lvqeXYLmIv026LBt3wMPqhWCTvmHKwldC9J4f28r1SjIq6PPm5++70vH35n8i5V+oz0DU+v8vaR832L5/fXbXb7Tb8jv/8a9lVRyS2r3XMcym2M9f2yNXTGp1tVtZsfBzX4bR6OV14GaBFg2Bqs74JS2KXx5MMOyLlYpDkXoV93u8PzER+ZeTb+b0Gcj757aJ9ftzt/P7aIt3ki5LTwHVeaQT4RzCundLi+6cYO4YJYe+a0T9+Obs6hblgbDcctD/xI95RxQE5O2FioIc4rL3aBl7zzWzGPP710+Ux7uWTn7ufzW8F0oONF+wr79LFLOKjUmU2ecUaA3Kz0dq4mQHbtPnHxtHhtdL0WrG4q/X4usfF9WhCx+MGe2ALNcss7rVyucFq+rFpKmKq4uIWQDA+q1M8UNA007hLlmBsyKfziFbCU7vXU+wOHXU4J11Rq5mvdEx8+PfZxyV4uGWTClj4wO9YHTriG1MFalZkHzAPy3f+n95f/dq+PLnOi5ec2j+/uj7KlGJC2yuN69MRHTCsLzmBrrBmZ3+CSdPrey4MoWbDLiGQch3QSiTyPkdayqu6sRMu5IEJewTMWt7rpWXkVcYMWV0fs142GCwC3eSFFpJeVRQeM4Os9VDaRoszkUZUCKa6qaZzIYQ+Zs1DtNoQ2/5l6+T40nY5dCCfGXSO7mdJMiEx09gbeUQTHnGZpWEBFPTk/HJ5VrblF+DN+s/L8HWO3odZBT6Cln6h2Vpsi27bqiNiAfgz0ExvVqrE9gLxvApr1jauLJJ/wQHzZyiahkcTI4lPwC0c6Fy4bv7NRuiLl91123WfZloKOZJZWke73n6sNO/TSONvHsej5N7HckS5qBu54KNQ71Sncazwd7OP8Cc+vtsN/sDHd/v216kxRzQKnhtlmj3gj8b3tD9hn0/8xXXsxN8ylVwLEg75ExTN1WkE0Vx86h61Vd0pjPotm+BfHvaaB/Ugw6YUnPB8PH+7ZCppoMSqcm2OYXSnoTKV5JbcBlQW+FqzjcAQPhUklSNGIpqC62+cxhGdEHBTLfji6YU5E7akwhAAbolkkgO+UFJgjThkENtuHTuIARRiHjjEGvaBdLb1DQ5xg3H9kEJkyBBmy/EMnQnXTNGEnF7c7fsxmYgSaXOdb/64QUDC/7ohr05Prt6Ty/dHftDtNzvbr5Gm8ME8PdOZ5u5uwWOPWpQrR24e7gGyS9ZsUfL/P3vvvtRIrjSI/z9PoWAifg3fzy5sg7n0xnwTNNBn+E7ftqFnzu7sCSNXybaGslRdUkF7/trX2NfbJ9lQ6lKqi6FsMBi6O06cwXaVlJlKpTJTeVmOb1Ze9zVvfu0o7NJH3eR5QUvX8iVV5ojXqhOYrknR2Ivq6LZbnSAS0RGiUhcJFS3FwIxLRK5JOlNT6FKkpfdLg9tpE5JSHqFpJnQLzaEtX0QibfoQGxyVH+vw8JCgjYSNN/KoYKg2G6jvXm71W8VtoxRD5ehVMdsnXSXWE1SmSAZsq58vPbElebJRWtjLny91Io5ECU7zcmwG6GUKjAPSWRw3QLjkf3j4zPqzka6D+uXzO11qXZfYMN2mZzyDzte5RJ15DAJ1fnOLnDJ0aVG7hNJLUHNEFhpEpiTkTMg0Ax0Q4tD8uu9QwyRHQ/u+53oHi7Lu9e7uzrauIPLr11/M9/rzz5Iny62TFT3rsFavvjB3AeBEIrCzQILAvUFOQ0e7GtFBGWJE3vD0Ck05o5KnlI21RHLarD2Xh0SJPsMipgYgFv6iY9DuUczHJlBBvaqk60gSpisf+6qkdu1jOSl3Tnc8MiWG/dxrblgsbLNCC2hLd78mOqqRcVmVTEuxixptzs/LcVKChfCE14OXxzXDWwFljsolglQ1sI0KgtzmHv1kHB8eMJ6kNaTdWBa+hS+f7u7Aoc6JuQDv7lYzNpa6X1LQf83IytIUQLeCCcyGcgFCgJj+xXhy65B1e1KtUonxK2fjr3A2agXMr0DuzxKoMwYX1WnG1bsgLdLc9Nf5rh7sgdHFdcN2DPMNM+meanmTaWS1CudG1DXnGSLTRObwAOj6yUvzdqm8VkRHcKklIQJoSOQN8dqlQmP+G65NmGUVAG0NkpREg9WaaRfgPB1PCMhhOymcG3riFhAmSYiTHSIb6p9KV1IF3dUbSz8MrtqNEef+dd0GVC7yvyiLfa0DmwWIiCTpFILukpSEVJB4ZjsHxFRIFNOrQkKlyEYj+s2NCM9sKoH/entbP6KfCHg63grQRTqzt5NJkvJvdKqzb6mA3jJ0msQzJPFVMezCqMdqzWM8JLHQtxxKJ4RD9IbEMWB/8e5E5DIu5EF2VVOw6V4p94p3RDghqwt9PIfR54tuOE7LNom+2b58Xassa3jnHMxLksCy6Cq3jZvEdprQ0Z/akfk1w7HWxcwzYIIZY8+LxoxjSwadaUG+hSTRGs2Em75suoVRaVsZuRCAzwQDQWmhg0MZAsjeoHouLRjhd9N41IWogvmiFDqYOcSM8VwZLezBlkeB3BVSRmhIYn5TLxLq5UdRxvi01X4jLGQwnZkR9CbSUgQL6RQG56cxoxRsX8BVmFwdJ+UsA4ts2FMM1C0IqlZhw+fg6YPFWD22PlM+xob2SqkzSaaYxrkToGbjY7FESptid8mTASD1CIcFGY1MmI1SgzXbGFpskot3J1st7aRy0a/5KuSGGwjdlm0FAuLTlwjelqlxi5TnzX1e+ZNqzYArnveZAufJvOMkX4lmBwt8vxyD2crTK2KsL2b4+1snP0rBrUMpuB9V4G4hx7MtAPej9tsD1X57iWXfvtOKbz+KvdVR4sWnrb/0Em8vurrbCy/s9qOm2900+V7LuT3vSm4/irg9XRG3H/Xbnq5+23dWuu2FVG37UbDtoXlhbWzle9Zq+x7KtL3MCm3fV3G251uXzQbiBzimeFXu/w2l/sIEm0Q4CWunNi3+BYG1g4QvCNeWaQao2uwPPz8Awu+w7p8WXmllExf82iaGz7XaUb8p5p4F/4v9MYFQXy79IVPyNaPQq23GM7jzygRBGL0/u/h8io4uLv6/439CGyyvBI5DwUM3qGQfvPoTbfyrfTQmTG6g5lmQbmlW1pwI1oVGlQXJTVS4d4QcHKisA4k5aEgm+Jry1Keeu26Z8ojExKiWFeL5xK+nuD9oDfEdjDSqEvq80+/3FibvCnWMjXKZgmdFYrhVrhD5KHpLWbQwlZMYSyWsVipj3CSPS28/U+t3P1Pr6I/zSqrU0d+ZzXuCP9HRiam1cvxJ//GOssykT01x+PFc//lBRxrDB3/Ij6MRDQna2evr584xNm/Y3n3sTo6wbOCPW8cRjr71Qs5MuJSQW3V5DeCPtFBjYzEe8Wlj2eX+e7LAcPPPHAdjAYPqKli7HEuJw6tgSmVKoHe9HWAbZOT2wsuz0qzJibm3V6rbghvWrYBPyIU2rHYU6h3zXvdH1R8uOI8Lu5ehhtuoduUUhtUFU5M0XQypNKHwcdQBmKpuEQL0P25FuKClwSitQrgR2iTfgvl8ql8R2xdHnU6nt422qhSDX+oIs8qD3E8it7zamEg+TSoMcn8iVWlUzNkvkemRJW2WxutELH/4KuGajlKkKwkn4Ad/nK1pZ7v37rQDLUZO+5bYvuh2+oc13Affz6HQw+7RB8kNu0Xy3qrOL7wOc7Srla3DMZ9OMYvgMuRcY8HGull0khJ7HV9doycSEI3peYf9sjJ6Nn93DmFFNnwsWQGB6Vpg+LPeV/76Y92PvJ1Od57oCDqdxjfXc4i7hmJmviRZcIFuN9VWvECf+A1Jzyckbq611q/Q0wiZxqT2yTtPs18xqRd7//blcIsRa/+LpBK22zt9XTdOeZa8RlqrLrVhV0zvvLKSI6zeUnYY0/VCIQ9QmDoUAo14mAnEtffVjo9QYuvSUilIPIIziUJJNbh3iGcIX3MaCURZOyIJpBvieCaoyEPdNQjfgn7n0IzqX9KNaGwDtE3lfYXUTzVEkampM+XvaEuhkCaTlXnvz3W+qLk4sKU29JSaHaMsdV/rklw+qSvi8t354PT45LfTwefzo8EfZxe/DY5Ozwfd3sHg+M3xQF+lN92oYUwJk0E13v7BU6xP37dtyUohMYvaOOaseOXKIXE0DyLRsFVioTKRAfNMMwl/tCGHVujatuiyitIgnECxGgHXQnmgiRsUUnJ0Uqu+Q8ASMleqLVXOzoKg8c3YPEhWROIjqCHJRwVae5ObimJTfEVQlpQvvB0xAMTb1mKpNchr79hVwNKE++ShPboiC0Q8+mGQWq4AXNVkjD839KJstJD9q7kn0sA5wWISTKP+ihbmuCCx2Fip4hRi4+y2f3/SRxEdE32VeXL62a2fuWB01OOjJlumFGilM7Y4lBRRuBr/l5+154Kv6gKtdNlVF1sFY1RWovN2f+94/23vuN9/8/Zk/+Tg9ODNwdvdN2/fvO0cH542bmTgr4mY4O6TLcr5b0fdZ78qh6c7hzsnhzvdnYODg4OT3sFBb2/vuHdy2O33ursn3ZPu8fHpm17juKvS6uRHzZOsT6+/V79CjobX+d35/VcoH1Wv1MPsm72D/bd7e3tHnf7u6dvu/lHn4LT3ttfd650evdk9fnPcOent9U+7J/sH+/03p/u7b97uHO93e8dHh72To7eNQ7wNjjoJYUWLVhNf5WUA2rLtAIH9BKpd7UFUqKDorVLF5ZGnJH3mXKLjI0hdOmOjFOtqSVlK0AXB0xY6Of7FZcueHP+yQC6HmfwvvLOq41sLAV1kKC/wr+cVUPA8Ujr2RCeMz1BCUsVqisXOz99t53o3QhPMIjHBV9XyT9Eu6Q+7B9HesN8P97u9/d7B4U6v1w0P94a417xXjiHHQ2R5nGBJtiETwtORoUKbnqRJ0oe/M2vyI171Or1uu6P+dwF5Ea87ncV6N3j43jvrY1GEy0kgdyHbPdzvPASyUCQqXWU85pFSvEMcx0pYMnT+4czIVEniWJhgHsgk1BkyEy4kSBXJ9TfeWWnlA4SPS0mm2vWp7w+VMYUkD9AfuvJfIdb8GtMYD5VIcIHmbtwxUZRPqLaDLyOiBJzufGWKStYniy1cRdLSXMvKp5TPFYmcS2JHljsl8nSmfwNRfMLDbOoKyj+QJBZZopv9DLQtvaogE2dWmWnqdYeCEa+/mZA45nUGyxwLvtffG/zj+L2y4HcOdpU9kz94enxy26NuXTaWsn9+1AV4uroA/hJ870UBamnxzCoC1OCwDukNz6wcQA0V1ya/YalaADUIPXVuw8oLAdyB8xrkOjxKFYAaMrzQ5Agf0xeX/19G7uUk//uYvbTM/zm4fb9p/3MI8n3l/M8hwnNI+PdB/5Ht/4jZ/gXC/0j1f7xU/wLhX3iefz2uzyvJvw6HdTCBn0+Gfx0F18b8XSq9vw6jp7Z/HzS3/y4E18DYXTSxvw6l78BwfZYp/au0Z+YEMOYWjm0zO6bXhJlrkpa+0MRJEtMQD+PqTbQgYdLr76WNLRciJB7GINgbYDrkPCaY1SH0Rv+ERjEuoGXKv1+8O0eMjLmk+r7qBguvDadSPJ1KJVPMBDRqN3GyDBEG+pD6nDFG4sbbjZFvcmBDZh91KV2c7pDAVwA3iQL0ydTV1zYWosU2HmdHH47y9smbfqcgihmGsGUslJY6JUyKbRmLtmuspnBo63Hn/hB8m8hp/DOOE9a2MLZpJLZKIVKmI0tuNMT8hqTQYqS2/dV2N2jMdCkR2XSlDEdFKbgaGM7MC21hHLaKvb5pBafMpY3ZTN+nr2fEr4Ft0YjfKkpPFfE7D5IVkXiVEb/+Wiy1BusZ8WvgfDERv3aZnnPEr78mLyPi9ylX5aEjfkur80IifhuuUD7qM4z4NTiuNOL3fKHY3kpMb35GaFgrptyjxPaayf/COysLIqsP7tUTP1hw787h7u5uFw/3+vv9XdLrdfaHXdId7vb3hzt7u93mBZw0PR7qCldIPE0qsa4msHMdgns9fB/kVncRhB89uNcgu9pA0/PGIaUlgVwjACpBRysTAD/iIJ8uDtJfgu89DrKWFs8sDrIGh3W4BHpmcZA1VFybi6Cl4iBrEHrqe6CVx0HegfMaXA09ShxkDRle6HWSj+mLi4MsI/dy4iB9zF5aHOQc3L7fOMg5BPm+4iDnEOE5xEH6oP+Ig3zEOMgC4X/EQT5eHGSB8C88DrIe1+cVB1mHwzqYwM8nDrKOgmtj/i4VB1mH0VPbvw8aB3kXgmtg7C4aB1mH0ndguD7LOMjiNf1DQ/tBq2Yowam72rDXzQlOhYnXgu95SsdUMZ+OTqu5yAl6jZ3jdi1WHB74QVE/pn+TSIfQwRW2iw6EQ8RH8y4UbeHRuQg6tksws7WR63CqYjQHnwI2r4zKTnPV0Xb/SDADPdo2jAq5ru6vxIRMcUiCnwzkR/rhlJgLK7jf54kyzyFUTw+CdSQohvi9FhJZOIFQAGgZQYTUsaEQVmDGVTuNhgR2LkYRlnioiP01I+ks0HyRc/9odIgPDg+6w/0wjPr4pwYk1Vg8Ik3LZIPPuh6r0MWUk5ggcg00jOkV8UlmAtWGRJmUSPIxUaTSppO90jMjY2VWp46wE8yiWJtgbhLKJEnbJqCSRJbWokzX3eHosDfa6e/vD3d2I7yHd0Jy2DuMOqRDdvd39orktLA+MlHttI351X+H6hpKEzqeKGIByOq9G55eoSnBIkuNRQlM7JjSMLAjuc/G9pAoEbPTGXX29jHuDPFhpzfc94iXpVpgmQLEXz6/g4/zCxB/+fzOlhaG8y5SSipU+9HGH1dTmvMQp1IZ5F8+vxP6etI8aYFX+A9Tgq8oG6OI3zDFHhyJcEKmpIV0EacWSrCcmPc5suG096kprAdekaB+dQKjWzbJ0jgXOhvF+lMbjjUQOmNI8CmByGglnRSdp3imS2ab+PWzT4oK24q0it4RTUko41nL+R1wETVtTwdqbHBmqLFbOj7cXS6jG3BjjLmaQ/10aWpnacr5EGqEFGDmjlrBGVNJUhyjs0/Xe25MwsKYG8fi5Z+XsHaX/75Em2enF2/R57fHbtDe/k5vS8PkP5j7SKyfBaKCh4o+iYSdYfabBdeNqMF+VT7waip/ueQFG9++Ko6ABgAKrJxwOrhWSV07eY16Yra2Qw14CWJ7Ixt2FxMc6d0jvaW6qI5OBYLwAkEkoko6mRDrluJLxqUS/+kM6rJP4Hgsvl8a3E6bkJTyCE0zIWGQoZLwCj4SFU+IPFdBPzwkaCNhY688lnp9I1DfeXN94NJEJ9/o4nAGL9B3FJz56WUhFWjTmrMSp8H4760WYO7GBLJhpbszP1DQMdbmxvjvjZaGR4+wsVXlp8R4rSwTjVI8njZzTi/FQ594Ko02bsQKgqsrvQl+vvSEjOTJRmm9Ln++1HdRsqAgW6ANeg6XLG6ixtrgE/PlIzd/ORvpphrqdIHWo3SqpCJmcBTOeAYV3HOZN/PWWkjuh3NRhi6zNA7UeJeQHQVBpiAz9b6lAlyWTIc1kUibe6B1WkEE6pMbUvAsDetTXGwiTi6NXu/u7mwLgtNw8uvXX8z3+vPPkieFtbHCYe3X59UXNuWRUpmiXKIB2wokCGEFujl61ex8yhDTvRbRlDMquTJotEDhQ1B4IndaDomSXIYtYCVTgoW/0BiSxVDMx6LlzjPoaiAJQ38p2eQMChM0DApIYUP5fDElhuXca25YLJScvcHCAdoqKEiMy6pgWYpF1Ghzfi5wT4KF8GTPg+cVmeHzHhFwgAUlGORkce4tzSMnpTk8+WcIsVGalqcL3hxqh8drY0LXwsFzWVqBY3e3erOwu7tTAApsylWqHTCBYVb965Bo7UP/YvLz6nBw/K5oWmKqyvnyK5wvWjfxXS3+LIGS2bioQDKu3oWdmOZXZDpswoM9MNpnqu/iYL5hJt1TLW8yjazWbtyIkDuAGSLTRObwAOj6yUvzdoiZkiLufphCbgKTFEuChkTeEFJMtZQ3XCvtpUNUZ1+SlESD1dobF54VmU8KotZaUArfJCF5Z+lsqH/ylrGirXlj6YfBwNsYce5HGG2oBdnwvyhLSq31GbpGRJJ0ShmJ1PkZUkFik9iBIcnPuB/ym2mRjUb0mxsRnoF81tfb2/oR/UTA0/FWgC7SmaksjJMk5d/oVMdqUKFsEUGnSTxDEizOqkKoljLGQxILJX1iUJfg3LkhcQzYX7w7EbmgCXmQXW1URXg5AMv50sCwXRUfnMPo88UiHCxl5VpHBFy+rlUPNbxzjqgiZpahVsnkbhKQ5UYZ1sf9DH3NcKyVDfMM013nQSDlcgDHscVOe+nJt5Ak+siecGXFqNcyFhnNurKLAzDVsXVueHZFGQLwH5q8dS2d4PdQeyedv0fa7nAwc4gZ47myVdgxLY8CuQVeRmhIYp2oUt3A9bu9KBF82mp3BRYymM7MCJrl9Z7HQm4EZfeAGaVgmwGuwtzvOJlk+VJkw14gsmG3IFZahe2Zg6elu1Hlbax8PsaGdoaog0GmmMa5kVqzTbFofN0peTIANB5BmJPRiISQa6A0O80oBvtNcvHuZKulvSFXjN8wRcKc7rn9AUKxZb2MIN78re1tkhpDvTxv7lzxuqqFfAp88LxlPsj7eeI+X4lmgh++L/BNJki6wlCCL2b4GoXbh0B7TI2L136e7+MFLgRXvvH0Ws0RUaaVYiUg8JBnWnDCo9pWg9Z05Bo7U9h4FcHKc1xiutgp/pjgawKeGAKhHTz1XDpMppQIozbCJCBWeAqWIYPXaGQlhXVHY4YwJN8b61GfAJ6gnJqFu1dbuglmYyKC1UoDv8u19vbydJaTHFThKYFwNz6ap8thht6dHH1SpD3SzHzihvLFQPOy6AZ3SDZaIWMXs5ma10Yy4KlD9YHDeB6+8ajC85XIFYCW0hhc14uK/XgUD0kq0SllQhLKFiUJ8PqT8SzM/tRMq0mwsma/1etCV4EJsDeNOMVMSDLdTmIslUBdmLc1Fis8WPxV1JMtCqKXov/gPPbFNYw1xRqgk0yqW5IWDqkR3OFrackQZpzNpvRvz/erye8+fhFklMVqE16qlwIaXSoe1B8UgpdO6Qw5G+l1xnHxYGRRjR6fCRItzq5lRg3zfI6HZFJ7qyBq0nzP2912v93rtnud3m5v97Db2z/Yb/f2Dnu7vcPdzm67t9PvHvb39g/22t3OAqWtDYpVLl4WyYcXz+cTnhqbkKco5mPvYreOVjggS4rmlMcrS2d2tYh0eIaaCWGtukma73Ojo5VQevXnxhUdYoYHOJpSttFCGykBI5GNB2rABSr8vDhtyV0hW0Phu1QIc+zXVCXMAfyhFNYQ5TtWC8tEeK6KYRmPtVQNcyB/KIf3UQ5zOr5g9TBH8vtWEHM6fBcq4lNoEH7c0zoqB82Dbh5Ac7DQvVSloIjfWp73RRAf/yi38/84peee0pZEz/UAdpXN1+tsbS7p7nnwuiid7+FMlTgdE/lduiYM6mvqlzDQrave8QROCUORl6p8LEqBtVRPFkViLX0RBsIfKs59HBGGiM9VCWqO4ZqpSY/sgjBEeMG6kh8sNcBjm8njhUyh/NsGgVN6DBs+xSB3H2r7TomOjcdomPIbL1va7e6LCZmZbBQx4TdInUQM3ZChTQGG3BU1FGXjPNDeJP9nDlQb5H7/WKeIqGkfS4yb2cprTD9NOCN32C4rASgnaVXq4BFOaQGoBfKznk6VYx63DArcUsbwPf+bxjHe7gcdtKnX4L+h409fzHqgj+eo2xt0dQjnexyqL/61hY6SJCZ/kOE/qdze6/SDbtDtOzg3//nbxft3Lf3OP0h4xbdssZHtbi/ooPd8SGOy3e2fdncPDJG39zq7pjWUI7UIRnhK41Ul0Hw8R3p8tGkjP1MSTbBsoYgMKWYtNEoJGYqohW4oi/iN2KoQUD9ZgbtZhuV6mt4fdYkNNjbqoTUHmJ+Y7Fp9pFCqSyvBFe7SDPOe/4WvSZlGVyRlZFVGWwUHPZsDW1cIwTfz9sVusBt02t1urw0FQWlYhn4Nzbl7r7AtM+Ct77wl/VeZHtaEeKz1tPOZvRsSJrlooWyYMZndtl9xekMr+1UBtjIzQejg90szj6m8ANYClmTMU/q3foKXkaRMcre4ShybI2uYchxBWUCShkrxBzlGifBsiI/ucUHQiMcxv1Ejm36Cea40ZMJtuppDW69RTFn2rYWmOASKMvotT9YwdK2Wjfh4jmY8e/UqVSc8hrwMSAEwaUcmGTimQrZMmr+X56FLC7ghE55kyoaKAvQpJlgQFBOJMgEZEWg4U4RiagbMdBlQPdXp8XlLUTVJecIFQdTLD8RRBL0iqzH9gGZTTZmLYLVlrip83lRgdTtBt3yArhZUr37YHWqUOvQ9Jfw6NgemUb9/f3f0oYnirZ6zKjdO8xxOY0LO0EGnF3S/IonHm2JLJ48lOLwi0hUwEjr3AwtE2RhKmUBXDf0njI+F4CE1VfrUEMwmd4PtDsa9wtptTOxKB5vJ9JFoO0q6nfJB57gHCvs6LFIS8jRSw1E2jg22Eo8hzQykQwblIKCNpV28iS6AoAD92qas/RURFuJEZBpK0TKuhzrIUCFvXc4SGnr5bibbAkq8YJegLwgTPEWbJBgH6H8SctVCf9CUiAlOr7Yg+5xek3iGnHkGjqYUj6CycokSlDGSzl1VPQTSDxnk8gUWaNPmkZhRzW9F/LfmIHk7eho/M+6iWN6CnpZ2P1lxHs+c/KXMSSiFO6vhFcXouqsRseSQeDwGWWCG/Di0bcc85rbcG/hcbk6BGv6zj5shHW/7riWo1eJ2hakrZh1SERVhSsABVt5hZkyAwBtv3rqMaEpucByLFkqB+UVLe0BwhIY4xiwkqXgA+3dlTlhA9OxEGxaKVfJ61W5VqnK86Vm0QvP4Y2KqdwIG4HpaBAeeSUGjOyqhu9MgixlJ8ZC6yrL2WKj8MP98UMdDYaAGmW24ZmpUSXOzraVzx9S90sq0wrfSkhDQcoqPrAKh5H8aTqgkul8XICgr9MIQhiTyfN8LUBxN0RWrbbedPNgc+bckJ2AFq7nOv5yfbqk/dCOFGB50g+Yv2KqLPEVvzT7fKmSq5l2tv2Y4nolxhtMo0H9DNfCvN2Q4IXGyPeIDqAwUbyv9MCbRmKihtwsIDqyuTUQwkdM//zsM5AArEiN/9t9btXVhbI0rm4tYVStf/blh8VrgJjeM1eFik8hXxCXQHKIwkSuoWqCCCHmaa6KFxcl9PX45G2gWAr3Hw2shtqtFcX8/b1zB24N4zczsCi29L+oJCVvOnGzCHfQ4hjPTn7bu7TmbIrwmwZTKlOhe70qibY/wV2Du+Ofwmgwg4XbgAScGYUqUWfXnMRSUd9P6kpYSfWKffku4UPLi+PdTH8N/V1b1jCkb6uM50t1oUC/o9oK9ll/OpUgOYwt+/nS8QHtvAr0ZVr0trOz0bqVAP9KXp1TcsjTVLVG3RDV74rQpCVampyjMLcZGIGyenWzZ4gKm4UahKEfd0Yl0jneAzvy0bJQVL/rMBGZQeytdpWv5zGjK+jcTLAdUDNQWoNGW4fUyj+eOgTKvn538u2aN2rrDUafTadzlBip7ktXVJz9CKdFl1eYLmIKWbaSNLrU6pZKOtZHkaGEXw3F/VFqXMmHqVyQc0/aQMvUteIXDMf1V/fGLo+Net7sAGRXjDVbK/MbW5CkSIWb1rFrb86rb6R4EizCFGp+RNLgmLOKrqux+YYrFzDvWAQSkQaigdUEYHsbN2xiFPCXBMG+Acxsyo5jj2mP01bkaRleMSDEbm1vUTtBR+ne3E3RM3Rf1JxoSewsx5UIiQa5J6tcWfKMUS2FG5MpGVXqaEESIKVzbgtROYk6lJcqUyJSGAm1iKXF4ha4hxCf3e+qyft+onLVQktJrGpMxMVWPTVyHJKku/bzVQnSa4FDmo/pRGmoMN656bZzCsGooE28FMJmWr1Bweo4SUKN0WQUdWLcd8TBTKG9V9NN+0F9siQm7pilnarRGt5+PtNanPlh3LTpmM+SKVgKXmBVqoWVWCO72aUrU+GINlkiSacLTdVqdCwPRXQsDV4hTLDNNaEXSiHqFtFqF89quVfhw+6IhhVfrUQfz/YPtnFLwf+QG8+aH30+28sMeqo5JaF3taATLAPyJ2RVlY3Bkb7zjNxsttPGeRDSbbmhu3viNjicbsATKOEPXPbWoTny6EYETRNlNCRGE+VwSpsrH2gk6pnrVDDyNERlRVizLq0bIHy6skcdF8AQViN8wEmntBTM81p6ot2efzy+Cj+lYN8tBm/CFEp7oy3lbd/dnnLWTlI+oZ2p5bWpa6GbClTCgwtbSlhxNSJyA3Ae/uyAhMKfSbEFOKO0r4cxr/CYJngqEw5QLrTjf8DSO5rAou44CRoUMxvwaPBVtI4qAXavCQF+hNGNVsyQr1C7cqtdqGFD3SVEPBIU9BDH0fING67GjWZJSnlJpFgKlZIxTiDHwRMByFKwo8Wqa0E19h1fyW79z6DsjoUPOcan1+633VVQoLSDWh4O+qdGWiNpY1j2pNsu3Un9+UejB6fstqe7eEc9QzMdj0z0CXbw7R0qY6vueiI4pnIS2M1/ebs9RhISZVDoeGlKGU6r0mPPt92fvT4uzMRP1PuQRPAMHKI5nAsopQ6F2CyUHv/+V27N/2GrufrMzHRgrdCcL9XYLKni722CICLxUP0AXpMsAhjEjTrCYEGH57eT0c5swdWoU2+0rMeNi1k3bAfXmJbR5geL4hUuYIckvm93toL7d0oColwMxwb3+3uWWQ+/02iwqlnkgrt84t+JstjdM+fWbaBVBsaTQvZg0Pfw6lcYdrVbbOLDQpYxF4PWNujTtI8yI8HMYU8KkIej970pwDBtYHTeQ0bCqeFHXfMs0yPPmNXUwN8+PPmwFOpJPzSPQNU5n6kQIS9sU1AbbE1QrEN5agctnCE091faEKE69onkTDcX9Jx/OkY8xQptqKFvGWhh1vZAoQqotQF/9h1f1u7H2YXp2P0nLSddxcrlm7TU9+Rfvxe/wf4o2lKKMWvM+lAbudWg9udjq6c6TrrOkUq1a6OOXX0r956HX5C0r7fbKsiu+Ni0n3yumUFLhd0puFkTiqbtMLrdxz1h4DzzXoNnkYmiXOHtB1F9oU0rG5QDa0DRAJ8rP26K9QKcEQYcfGk4qSqFuBRBzNiamVXcEFa2vcUyjGp9rr9Pu7Le7e6iz87rbf71z+P93Oq+b5/sohPQ91SoxAt9DE2y6h+3OAWDTfb3bed3rL4aN1zd+1U3Aj1ynfBswpC/4ZaW5fhnLBdpse/iEWXq9qk0EF+BqfI2LCWchcaweCM1PXud8r7e5Z5kh3TbeksU6Lyr4Kxs16fcaXxF4RCDfEs6aNZ3y+poUcD01Q+QdL0gKpceLi6aDG5ohtNfv7+w78zQi30qR5jwc6PiycgR6c8QF/bvJ4s9DGlwU9G93AeKtpUhwqAw0NKSyqp33OrsHzd0sKcXxanv0miRJPZW9M4Ujx7Ft/ekGLhMQQEISFvr+7JG5yYYS7rDiyQQz3V63haj0YsO1FSuNp4GDkRQrxQKuPZJEh4y7ofOufhXC9vtv37w5PN4/OX3ztnN40Dk86faOj4+aN+C37oyVC7qzYsp0oVu7BcKXCH8QCJ2cTglcBflF6PWRbN0v6B8cvcNsjI7TWSI5iukwxeksQOeEuJvUMZWTbAjxTWMeYzbeHvPtYcyH22PeDbq72yINt0MYYFvZ9PB/wZj//G5nZ7/9bqdf7Umk1PL+XnsBMZx3/X8Cc1M4e3Nec/T797Z3+D2FObm8NWnhXgdzsix6rKNGbZ659uT5xS+5DtpC734pNPL37E3tywfr8sFWe21MyQLSi2Lx1LbkvE1ZWLj7ILUGhmMJx8ZovFAj0HbAX6mm42UTaQ84qB4VNtu5Dei2mvk1GhK42sYsnPBUf2yHNuLR3Oe80c8UQPhPGPvYdl4yZ5J63d1P2KsFuAmNY9PcEtzPCtRajzmkRE24kJ6g1nTCMXXNKxMsJ/Zh78EaANW/E5KkJIRbizbcHOQvwjUNfKLF7CjMbHpWAT6FXyDplPxt8+/ng6ej4EsPT+lYx2Waq4PC6JoihWE5bBbzlf4wqOObOai79YGwGwgFGGcpLIqerA6/BqRXK+Q/dytaMOiya3rryIq4St0nIqBMSM+JeieNwC2h30X2XUQjuy3CmGdRvgOO1UcbR5CiKZE4whLXb4r35lcdDBIWXoWAw9wewVE0gAcGdkj1ZEiE0MFm/h4pYA4vBXSKx17d23l3U369kylt42EYdXs7tZIlZ50zNTY6O3GBjhoRSyvDOD+jI7WG8BCPI5+FLagKs0DDa6lwJ7zz2KN2mFtZxJvdgj5oQLDbAXBEcCMtDENBbN0TiqbbxYNjisMJZWTg5XIvC4YZyk8LbwqFHx828KTksqDMG68pPEnKQcLem0HMQIvzR0rGua667OyFQWpntmIu4uEV7CMj507s5xqhoH8DPUqd93FMoPk3CDn9m5JYYsJTOdAnTa4fWfVCz9d2Mm6OGuDAakKF/G6+OFhBXOpzEKqDuR/ryOiRsv6VWnLOmUpJ0MVnA5nubekFZy292WzS5aczLWLRz+ji48nH1+g3fqMUqSlOdDWFXyuwFFQadLtag+afT8idURqEwPK00jR+msc2hs9/s89Uhj5jI+5ztzn8oB2qlXQeQ6vva9nZnI6nx+d+vrbt2SkCEopgNo0D85xOIMSp9jUzztr5m6U6xHxeo85GO2P+UhZq7NkhhpzHBLOGyzHKaQWpTDmbVOflIhhmNK5OWeUAp71sdA9Oup3DjWbgfDxHMIMfYVQPSMgjUrtvboNFyJTIcNIcGDuLLhbKZo5jr7IhSRmREDxhOPSf/nc14+a/O220qFrmgyKfP2+Xz/lLd8roAtDLcmN5LRIe1QuwhcSCR5uEa1dcddnVVFnNabDsTJ94hL6cndRPRJPKPIWvmk9x9qk6AzgyEhw+HNnyEauT8ahyPN1zMlsSa85kJdPx/hPaAevy9NWM//d//x9hamBVQTKnzX/c+1zzfh5McZJQNjbPbvxHQ6Hi4WTO4SlOqiBDYVPtmVw7uD3Y6oEXJIb0ovUD3UFWD3hKkpiGWBQrpqJ7c28+7pxNE5Ek5rNpyZFy/4nzcedMDC7WURY/OMrewHOmvkP/XXZiN6y5z4noCPJUpe65bBvN55VH04xJOiVb9mg3p2h+rn9yX9RAYH7MT3TnTqk7gfOx0QMdv+RbU9PBzB3k8fG3mA/lafgNI2llIh/AygpZysCrRYUuf6OMFqrLB7+LMdBtXvha2BoVZy5CU2LSe8NTV6uhPGeheEJx1tqfGE+npaiUWvQblly2/3JXJBTF/8nulL94zK8obuNM8ogKSH7Lt81/6V/RifllhvznkOcRvNMhWzOUrzcbONyQ864qzHOB9lgXc93u2ouNfPf2kscEsvCRA80rHFcPTWP/VSNATnE4MWWUJ7hQpMAE9YWYoSFBhMpJvhYRijJdEUXiVGaJ5Qk9EIU671NdH8HdS0AOSIJTPCVSoZyanElYayLBJNcd8OEL9bFlkvABNMi0wrEaQgod2XT2ST9hBBaiUQvSYyCJsgASpFxJAZSpJ67JHklSHmVhUyO8EYkhyM6dNWYCZSY6rG8DaAXMVwDolXCVFTc9mLbuAMpL2n8wmPSoLqbCkczjLKEOYah4SVk9hFk6J7Ftebi+fH6HJvxGR4tpQMyuABhvW8IwS0nT/Vp0x8yB548JgY2Y0+QGC7fJjFMLZ3Kizitb0yhFjEvnkSjfAG+YwiD/xbOUKcGN5UazG+F7XAaHPCVRNk3mqjFzdbi3JiPMBKzqmkxR2w5o6xtPSJzkB9Q8pcgLsJjHGLcCg9CRZ+PwEZoSIfA41y4h7N6AJvQZZcqRQaRFUIVIkHTwFGDBLbIHVM7MwBbR0ivlVzK0g921LhXjr4Ea+Z8lZeStKxcZcyhMOSQTHI/0sZQr+0nKxymeNtU1cRbRsj5VD9ydAMI6qeHsRuKjYt+H2+DxYQK9bJBV1GBUFx/s/zNlG6J6TRAVyzG6aPyFENQiVGuOX85OrHTXC+xMjbmomXzeFSK2szxWwAsWxCaYlaw7iCvFLBrElC1iMtyOXe7F3o7pcNsISPtf1G5Do5DFGPXCZG0rPUoB6+LJm2C5oEF0H+wWRMvvfpFbu7djU2sV3w+nO6D8hOXEVpm4DdLFiOMOnDnWc83OuhcWDTe/BWv8SGD9YzGwkkcC69NiYJkVfrhz6dxIi3ueTODSWc3J1FBG+2x3w6oui+ZHTf3OflBgc1ittDZAzYe6pCo+OsjME6EWaAXTLRDXaLjrAbbVgKtaeaFFC1onfVR3kXqso0iRzhhYemKAYo5Myoaask8AnJv7Fvg0AgMxm8aUXYnHgvIoL0pppjbB6gmnDGrom6PeEphHYFhvR+T6VkTUg4MEy8lj0tsHUs2t9xQV9odGgD+kfrgUA0MfDMj3uxGmD523AjIlBA1JzG+QUqWq0sFLZkL3kg3O9RURm1Vsy8pVjt/bhMKIPqB2miuVQaCz7nhKtnXhsTQIl7AkCsJXF25VEKMbKJQstb2IqHCZ1VE9/4wyFsrqkf0QqP7Fh4OYjwdCYpmJgfGf3BNXC69xrTvsHMpmmnps5xqJC+ueXj+asvXbACOw//KLC8ewjZGqv+NE63Sqrq2X51k5eczefoFOntswy0+Fl+zceRlOnZfmzHkw90QuEhbnpVwA2ItZfTSYWo1QJPe2g+7BXD8Pg4TuE69RSDMm7t4bD+ZSexgEwK5dBP4QJ9X+AE3gbQAWgfY69JoUZqkVOfXOrcUvoFwLoDuvnSi75vrSdNAoeng+NfLNe7Db74y6e/u9iOzt7oUHB2HU3dnBOIp2R71ov9MwNhFaUzjw/Nw9E5aGwlkY572cGZX+ToNr4lw3o6zGiimrNvfBehvCg0RMQwJ/tru9nV3z2Zyl7V4AJd0XIEDImUx5bLYk2JvGVLMH4ISSFKfhZFbFr84XWbsv5+N3B3g6gO1L1YvnPEvQWWGea2++OrT4StwBaQNHo4Mmpo2Cz5twRYkTFlh5B6Z6b46TDhyL9we3ISSwpreC0+wSvwnd2Jiyb4Fpi78A1e52zi4TdrDalV7QMytTzETC08UAL4SuFhJ/ZiLm44bgQj5c0coFOZuSkNDruoiHmkSvpc4zm4p114E25Fw+3FEWRQfh4f4uFtGo042GpEdGvb1of6S+6O3thk2Tt9QyK8j8Uww+W2LWH1aePhDz8X3Jd6eTbW4ek67UPlv+GKlV6+6gl53Vgm81aHRk6AEV+rGkftvH6nYZ4bDYqepRgLez3hP4PAr7gRhaZItoX5UY8AXQcEpWJqSrqapBZ0RIFyRYD/UcyI7SIZUpTl2Tz5BPFStDPJdRpUm5DEhKcDSA4hoSl+Lv5tU5Md3yzC+3pru7qM2523Petsq3dP17de/670tctq1us+HvClZQB45p0wGdpm0ss015/X8BAAD//2YU1sA=" -} diff --git a/journalbeat/input/config.go b/journalbeat/input/config.go deleted file mode 100644 index 6c202030b357..000000000000 --- a/journalbeat/input/config.go +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package input - -import ( - "time" - - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" - "github.com/elastic/beats/v7/journalbeat/pkg/journalread" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/fmtstr" - "github.com/elastic/beats/v7/libbeat/processors" -) - -// Config stores the options of an input. -type Config struct { - // Unique ID of the input for state persistence purposes. - ID string `config:"id"` - // Paths stores the paths to the journal files to be read. - Paths []string `config:"paths"` - // Backoff is the current interval to wait before - // attemting to read again from the journal. - Backoff time.Duration `config:"backoff" validate:"min=0,nonzero"` - // MaxBackoff is the limit of the backoff time. - MaxBackoff time.Duration `config:"max_backoff" validate:"min=0,nonzero"` - // Seek is the method to read from journals. - Seek journalread.SeekMode `config:"seek"` - // CursorSeekFallback sets where to seek if registry file is not available. - CursorSeekFallback journalread.SeekMode `config:"cursor_seek_fallback"` - // Matches store the key value pairs to match entries. - Matches []journalfield.Matcher `config:"include_matches"` - // SaveRemoteHostname defines if the original source of the entry needs to be saved. - SaveRemoteHostname bool `config:"save_remote_hostname"` - - // Fields and tags to add to events. - common.EventMetadata `config:",inline"` - // Processors to run on events. - Processors processors.PluginConfig `config:"processors"` - // ES output index pattern - Index fmtstr.EventFormatString `config:"index"` -} - -var ( - // DefaultConfig is the defaults for an inputs - DefaultConfig = Config{ - Backoff: 1 * time.Second, - MaxBackoff: 20 * time.Second, - Seek: journalread.SeekCursor, - CursorSeekFallback: journalread.SeekHead, - SaveRemoteHostname: false, - } -) diff --git a/journalbeat/input/input.go b/journalbeat/input/input.go deleted file mode 100644 index f1238d61c81e..000000000000 --- a/journalbeat/input/input.go +++ /dev/null @@ -1,274 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package input - -import ( - "context" - "fmt" - "strings" - "sync" - "syscall" - "time" - - "github.com/elastic/beats/v7/libbeat/processors/add_formatted_index" - "github.com/elastic/go-concert/timed" - - "github.com/elastic/beats/v7/libbeat/common/acker" - "github.com/elastic/beats/v7/libbeat/common/atomic" - "github.com/elastic/beats/v7/libbeat/common/fmtstr" - - "github.com/elastic/beats/v7/journalbeat/checkpoint" - "github.com/elastic/beats/v7/journalbeat/reader" - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/processors" -) - -// Input manages readers and forwards entries from journals. -type Input struct { - readers []*reader.Reader - done chan struct{} - config Config - client beat.Client - states map[string]checkpoint.JournalState - logger *logp.Logger - eventMeta common.EventMetadata - processors beat.ProcessorList -} - -// New returns a new Inout -func New( - c *common.Config, - info beat.Info, - done chan struct{}, - states map[string]checkpoint.JournalState, -) (*Input, error) { - config := DefaultConfig - if err := c.Unpack(&config); err != nil { - return nil, err - } - - logger := logp.NewLogger("input") - if config.ID != "" { - logger = logger.With("id", config.ID) - } - - var readers []*reader.Reader - if len(config.Paths) == 0 { - cfg := reader.Config{ - Path: reader.LocalSystemJournalID, // used to identify the state in the registry - Backoff: config.Backoff, - MaxBackoff: config.MaxBackoff, - Seek: config.Seek, - CursorSeekFallback: config.CursorSeekFallback, - Matches: config.Matches, - SaveRemoteHostname: config.SaveRemoteHostname, - CheckpointID: checkpointID(config.ID, reader.LocalSystemJournalID), - } - - state := states[cfg.CheckpointID] - r, err := reader.NewLocal(cfg, done, state, logger) - if err != nil { - return nil, fmt.Errorf("error creating reader for local journal: %+v", err) - } - readers = append(readers, r) - } - - for _, p := range config.Paths { - cfg := reader.Config{ - Path: p, - Backoff: config.Backoff, - MaxBackoff: config.MaxBackoff, - Seek: config.Seek, - CursorSeekFallback: config.CursorSeekFallback, - Matches: config.Matches, - SaveRemoteHostname: config.SaveRemoteHostname, - CheckpointID: checkpointID(config.ID, p), - } - - state := states[cfg.CheckpointID] - r, err := reader.New(cfg, done, state, logger) - if err != nil { - return nil, fmt.Errorf("error creating reader for journal: %+v", err) - } - readers = append(readers, r) - } - - inputProcessors, err := processorsForInput(info, config) - if err != nil { - return nil, err - } - - logger.Debugf("New input is created for paths %v", config.Paths) - - return &Input{ - readers: readers, - done: done, - config: config, - states: states, - logger: logger, - eventMeta: config.EventMetadata, - processors: inputProcessors, - }, nil -} - -// Run connects to the output, collects entries from the readers -// and then publishes the events. -func (i *Input) Run(pipeline beat.Pipeline) { - var err error - i.client, err = pipeline.ConnectWith(beat.ClientConfig{ - PublishMode: beat.GuaranteedSend, - Processing: beat.ProcessingConfig{ - EventMetadata: i.eventMeta, - Meta: nil, - Processor: i.processors, - }, - ACKHandler: acker.Counting(func(n int) { - i.logger.Debugw("journalbeat successfully published events", "event.count", n) - }), - }) - if err != nil { - i.logger.Error("Error connecting to output: %v", err) - return - } - - i.publishAll() -} - -// publishAll reads events from all readers and publishes them. -func (i *Input) publishAll() { - out := make(chan *beat.Event) - defer close(out) - - var wg sync.WaitGroup - defer wg.Wait() - for _, r := range i.readers { - wg.Add(1) - r := r - go func() { - defer wg.Done() - - suppressed := atomic.NewBool(false) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - for { - select { - case <-i.done: - return - default: - } - - event, err := r.Next() - if event == nil { - if err != nil { - if i.isErrSuppressed(ctx, err, suppressed) { - i.logger.Debugf("Error message suppressed: EBADMSG") - continue - } - i.logger.Errorf("Error while reading event: %v", err) - } - continue - } - - select { - case <-i.done: - case out <- event: - } - } - }() - } - - for { - select { - case <-i.done: - return - case e := <-out: - i.client.Publish(*e) - } - } -} - -// isErrSuppressed checks if the error is due to a corrupt journal. If yes, only the first error message -// is displayed and then it is suppressed for 5 seconds. -func (i *Input) isErrSuppressed(ctx context.Context, err error, suppressed *atomic.Bool) bool { - if strings.Contains(err.Error(), syscall.EBADMSG.Error()) { - if suppressed.Load() { - return true - } - - suppressed.Store(true) - go func(ctx context.Context, suppressed *atomic.Bool) { - if err := timed.Wait(ctx, 5*time.Second); err == nil { - suppressed.Store(false) - } - - }(ctx, suppressed) - } - - return false -} - -// Stop stops all readers of the input. -func (i *Input) Stop() { - for _, r := range i.readers { - r.Close() - } - i.client.Close() -} - -// Wait waits until all readers are done. -func (i *Input) Wait() { - i.Stop() -} - -func processorsForInput(beatInfo beat.Info, config Config) (*processors.Processors, error) { - procs := processors.NewList(nil) - - // Processor ordering is important: - // 1. Index configuration - if !config.Index.IsEmpty() { - staticFields := fmtstr.FieldsForBeat(beatInfo.Beat, beatInfo.Version) - timestampFormat, err := - fmtstr.NewTimestampFormatString(&config.Index, staticFields) - if err != nil { - return nil, err - } - indexProcessor := add_formatted_index.New(timestampFormat) - procs.AddProcessor(indexProcessor) - } - - // 2. User processors - userProcessors, err := processors.New(config.Processors) - if err != nil { - return nil, err - } - procs.AddProcessors(*userProcessors) - - return procs, nil -} - -// checkpointID returns the identifier used to track persistent state for the -// input. -func checkpointID(id, path string) string { - if id == "" { - return path - } - return "journald::" + path + "::" + id -} diff --git a/journalbeat/input/input_test.go b/journalbeat/input/input_test.go deleted file mode 100644 index eb925f1ef0b1..000000000000 --- a/journalbeat/input/input_test.go +++ /dev/null @@ -1,167 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package input - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" - - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/beat/events" - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/processors" - _ "github.com/elastic/beats/v7/libbeat/processors/actions" -) - -func TestProcessorsForInput(t *testing.T) { - testCases := map[string]struct { - beatInfo beat.Info - configStr string - event beat.Event - expectedFields map[string]string - }{ - "Simple static index": { - configStr: "index: 'test'", - expectedFields: map[string]string{ - "@metadata.raw_index": "test", - }, - }, - "Index with agent info + timestamp": { - beatInfo: beat.Info{Beat: "TestBeat", Version: "3.9.27"}, - configStr: "index: 'beat-%{[agent.name]}-%{[agent.version]}-%{+yyyy.MM.dd}'", - event: beat.Event{Timestamp: time.Date(1999, time.December, 31, 23, 0, 0, 0, time.UTC)}, - expectedFields: map[string]string{ - "@metadata.raw_index": "beat-TestBeat-3.9.27-1999.12.31", - }, - }, - "Set field in input config": { - configStr: `processors: [add_fields: {fields: {testField: inputConfig}}]`, - expectedFields: map[string]string{ - "fields.testField": "inputConfig", - }, - }, - } - for description, test := range testCases { - t.Run(description, func(t *testing.T) { - if test.event.Fields == nil { - test.event.Fields = common.MapStr{} - } - config, err := inputConfigFromString(test.configStr) - if err != nil { - t.Errorf("[%s] %v", description, err) - return - } - processors, err := processorsForInput(test.beatInfo, config) - if err != nil { - t.Errorf("[%s] %v", description, err) - return - } - processedEvent, err := processors.Run(&test.event) - // We don't check if err != nil, because we are testing the final outcome - // of running the processors, including when some of them fail. - if processedEvent == nil { - t.Errorf("[%s] Unexpected fatal error running processors: %v\n", - description, err) - } - for key, value := range test.expectedFields { - field, err := processedEvent.GetValue(key) - if err != nil { - t.Errorf("[%s] Couldn't get field %s from event: %v", description, key, err) - return - } - assert.Equal(t, field, value) - fieldStr, ok := field.(string) - if !ok { - // Note that requiring a string here is just to simplify the test setup, - // not a requirement of the underlying api. - t.Errorf("[%s] Field [%s] should be a string", description, key) - return - } - if fieldStr != value { - t.Errorf("[%s] Event field [%s]: expected [%s], got [%s]", description, key, value, fieldStr) - } - } - }) - } -} - -func TestProcessorsForInputIsFlat(t *testing.T) { - // This test is regrettable, and exists because of inconsistencies in - // processor handling between processors.Processors and processing.group - // (which implements beat.ProcessorList) -- see processorsForConfig for - // details. The upshot is that, for now, if the input configuration specifies - // processors, they must be returned as direct children of the resulting - // processors.Processors (rather than being collected in additional tree - // structure). - // This test should be removed once we have a more consistent mechanism for - // collecting and running processors. - configStr := `processors: -- add_fields: {fields: {testField: value}} -- add_fields: {fields: {testField2: stuff}}` - config, err := inputConfigFromString(configStr) - if err != nil { - t.Fatal(err) - } - processors, err := processorsForInput( - beat.Info{}, config) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, 2, len(processors.List)) -} - -// setRawIndex is a bare-bones processor to set the raw_index field to a -// constant string in the event metadata. It is used to test order of operations -// for processorsForConfig. -type setRawIndex struct { - indexStr string -} - -func (p *setRawIndex) Run(event *beat.Event) (*beat.Event, error) { - if event.Meta == nil { - event.Meta = common.MapStr{} - } - event.Meta[events.FieldMetaRawIndex] = p.indexStr - return event, nil -} - -func (p *setRawIndex) String() string { - return fmt.Sprintf("set_raw_index=%v", p.indexStr) -} - -// Helper function to convert from YML input string to an unpacked -// Config -func inputConfigFromString(s string) (Config, error) { - config := DefaultConfig - cfg, err := common.NewConfigFrom(s) - if err != nil { - return config, err - } - err = cfg.Unpack(&config) - return config, err -} - -// makeProcessors wraps one or more bare Processor objects in Processors. -func makeProcessors(procs ...processors.Processor) *processors.Processors { - procList := processors.NewList(nil) - procList.List = procs - return procList -} diff --git a/journalbeat/journalbeat.docker.yml b/journalbeat/journalbeat.docker.yml deleted file mode 100644 index 643eea808b83..000000000000 --- a/journalbeat/journalbeat.docker.yml +++ /dev/null @@ -1,12 +0,0 @@ -journalbeat.inputs: -- paths: [] - seek: cursor - -processors: - - add_cloud_metadata: ~ - - add_docker_metadata: ~ - -output.elasticsearch: - hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' - username: '${ELASTICSEARCH_USERNAME:}' - password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/journalbeat/journalbeat.reference.yml b/journalbeat/journalbeat.reference.yml deleted file mode 100644 index 19692cfec94b..000000000000 --- a/journalbeat/journalbeat.reference.yml +++ /dev/null @@ -1,1561 +0,0 @@ -###################### Journalbeat Configuration Example ######################### - -# This file is an example configuration file highlighting only the most common -# options. The journalbeat.reference.yml file from the same directory contains all the -# supported options with more comments. You can use it as a reference. -# -# You can find the full configuration reference here: -# https://www.elastic.co/guide/en/beats/journalbeat/index.html - -# For more available modules and options, please see the journalbeat.reference.yml sample -# configuration file. - -# ============================= Journalbeat inputs ============================= - -journalbeat.inputs: - # Paths that should be crawled and fetched. Possible values files and directories. - # When setting a directory, all journals under it are merged. - # When empty starts to read from local journal. -- paths: [] - - # An optional unique identifier for the input. By providing a unique `id` you - # can operate multiple inputs on the same journal. This allows each input's - # cursor to be persisted independently in the registry file. - #id: "" - - # The number of seconds to wait before trying to read again from journals. - #backoff: 1s - # The maximum number of seconds to wait before attempting to read again from journals. - #max_backoff: 20s - - # Position to start reading from journal. Valid values: head, tail, cursor - seek: cursor - # Fallback position if no cursor data is available. - #cursor_seek_fallback: head - - # Exact matching for field values of events. - # Matching for nginx entries: "systemd.unit=nginx" - #include_matches: [] - - # Set the option to preserve the remote hostname in entries from a remote journal. - # It is only needed when used with add_host_metadata, so the original host name - # does not get overwritten by the processor. - #save_remote_hostname: false - - # Optional fields that you can specify to add additional information to the - # output. Fields can be scalar values, arrays, dictionaries, or any nested - # combination of these. - #fields: - # env: staging - - -# ========================= Journalbeat global options ========================= -#journalbeat: - # Name of the registry file. If a relative path is used, it is considered relative to the - # data path. - #registry_file: registry - -# ======================= Elasticsearch template setting ======================= -setup.template.settings: - index.number_of_shards: 1 - #index.codec: best_compression - #_source.enabled: false - -# ================================== General =================================== - -# The name of the shipper that publishes the network data. It can be used to group -# all the transactions sent by a single shipper in the web interface. -# If this options is not defined, the hostname is used. -#name: - -# The tags of the shipper are included in their own field with each -# transaction published. Tags make it easy to group servers by different -# logical properties. -#tags: ["service-X", "web-tier"] - -# Optional fields that you can specify to add additional information to the -# output. Fields can be scalar values, arrays, dictionaries, or any nested -# combination of these. -#fields: -# env: staging - -# If this option is set to true, the custom fields are stored as top-level -# fields in the output document instead of being grouped under a fields -# sub-dictionary. Default is false. -#fields_under_root: false - -# Internal queue configuration for buffering events to be published. -#queue: - # Queue type by name (default 'mem') - # The memory queue will present all available events (up to the outputs - # bulk_max_size) to the output, the moment the output is ready to server - # another batch of events. - #mem: - # Max number of events the queue can buffer. - #events: 4096 - - # Hints the minimum number of events stored in the queue, - # before providing a batch of events to the outputs. - # The default value is set to 2048. - # A value of 0 ensures events are immediately available - # to be sent to the outputs. - #flush.min_events: 2048 - - # Maximum duration after which events are available to the outputs, - # if the number of events stored in the queue is < `flush.min_events`. - #flush.timeout: 1s - - # The disk queue stores incoming events on disk until the output is - # ready for them. This allows a higher event limit than the memory-only - # queue and lets pending events persist through a restart. - #disk: - # The directory path to store the queue's data. - #path: "${path.data}/diskqueue" - - # The maximum space the queue should occupy on disk. Depending on - # input settings, events that exceed this limit are delayed or discarded. - #max_size: 10GB - - # The maximum size of a single queue data file. Data in the queue is - # stored in smaller segments that are deleted after all their events - # have been processed. - #segment_size: 1GB - - # The number of events to read from disk to memory while waiting for - # the output to request them. - #read_ahead: 512 - - # The number of events to accept from inputs while waiting for them - # to be written to disk. If event data arrives faster than it - # can be written to disk, this setting prevents it from overflowing - # main memory. - #write_ahead: 2048 - - # The duration to wait before retrying when the queue encounters a disk - # write error. - #retry_interval: 1s - - # The maximum length of time to wait before retrying on a disk write - # error. If the queue encounters repeated errors, it will double the - # length of its retry interval each time, up to this maximum. - #max_retry_interval: 30s - -# Sets the maximum number of CPUs that can be executing simultaneously. The -# default is the number of logical CPUs available in the system. -#max_procs: - -# ================================= Processors ================================= - -# Processors are used to reduce the number of fields in the exported event or to -# enhance the event with external metadata. This section defines a list of -# processors that are applied one by one and the first one receives the initial -# event: -# -# event -> filter1 -> event1 -> filter2 ->event2 ... -# -# The supported processors are drop_fields, drop_event, include_fields, -# decode_json_fields, and add_cloud_metadata. -# -# For example, you can use the following processors to keep the fields that -# contain CPU load percentages, but remove the fields that contain CPU ticks -# values: -# -#processors: -# - include_fields: -# fields: ["cpu"] -# - drop_fields: -# fields: ["cpu.user", "cpu.system"] -# -# The following example drops the events that have the HTTP response code 200: -# -#processors: -# - drop_event: -# when: -# equals: -# http.code: 200 -# -# The following example renames the field a to b: -# -#processors: -# - rename: -# fields: -# - from: "a" -# to: "b" -# -# The following example tokenizes the string into fields: -# -#processors: -# - dissect: -# tokenizer: "%{key1} - %{key2}" -# field: "message" -# target_prefix: "dissect" -# -# The following example enriches each event with metadata from the cloud -# provider about the host machine. It works on EC2, GCE, DigitalOcean, -# Tencent Cloud, and Alibaba Cloud. -# -#processors: -# - add_cloud_metadata: ~ -# -# The following example enriches each event with the machine's local time zone -# offset from UTC. -# -#processors: -# - add_locale: -# format: offset -# -# The following example enriches each event with docker metadata, it matches -# given fields to an existing container id and adds info from that container: -# -#processors: -# - add_docker_metadata: -# host: "unix:///var/run/docker.sock" -# match_fields: ["system.process.cgroup.id"] -# match_pids: ["process.pid", "process.parent.pid"] -# match_source: true -# match_source_index: 4 -# match_short_id: false -# cleanup_timeout: 60 -# labels.dedot: false -# # To connect to Docker over TLS you must specify a client and CA certificate. -# #ssl: -# # certificate_authority: "/etc/pki/root/ca.pem" -# # certificate: "/etc/pki/client/cert.pem" -# # key: "/etc/pki/client/cert.key" -# -# The following example enriches each event with docker metadata, it matches -# container id from log path available in `source` field (by default it expects -# it to be /var/lib/docker/containers/*/*.log). -# -#processors: -# - add_docker_metadata: ~ -# -# The following example enriches each event with host metadata. -# -#processors: -# - add_host_metadata: ~ -# -# The following example enriches each event with process metadata using -# process IDs included in the event. -# -#processors: -# - add_process_metadata: -# match_pids: ["system.process.ppid"] -# target: system.process.parent -# -# The following example decodes fields containing JSON strings -# and replaces the strings with valid JSON objects. -# -#processors: -# - decode_json_fields: -# fields: ["field1", "field2", ...] -# process_array: false -# max_depth: 1 -# target: "" -# overwrite_keys: false -# -#processors: -# - decompress_gzip_field: -# from: "field1" -# to: "field2" -# ignore_missing: false -# fail_on_error: true -# -# The following example copies the value of message to message_copied -# -#processors: -# - copy_fields: -# fields: -# - from: message -# to: message_copied -# fail_on_error: true -# ignore_missing: false -# -# The following example truncates the value of message to 1024 bytes -# -#processors: -# - truncate_fields: -# fields: -# - message -# max_bytes: 1024 -# fail_on_error: false -# ignore_missing: true -# -# The following example preserves the raw message under event.original -# -#processors: -# - copy_fields: -# fields: -# - from: message -# to: event.original -# fail_on_error: false -# ignore_missing: true -# - truncate_fields: -# fields: -# - event.original -# max_bytes: 1024 -# fail_on_error: false -# ignore_missing: true -# -# The following example URL-decodes the value of field1 to field2 -# -#processors: -# - urldecode: -# fields: -# - from: "field1" -# to: "field2" -# ignore_missing: false -# fail_on_error: true - -# =============================== Elastic Cloud ================================ - -# These settings simplify using Journalbeat with the Elastic Cloud (https://cloud.elastic.co/). - -# The cloud.id setting overwrites the `output.elasticsearch.hosts` and -# `setup.kibana.host` options. -# You can find the `cloud.id` in the Elastic Cloud web UI. -#cloud.id: - -# The cloud.auth setting overwrites the `output.elasticsearch.username` and -# `output.elasticsearch.password` settings. The format is `:`. -#cloud.auth: - -# ================================== Outputs =================================== - -# Configure what output to use when sending the data collected by the beat. - -# ---------------------------- Elasticsearch Output ---------------------------- -output.elasticsearch: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Array of hosts to connect to. - # Scheme and port can be left out and will be set to the default (http and 9200) - # In case you specify and additional path, the scheme is required: http://localhost:9200/path - # IPv6 addresses should always be defined as: https://[2001:db8::1]:9200 - hosts: ["localhost:9200"] - - # Set gzip compression level. - #compression_level: 0 - - # Configure escaping HTML symbols in strings. - #escape_html: false - - # Protocol - either `http` (default) or `https`. - #protocol: "https" - - # Authentication credentials - either API key or username/password. - #api_key: "id:api_key" - #username: "elastic" - #password: "changeme" - - # Dictionary of HTTP parameters to pass within the URL with index operations. - #parameters: - #param1: value1 - #param2: value2 - - # Number of workers per Elasticsearch host. - #worker: 1 - - # Optional index name. The default is "journalbeat" plus date - # and generates [journalbeat-]YYYY.MM.DD keys. - # In case you modify this pattern you must update setup.template.name and setup.template.pattern accordingly. - #index: "journalbeat-%{[agent.version]}-%{+yyyy.MM.dd}" - - # Optional ingest pipeline. By default no pipeline will be used. - #pipeline: "" - - # Optional HTTP path - #path: "/elasticsearch" - - # Custom HTTP headers to add to each request - #headers: - # X-My-Header: Contents of the header - - # Proxy server URL - #proxy_url: http://proxy:3128 - - # Whether to disable proxy settings for outgoing connections. If true, this - # takes precedence over both the proxy_url field and any environment settings - # (HTTP_PROXY, HTTPS_PROXY). The default is false. - #proxy_disable: false - - # The number of times a particular Elasticsearch index operation is attempted. If - # the indexing operation doesn't succeed after this many retries, the events are - # dropped. The default is 3. - #max_retries: 3 - - # The maximum number of events to bulk in a single Elasticsearch bulk API index request. - # The default is 50. - #bulk_max_size: 50 - - # The number of seconds to wait before trying to reconnect to Elasticsearch - # after a network error. After waiting backoff.init seconds, the Beat - # tries to reconnect. If the attempt fails, the backoff timer is increased - # exponentially up to backoff.max. After a successful connection, the backoff - # timer is reset. The default is 1s. - #backoff.init: 1s - - # The maximum number of seconds to wait before attempting to connect to - # Elasticsearch after a network error. The default is 60s. - #backoff.max: 60s - - # Configure HTTP request timeout before failing a request to Elasticsearch. - #timeout: 90 - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. - #kerberos.enabled: true - - # Authentication type to use with Kerberos. Available options: keytab, password. - #kerberos.auth_type: password - - # Path to the keytab file. It is used when auth_type is set to keytab. - #kerberos.keytab: /etc/elastic.keytab - - # Path to the Kerberos configuration. - #kerberos.config_path: /etc/krb5.conf - - # Name of the Kerberos user. - #kerberos.username: elastic - - # Password of the Kerberos user. It is used when auth_type is set to password. - #kerberos.password: changeme - - # Kerberos realm. - #kerberos.realm: ELASTIC - - -# ------------------------------ Logstash Output ------------------------------- -#output.logstash: - # Boolean flag to enable or disable the output module. - #enabled: true - - # The Logstash hosts - #hosts: ["localhost:5044"] - - # Number of workers per Logstash host. - #worker: 1 - - # Set gzip compression level. - #compression_level: 3 - - # Configure escaping HTML symbols in strings. - #escape_html: false - - # Optional maximum time to live for a connection to Logstash, after which the - # connection will be re-established. A value of `0s` (the default) will - # disable this feature. - # - # Not yet supported for async connections (i.e. with the "pipelining" option set) - #ttl: 30s - - # Optionally load-balance events between Logstash hosts. Default is false. - #loadbalance: false - - # Number of batches to be sent asynchronously to Logstash while processing - # new batches. - #pipelining: 2 - - # If enabled only a subset of events in a batch of events is transferred per - # transaction. The number of events to be sent increases up to `bulk_max_size` - # if no error is encountered. - #slow_start: false - - # The number of seconds to wait before trying to reconnect to Logstash - # after a network error. After waiting backoff.init seconds, the Beat - # tries to reconnect. If the attempt fails, the backoff timer is increased - # exponentially up to backoff.max. After a successful connection, the backoff - # timer is reset. The default is 1s. - #backoff.init: 1s - - # The maximum number of seconds to wait before attempting to connect to - # Logstash after a network error. The default is 60s. - #backoff.max: 60s - - # Optional index name. The default index name is set to journalbeat - # in all lowercase. - #index: 'journalbeat' - - # SOCKS5 proxy server URL - #proxy_url: socks5://user:password@socks5-server:2233 - - # Resolve names locally when using a proxy server. Defaults to false. - #proxy_use_local_resolver: false - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - # The number of times to retry publishing an event after a publishing failure. - # After the specified number of retries, the events are typically dropped. - # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting - # and retry until all events are published. Set max_retries to a value less - # than 0 to retry until all events are published. The default is 3. - #max_retries: 3 - - # The maximum number of events to bulk in a single Logstash request. The - # default is 2048. - #bulk_max_size: 2048 - - # The number of seconds to wait for responses from the Logstash server before - # timing out. The default is 30s. - #timeout: 30s - -# -------------------------------- Kafka Output -------------------------------- -#output.kafka: - # Boolean flag to enable or disable the output module. - #enabled: true - - # The list of Kafka broker addresses from which to fetch the cluster metadata. - # The cluster metadata contain the actual Kafka brokers events are published - # to. - #hosts: ["localhost:9092"] - - # The Kafka topic used for produced events. The setting can be a format string - # using any event field. To set the topic from document type use `%{[type]}`. - #topic: beats - - # The Kafka event key setting. Use format string to create a unique event key. - # By default no event key will be generated. - #key: '' - - # The Kafka event partitioning strategy. Default hashing strategy is `hash` - # using the `output.kafka.key` setting or randomly distributes events if - # `output.kafka.key` is not configured. - #partition.hash: - # If enabled, events will only be published to partitions with reachable - # leaders. Default is false. - #reachable_only: false - - # Configure alternative event field names used to compute the hash value. - # If empty `output.kafka.key` setting will be used. - # Default value is empty list. - #hash: [] - - # Authentication details. Password is required if username is set. - #username: '' - #password: '' - - # SASL authentication mechanism used. Can be one of PLAIN, SCRAM-SHA-256 or SCRAM-SHA-512. - # Defaults to PLAIN when `username` and `password` are configured. - #sasl.mechanism: '' - - # Kafka version Journalbeat is assumed to run against. Defaults to the "1.0.0". - #version: '1.0.0' - - # Configure JSON encoding - #codec.json: - # Pretty-print JSON event - #pretty: false - - # Configure escaping HTML symbols in strings. - #escape_html: false - - # Metadata update configuration. Metadata contains leader information - # used to decide which broker to use when publishing. - #metadata: - # Max metadata request retry attempts when cluster is in middle of leader - # election. Defaults to 3 retries. - #retry.max: 3 - - # Wait time between retries during leader elections. Default is 250ms. - #retry.backoff: 250ms - - # Refresh metadata interval. Defaults to every 10 minutes. - #refresh_frequency: 10m - - # Strategy for fetching the topics metadata from the broker. Default is false. - #full: false - - # The number of concurrent load-balanced Kafka output workers. - #worker: 1 - - # The number of times to retry publishing an event after a publishing failure. - # After the specified number of retries, events are typically dropped. - # Some Beats, such as Filebeat, ignore the max_retries setting and retry until - # all events are published. Set max_retries to a value less than 0 to retry - # until all events are published. The default is 3. - #max_retries: 3 - - # The number of seconds to wait before trying to republish to Kafka - # after a network error. After waiting backoff.init seconds, the Beat - # tries to republish. If the attempt fails, the backoff timer is increased - # exponentially up to backoff.max. After a successful publish, the backoff - # timer is reset. The default is 1s. - #backoff.init: 1s - - # The maximum number of seconds to wait before attempting to republish to - # Kafka after a network error. The default is 60s. - #backoff.max: 60s - - # The maximum number of events to bulk in a single Kafka request. The default - # is 2048. - #bulk_max_size: 2048 - - # Duration to wait before sending bulk Kafka request. 0 is no delay. The default - # is 0. - #bulk_flush_frequency: 0s - - # The number of seconds to wait for responses from the Kafka brokers before - # timing out. The default is 30s. - #timeout: 30s - - # The maximum duration a broker will wait for number of required ACKs. The - # default is 10s. - #broker_timeout: 10s - - # The number of messages buffered for each Kafka broker. The default is 256. - #channel_buffer_size: 256 - - # The keep-alive period for an active network connection. If 0s, keep-alives - # are disabled. The default is 0 seconds. - #keep_alive: 0 - - # Sets the output compression codec. Must be one of none, snappy and gzip. The - # default is gzip. - #compression: gzip - - # Set the compression level. Currently only gzip provides a compression level - # between 0 and 9. The default value is chosen by the compression algorithm. - #compression_level: 4 - - # The maximum permitted size of JSON-encoded messages. Bigger messages will be - # dropped. The default value is 1000000 (bytes). This value should be equal to - # or less than the broker's message.max.bytes. - #max_message_bytes: 1000000 - - # The ACK reliability level required from broker. 0=no response, 1=wait for - # local commit, -1=wait for all replicas to commit. The default is 1. Note: - # If set to 0, no ACKs are returned by Kafka. Messages might be lost silently - # on error. - #required_acks: 1 - - # The configurable ClientID used for logging, debugging, and auditing - # purposes. The default is "beats". - #client_id: beats - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. - #kerberos.enabled: true - - # Authentication type to use with Kerberos. Available options: keytab, password. - #kerberos.auth_type: password - - # Path to the keytab file. It is used when auth_type is set to keytab. - #kerberos.keytab: /etc/security/keytabs/kafka.keytab - - # Path to the Kerberos configuration. - #kerberos.config_path: /etc/krb5.conf - - # The service name. Service principal name is contructed from - # service_name/hostname@realm. - #kerberos.service_name: kafka - - # Name of the Kerberos user. - #kerberos.username: elastic - - # Password of the Kerberos user. It is used when auth_type is set to password. - #kerberos.password: changeme - - # Kerberos realm. - #kerberos.realm: ELASTIC - - # Enables Kerberos FAST authentication. This may - # conflict with certain Active Directory configurations. - #kerberos.enable_krb5_fast: false - -# -------------------------------- Redis Output -------------------------------- -#output.redis: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Configure JSON encoding - #codec.json: - # Pretty print json event - #pretty: false - - # Configure escaping HTML symbols in strings. - #escape_html: false - - # The list of Redis servers to connect to. If load-balancing is enabled, the - # events are distributed to the servers in the list. If one server becomes - # unreachable, the events are distributed to the reachable servers only. - # The hosts setting supports redis and rediss urls with custom password like - # redis://:password@localhost:6379. - #hosts: ["localhost:6379"] - - # The name of the Redis list or channel the events are published to. The - # default is journalbeat. - #key: journalbeat - - # The password to authenticate to Redis with. The default is no authentication. - #password: - - # The Redis database number where the events are published. The default is 0. - #db: 0 - - # The Redis data type to use for publishing events. If the data type is list, - # the Redis RPUSH command is used. If the data type is channel, the Redis - # PUBLISH command is used. The default value is list. - #datatype: list - - # The number of workers to use for each host configured to publish events to - # Redis. Use this setting along with the loadbalance option. For example, if - # you have 2 hosts and 3 workers, in total 6 workers are started (3 for each - # host). - #worker: 1 - - # If set to true and multiple hosts or workers are configured, the output - # plugin load balances published events onto all Redis hosts. If set to false, - # the output plugin sends all events to only one host (determined at random) - # and will switch to another host if the currently selected one becomes - # unreachable. The default value is true. - #loadbalance: true - - # The Redis connection timeout in seconds. The default is 5 seconds. - #timeout: 5s - - # The number of times to retry publishing an event after a publishing failure. - # After the specified number of retries, the events are typically dropped. - # Some Beats, such as Filebeat, ignore the max_retries setting and retry until - # all events are published. Set max_retries to a value less than 0 to retry - # until all events are published. The default is 3. - #max_retries: 3 - - # The number of seconds to wait before trying to reconnect to Redis - # after a network error. After waiting backoff.init seconds, the Beat - # tries to reconnect. If the attempt fails, the backoff timer is increased - # exponentially up to backoff.max. After a successful connection, the backoff - # timer is reset. The default is 1s. - #backoff.init: 1s - - # The maximum number of seconds to wait before attempting to connect to - # Redis after a network error. The default is 60s. - #backoff.max: 60s - - # The maximum number of events to bulk in a single Redis request or pipeline. - # The default is 2048. - #bulk_max_size: 2048 - - # The URL of the SOCKS5 proxy to use when connecting to the Redis servers. The - # value must be a URL with a scheme of socks5://. - #proxy_url: - - # This option determines whether Redis hostnames are resolved locally when - # using a proxy. The default value is false, which means that name resolution - # occurs on the proxy server. - #proxy_use_local_resolver: false - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - -# -------------------------------- File Output --------------------------------- -#output.file: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Configure JSON encoding - #codec.json: - # Pretty-print JSON event - #pretty: false - - # Configure escaping HTML symbols in strings. - #escape_html: false - - # Path to the directory where to save the generated files. The option is - # mandatory. - #path: "/tmp/journalbeat" - - # Name of the generated files. The default is `journalbeat` and it generates - # files: `journalbeat`, `journalbeat.1`, `journalbeat.2`, etc. - #filename: journalbeat - - # Maximum size in kilobytes of each file. When this size is reached, and on - # every Journalbeat restart, the files are rotated. The default value is 10240 - # kB. - #rotate_every_kb: 10000 - - # Maximum number of files under path. When this number of files is reached, - # the oldest file is deleted and the rest are shifted from last to first. The - # default is 7 files. - #number_of_files: 7 - - # Permissions to use for file creation. The default is 0600. - #permissions: 0600 - - # Configure automatic file rotation on every startup. The default is true. - #rotate_on_startup: true -# ------------------------------- Console Output ------------------------------- -#output.console: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Configure JSON encoding - #codec.json: - # Pretty-print JSON event - #pretty: false - - # Configure escaping HTML symbols in strings. - #escape_html: false - -# =================================== Paths ==================================== - -# The home path for the Journalbeat installation. This is the default base path -# for all other path settings and for miscellaneous files that come with the -# distribution (for example, the sample dashboards). -# If not set by a CLI flag or in the configuration file, the default for the -# home path is the location of the binary. -#path.home: - -# The configuration path for the Journalbeat installation. This is the default -# base path for configuration files, including the main YAML configuration file -# and the Elasticsearch template file. If not set by a CLI flag or in the -# configuration file, the default for the configuration path is the home path. -#path.config: ${path.home} - -# The data path for the Journalbeat installation. This is the default base path -# for all the files in which Journalbeat needs to store its data. If not set by a -# CLI flag or in the configuration file, the default for the data path is a data -# subdirectory inside the home path. -#path.data: ${path.home}/data - -# The logs path for a Journalbeat installation. This is the default location for -# the Beat's log files. If not set by a CLI flag or in the configuration file, -# the default for the logs path is a logs subdirectory inside the home path. -#path.logs: ${path.home}/logs - -# ================================== Keystore ================================== - -# Location of the Keystore containing the keys and their sensitive values. -#keystore.path: "${path.config}/beats.keystore" - -# ================================= Dashboards ================================= - -# These settings control loading the sample dashboards to the Kibana index. Loading -# the dashboards are disabled by default and can be enabled either by setting the -# options here, or by using the `-setup` CLI flag or the `setup` command. -#setup.dashboards.enabled: false - -# The directory from where to read the dashboards. The default is the `kibana` -# folder in the home path. -#setup.dashboards.directory: ${path.home}/kibana - -# The URL from where to download the dashboards archive. It is used instead of -# the directory if it has a value. -#setup.dashboards.url: - -# The file archive (zip file) from where to read the dashboards. It is used instead -# of the directory when it has a value. -#setup.dashboards.file: - -# In case the archive contains the dashboards from multiple Beats, this lets you -# select which one to load. You can load all the dashboards in the archive by -# setting this to the empty string. -#setup.dashboards.beat: journalbeat - -# The name of the Kibana index to use for setting the configuration. Default is ".kibana" -#setup.dashboards.kibana_index: .kibana - -# The Elasticsearch index name. This overwrites the index name defined in the -# dashboards and index pattern. Example: testbeat-* -#setup.dashboards.index: - -# Always use the Kibana API for loading the dashboards instead of autodetecting -# how to install the dashboards by first querying Elasticsearch. -#setup.dashboards.always_kibana: false - -# If true and Kibana is not reachable at the time when dashboards are loaded, -# it will retry to reconnect to Kibana instead of exiting with an error. -#setup.dashboards.retry.enabled: false - -# Duration interval between Kibana connection retries. -#setup.dashboards.retry.interval: 1s - -# Maximum number of retries before exiting with an error, 0 for unlimited retrying. -#setup.dashboards.retry.maximum: 0 - -# ================================== Template ================================== - -# A template is used to set the mapping in Elasticsearch -# By default template loading is enabled and the template is loaded. -# These settings can be adjusted to load your own template or overwrite existing ones. - -# Set to false to disable template loading. -#setup.template.enabled: true - -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default journalbeat uses the legacy index templates. -#setup.template.type: legacy - -# Template name. By default the template name is "journalbeat-%{[agent.version]}" -# The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.name: "journalbeat-%{[agent.version]}" - -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. -# The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "journalbeat-%{[agent.version]}-*" - -# Path to fields.yml file to generate the template -#setup.template.fields: "${path.config}/fields.yml" - -# A list of fields to be added to the template and Kibana index pattern. Also -# specify setup.template.overwrite: true to overwrite the existing template. -#setup.template.append_fields: -#- name: field_name -# type: field_type - -# Enable JSON template loading. If this is enabled, the fields.yml is ignored. -#setup.template.json.enabled: false - -# Path to the JSON template file -#setup.template.json.path: "${path.config}/template.json" - -# Name under which the template is stored in Elasticsearch -#setup.template.json.name: "" - -# Overwrite existing template -# Do not enable this option for more than one instance of journalbeat as it might -# overload your Elasticsearch with too many update requests. -#setup.template.overwrite: false - -# Elasticsearch template settings -setup.template.settings: - - # A dictionary of settings to place into the settings.index dictionary - # of the Elasticsearch template. For more details, please check - # https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html - #index: - #number_of_shards: 1 - #codec: best_compression - - # A dictionary of settings for the _source field. For more details, please check - # https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html - #_source: - #enabled: false - -# ====================== Index Lifecycle Management (ILM) ====================== - -# Configure index lifecycle management (ILM). These settings create a write -# alias and add additional settings to the index template. When ILM is enabled, -# output.elasticsearch.index is ignored, and the write alias is used to set the -# index name. - -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'journalbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'journalbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" - -# Set the lifecycle policy name. The default policy name is -# 'beatname'. -#setup.ilm.policy_name: "mypolicy" - -# The path to a JSON file that contains a lifecycle policy configuration. Used -# to load your own lifecycle policy. -#setup.ilm.policy_file: - -# Disable the check for an existing lifecycle policy. The default is true. If -# you disable this check, set setup.ilm.overwrite: true so the lifecycle policy -# can be installed. -#setup.ilm.check_exists: true - -# Overwrite the lifecycle policy at startup. The default is false. -#setup.ilm.overwrite: false - -# =================================== Kibana =================================== - -# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API. -# This requires a Kibana endpoint configuration. -setup.kibana: - - # Kibana Host - # Scheme and port can be left out and will be set to the default (http and 5601) - # In case you specify and additional path, the scheme is required: http://localhost:5601/path - # IPv6 addresses should always be defined as: https://[2001:db8::1]:5601 - #host: "localhost:5601" - - # Optional protocol and basic auth credentials. - #protocol: "https" - #username: "elastic" - #password: "changeme" - - # Optional HTTP path - #path: "" - - # Optional Kibana space ID. - #space.id: "" - - # Custom HTTP headers to add to each request - #headers: - # X-My-Header: Contents of the header - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - -# ================================== Logging =================================== - -# There are four options for the log output: file, stderr, syslog, eventlog -# The file output is the default. - -# Sets log level. The default log level is info. -# Available log levels are: error, warning, info, debug -#logging.level: info - -# Enable debug output for selected components. To enable all selectors use ["*"] -# Other available selectors are "beat", "publisher", "service" -# Multiple selectors can be chained. -#logging.selectors: [ ] - -# Send all logging output to stderr. The default is false. -#logging.to_stderr: false - -# Send all logging output to syslog. The default is false. -#logging.to_syslog: false - -# Send all logging output to Windows Event Logs. The default is false. -#logging.to_eventlog: false - -# If enabled, Journalbeat periodically logs its internal metrics that have changed -# in the last period. For each metric that changed, the delta from the value at -# the beginning of the period is logged. Also, the total values for -# all non-zero internal metrics are logged on shutdown. The default is true. -#logging.metrics.enabled: true - -# The period after which to log the internal metrics. The default is 30s. -#logging.metrics.period: 30s - -# A list of metrics namespaces to report in the logs. Defaults to [stats]. -# `stats` contains general Beat metrics. `dataset` may be present in some -# Beats and contains module or input metrics. -#logging.metrics.namespaces: [stats] - -# Logging to rotating files. Set logging.to_files to false to disable logging to -# files. -logging.to_files: true -logging.files: - # Configure the path where the logs are written. The default is the logs directory - # under the home path (the binary location). - #path: /var/log/journalbeat - - # The name of the files where the logs are written to. - #name: journalbeat - - # Configure log file size limit. If limit is reached, log file will be - # automatically rotated - #rotateeverybytes: 10485760 # = 10MB - - # Number of rotated log files to keep. Oldest files will be deleted first. - #keepfiles: 7 - - # The permissions mask to apply when rotating log files. The default value is 0600. - # Must be a valid Unix-style file permissions mask expressed in octal notation. - #permissions: 0600 - - # Enable log file rotation on time intervals in addition to size-based rotation. - # Intervals must be at least 1s. Values of 1m, 1h, 24h, 7*24h, 30*24h, and 365*24h - # are boundary-aligned with minutes, hours, days, weeks, months, and years as - # reported by the local system clock. All other intervals are calculated from the - # Unix epoch. Defaults to disabled. - #interval: 0 - - # Rotate existing logs on startup rather than appending to the existing - # file. Defaults to true. - # rotateonstartup: true - -# ============================= X-Pack Monitoring ============================== -# Journalbeat can export internal metrics to a central Elasticsearch monitoring -# cluster. This requires xpack monitoring to be enabled in Elasticsearch. The -# reporting is disabled by default. - -# Set to true to enable the monitoring reporter. -#monitoring.enabled: false - -# Sets the UUID of the Elasticsearch cluster under which monitoring data for this -# Journalbeat instance will appear in the Stack Monitoring UI. If output.elasticsearch -# is enabled, the UUID is derived from the Elasticsearch cluster referenced by output.elasticsearch. -#monitoring.cluster_uuid: - -# Uncomment to send the metrics to Elasticsearch. Most settings from the -# Elasticsearch output are accepted here as well. -# Note that the settings should point to your Elasticsearch *monitoring* cluster. -# Any setting that is not set is automatically inherited from the Elasticsearch -# output configuration, so if you have the Elasticsearch output configured such -# that it is pointing to your Elasticsearch monitoring cluster, you can simply -# uncomment the following line. -#monitoring.elasticsearch: - - # Array of hosts to connect to. - # Scheme and port can be left out and will be set to the default (http and 9200) - # In case you specify and additional path, the scheme is required: http://localhost:9200/path - # IPv6 addresses should always be defined as: https://[2001:db8::1]:9200 - #hosts: ["localhost:9200"] - - # Set gzip compression level. - #compression_level: 0 - - # Protocol - either `http` (default) or `https`. - #protocol: "https" - - # Authentication credentials - either API key or username/password. - #api_key: "id:api_key" - #username: "beats_system" - #password: "changeme" - - # Dictionary of HTTP parameters to pass within the URL with index operations. - #parameters: - #param1: value1 - #param2: value2 - - # Custom HTTP headers to add to each request - #headers: - # X-My-Header: Contents of the header - - # Proxy server url - #proxy_url: http://proxy:3128 - - # The number of times a particular Elasticsearch index operation is attempted. If - # the indexing operation doesn't succeed after this many retries, the events are - # dropped. The default is 3. - #max_retries: 3 - - # The maximum number of events to bulk in a single Elasticsearch bulk API index request. - # The default is 50. - #bulk_max_size: 50 - - # The number of seconds to wait before trying to reconnect to Elasticsearch - # after a network error. After waiting backoff.init seconds, the Beat - # tries to reconnect. If the attempt fails, the backoff timer is increased - # exponentially up to backoff.max. After a successful connection, the backoff - # timer is reset. The default is 1s. - #backoff.init: 1s - - # The maximum number of seconds to wait before attempting to connect to - # Elasticsearch after a network error. The default is 60s. - #backoff.max: 60s - - # Configure HTTP request timeout before failing an request to Elasticsearch. - #timeout: 90 - - # Use SSL settings for HTTPS. - #ssl.enabled: true - - # Controls the verification of certificates. Valid values are: - # * full, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. - # * strict, which verifies that the provided certificate is signed by a trusted - # authority (CA) and also verifies that the server's hostname (or IP address) - # matches the names identified within the certificate. If the Subject Alternative - # Name is empty, it returns an error. - # * certificate, which verifies that the provided certificate is signed by a - # trusted authority (CA), but does not perform any hostname verification. - # * none, which performs no verification of the server's certificate. This - # mode disables many of the security benefits of SSL/TLS and should only be used - # after very careful consideration. It is primarily intended as a temporary - # diagnostic mechanism when attempting to resolve TLS errors; its use in - # production environments is strongly discouraged. - # The default value is full. - #ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions from 1.1 - # up to 1.3 are enabled. - #ssl.supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] - - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client certificate key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the certificate key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE-based cipher suites - #ssl.curve_types: [] - - # Configure what types of renegotiation are supported. Valid options are - # never, once, and freely. Default is never. - #ssl.renegotiation: never - - # Configure a pin that can be used to do extra validation of the verified certificate chain, - # this allow you to ensure that a specific certificate is used to validate the chain of trust. - # - # The pin is a base64 encoded string of the SHA-256 fingerprint. - #ssl.ca_sha256: "" - - # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. - #kerberos.enabled: true - - # Authentication type to use with Kerberos. Available options: keytab, password. - #kerberos.auth_type: password - - # Path to the keytab file. It is used when auth_type is set to keytab. - #kerberos.keytab: /etc/elastic.keytab - - # Path to the Kerberos configuration. - #kerberos.config_path: /etc/krb5.conf - - # Name of the Kerberos user. - #kerberos.username: elastic - - # Password of the Kerberos user. It is used when auth_type is set to password. - #kerberos.password: changeme - - # Kerberos realm. - #kerberos.realm: ELASTIC - - #metrics.period: 10s - #state.period: 1m - -# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` -# setting. You can find the value for this setting in the Elastic Cloud web UI. -#monitoring.cloud.id: - -# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` -# and `monitoring.elasticsearch.password` settings. The format is `:`. -#monitoring.cloud.auth: - -# =============================== HTTP Endpoint ================================ - -# Each beat can expose internal metrics through a HTTP endpoint. For security -# reasons the endpoint is disabled by default. This feature is currently experimental. -# Stats can be access through http://localhost:5066/stats . For pretty JSON output -# append ?pretty to the URL. - -# Defines if the HTTP endpoint is enabled. -#http.enabled: false - -# The HTTP endpoint will bind to this hostname, IP address, unix socket or named pipe. -# When using IP addresses, it is recommended to only use localhost. -#http.host: localhost - -# Port on which the HTTP endpoint will bind. Default is 5066. -#http.port: 5066 - -# Define which user should be owning the named pipe. -#http.named_pipe.user: - -# Define which the permissions that should be applied to the named pipe, use the Security -# Descriptor Definition Language (SDDL) to define the permission. This option cannot be used with -# `http.user`. -#http.named_pipe.security_descriptor: - -# Defines if the HTTP pprof endpoints are enabled. -# It is recommended that this is only enabled on localhost as these endpoints may leak data. -#http.pprof.enabled: false - -# ============================== Process Security ============================== - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -#seccomp.enabled: true - -# ============================== Instrumentation =============================== - -# Instrumentation support for the journalbeat. -#instrumentation: - # Set to true to enable instrumentation of journalbeat. - #enabled: false - - # Environment in which journalbeat is running on (eg: staging, production, etc.) - #environment: "" - - # APM Server hosts to report instrumentation results to. - #hosts: - # - http://localhost:8200 - - # API Key for the APM Server(s). - # If api_key is set then secret_token will be ignored. - #api_key: - - # Secret token for the APM Server(s). - #secret_token: - - # Enable profiling of the server, recording profile samples as events. - # - # This feature is experimental. - #profiling: - #cpu: - # Set to true to enable CPU profiling. - #enabled: false - #interval: 60s - #duration: 10s - #heap: - # Set to true to enable heap profiling. - #enabled: false - #interval: 60s - -# ================================= Migration ================================== - -# This allows to enable 6.7 migration aliases -#migration.6_to_7.enabled: false - diff --git a/journalbeat/journalbeat.yml b/journalbeat/journalbeat.yml deleted file mode 100644 index e049dbc908e0..000000000000 --- a/journalbeat/journalbeat.yml +++ /dev/null @@ -1,217 +0,0 @@ -###################### Journalbeat Configuration Example ######################### - -# This file is an example configuration file highlighting only the most common -# options. The journalbeat.reference.yml file from the same directory contains all the -# supported options with more comments. You can use it as a reference. -# -# You can find the full configuration reference here: -# https://www.elastic.co/guide/en/beats/journalbeat/index.html - -# For more available modules and options, please see the journalbeat.reference.yml sample -# configuration file. - -# ============================= Journalbeat inputs ============================= - -journalbeat.inputs: - # Paths that should be crawled and fetched. Possible values files and directories. - # When setting a directory, all journals under it are merged. - # When empty starts to read from local journal. -- paths: [] - - # An optional unique identifier for the input. By providing a unique `id` you - # can operate multiple inputs on the same journal. This allows each input's - # cursor to be persisted independently in the registry file. - #id: "" - - # The number of seconds to wait before trying to read again from journals. - #backoff: 1s - # The maximum number of seconds to wait before attempting to read again from journals. - #max_backoff: 20s - - # Position to start reading from journal. Valid values: head, tail, cursor - seek: cursor - # Fallback position if no cursor data is available. - #cursor_seek_fallback: head - - # Exact matching for field values of events. - # Matching for nginx entries: "systemd.unit=nginx" - #include_matches: [] - - # Optional fields that you can specify to add additional information to the - # output. Fields can be scalar values, arrays, dictionaries, or any nested - # combination of these. - #fields: - # env: staging - - -# ========================= Journalbeat global options ========================= -#journalbeat: - # Name of the registry file. If a relative path is used, it is considered relative to the - # data path. - #registry_file: registry - -# ======================= Elasticsearch template setting ======================= -setup.template.settings: - index.number_of_shards: 1 - #index.codec: best_compression - #_source.enabled: false - -# ================================== General =================================== - -# The name of the shipper that publishes the network data. It can be used to group -# all the transactions sent by a single shipper in the web interface. -#name: - -# The tags of the shipper are included in their own field with each -# transaction published. -#tags: ["service-X", "web-tier"] - -# Optional fields that you can specify to add additional information to the -# output. -#fields: -# env: staging - -# ================================= Dashboards ================================= -# These settings control loading the sample dashboards to the Kibana index. Loading -# the dashboards is disabled by default and can be enabled either by setting the -# options here or by using the `setup` command. -#setup.dashboards.enabled: false - -# The URL from where to download the dashboards archive. By default this URL -# has a value which is computed based on the Beat name and version. For released -# versions, this URL points to the dashboard archive on the artifacts.elastic.co -# website. -#setup.dashboards.url: - -# =================================== Kibana =================================== - -# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API. -# This requires a Kibana endpoint configuration. -setup.kibana: - - # Kibana Host - # Scheme and port can be left out and will be set to the default (http and 5601) - # In case you specify and additional path, the scheme is required: http://localhost:5601/path - # IPv6 addresses should always be defined as: https://[2001:db8::1]:5601 - #host: "localhost:5601" - - # Kibana Space ID - # ID of the Kibana Space into which the dashboards should be loaded. By default, - # the Default Space will be used. - #space.id: - -# =============================== Elastic Cloud ================================ - -# These settings simplify using Journalbeat with the Elastic Cloud (https://cloud.elastic.co/). - -# The cloud.id setting overwrites the `output.elasticsearch.hosts` and -# `setup.kibana.host` options. -# You can find the `cloud.id` in the Elastic Cloud web UI. -#cloud.id: - -# The cloud.auth setting overwrites the `output.elasticsearch.username` and -# `output.elasticsearch.password` settings. The format is `:`. -#cloud.auth: - -# ================================== Outputs =================================== - -# Configure what output to use when sending the data collected by the beat. - -# ---------------------------- Elasticsearch Output ---------------------------- -output.elasticsearch: - # Array of hosts to connect to. - hosts: ["localhost:9200"] - - # Protocol - either `http` (default) or `https`. - #protocol: "https" - - # Authentication credentials - either API key or username/password. - #api_key: "id:api_key" - #username: "elastic" - #password: "changeme" - -# ------------------------------ Logstash Output ------------------------------- -#output.logstash: - # The Logstash hosts - #hosts: ["localhost:5044"] - - # Optional SSL. By default is off. - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client Certificate Key - #ssl.key: "/etc/pki/client/cert.key" - -# ================================= Processors ================================= - -# Configure processors to enhance or manipulate events generated by the beat. - -processors: - - add_host_metadata: ~ - - add_cloud_metadata: ~ - - add_docker_metadata: ~ - - -# ================================== Logging =================================== - -# Sets log level. The default log level is info. -# Available log levels are: error, warning, info, debug -#logging.level: debug - -# At debug level, you can selectively enable logging only for some components. -# To enable all selectors use ["*"]. Examples of other selectors are "beat", -# "publisher", "service". -#logging.selectors: ["*"] - -# ============================= X-Pack Monitoring ============================== -# Journalbeat can export internal metrics to a central Elasticsearch monitoring -# cluster. This requires xpack monitoring to be enabled in Elasticsearch. The -# reporting is disabled by default. - -# Set to true to enable the monitoring reporter. -#monitoring.enabled: false - -# Sets the UUID of the Elasticsearch cluster under which monitoring data for this -# Journalbeat instance will appear in the Stack Monitoring UI. If output.elasticsearch -# is enabled, the UUID is derived from the Elasticsearch cluster referenced by output.elasticsearch. -#monitoring.cluster_uuid: - -# Uncomment to send the metrics to Elasticsearch. Most settings from the -# Elasticsearch output are accepted here as well. -# Note that the settings should point to your Elasticsearch *monitoring* cluster. -# Any setting that is not set is automatically inherited from the Elasticsearch -# output configuration, so if you have the Elasticsearch output configured such -# that it is pointing to your Elasticsearch monitoring cluster, you can simply -# uncomment the following line. -#monitoring.elasticsearch: - -# ============================== Instrumentation =============================== - -# Instrumentation support for the journalbeat. -#instrumentation: - # Set to true to enable instrumentation of journalbeat. - #enabled: false - - # Environment in which journalbeat is running on (eg: staging, production, etc.) - #environment: "" - - # APM Server hosts to report instrumentation results to. - #hosts: - # - http://localhost:8200 - - # API Key for the APM Server(s). - # If api_key is set then secret_token will be ignored. - #api_key: - - # Secret token for the APM Server(s). - #secret_token: - - -# ================================= Migration ================================== - -# This allows to enable 6.7 migration aliases -#migration.6_to_7.enabled: true - diff --git a/journalbeat/magefile.go b/journalbeat/magefile.go deleted file mode 100644 index 0ba6de46d4b1..000000000000 --- a/journalbeat/magefile.go +++ /dev/null @@ -1,171 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build mage -// +build mage - -package main - -import ( - "fmt" - "runtime" - "strings" - "time" - - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" - - devtools "github.com/elastic/beats/v7/dev-tools/mage" - - // mage:import - "github.com/elastic/beats/v7/dev-tools/mage/target/common" - // mage:import - _ "github.com/elastic/beats/v7/dev-tools/mage/target/integtest/notests" - // mage:import - _ "github.com/elastic/beats/v7/dev-tools/mage/target/unittest" - // mage:import - _ "github.com/elastic/beats/v7/dev-tools/mage/target/test" -) - -func init() { - common.RegisterCheckDeps(Update) - - devtools.BeatDescription = "Journalbeat ships systemd journal entries to Elasticsearch or Logstash." - - devtools.Platforms = devtools.Platforms.Filter("linux !linux/ppc64 !linux/mips64") -} - -const ( - libsystemdDevPkgName = "libsystemd-dev" - libsystemdPkgName = "libsystemd0" - libgcryptPkgName = "libgcrypt20" -) - -// Build builds the Beat binary. -func Build() error { - return devtools.Build(devtools.DefaultBuildArgs()) -} - -// GolangCrossBuild build the Beat binary inside of the golang-builder. -// Do not use directly, use crossBuild instead. -func GolangCrossBuild() error { - mg.Deps(deps.Installer(devtools.Platform.Name)) - return devtools.GolangCrossBuild(devtools.DefaultGolangCrossBuildArgs()) -} - -// BuildGoDaemon builds the go-daemon binary (use crossBuildGoDaemon). -func BuildGoDaemon() error { - return devtools.BuildGoDaemon() -} - -// CrossBuild cross-builds the beat for all target platforms. -func CrossBuild() error { - return devtools.CrossBuild(devtools.ImageSelector(selectImage)) -} - -// CrossBuildXPack cross-builds the beat with XPack for all target platforms. -func CrossBuildXPack() error { - return devtools.CrossBuildXPack(devtools.ImageSelector(selectImage)) -} - -// CrossBuildGoDaemon cross-builds the go-daemon binary using Docker. -func CrossBuildGoDaemon() error { - return devtools.CrossBuildGoDaemon(devtools.ImageSelector(selectImage)) -} - -// Package packages the Beat for distribution. -// Use SNAPSHOT=true to build snapshots. -// Use PLATFORMS to control the target platforms. -func Package() { - start := time.Now() - defer func() { fmt.Println("package ran for", time.Since(start)) }() - - devtools.UseElasticBeatPackaging() - - mg.Deps(Update) - mg.Deps(CrossBuild, CrossBuildXPack, CrossBuildGoDaemon) - mg.SerialDeps(devtools.Package, TestPackages) -} - -// TestPackages tests the generated packages (i.e. file modes, owners, groups). -func TestPackages() error { - return devtools.TestPackages() -} - -// Update updates the generated files (aka make update). -func Update() error { - return sh.Run("make", "update") -} - -// Fields generates a fields.yml for the Beat. -func Fields() error { - return devtools.GenerateFieldsYAML() -} - -// ----------------------------------------------------------------------------- -// Customizations specific to Journalbeat. -// - Install required headers on builders for different architectures. - -var ( - journaldPlatforms = []devtools.PlatformDescription{ - devtools.Linux386, devtools.LinuxAMD64, - devtools.LinuxARM64, devtools.LinuxARM5, devtools.LinuxARM6, devtools.LinuxARM7, - devtools.LinuxMIPS, devtools.LinuxMIPSLE, devtools.LinuxMIPS64LE, - devtools.LinuxPPC64LE, - devtools.LinuxS390x, - } - - deps = devtools.NewPackageInstaller(). - AddEach(journaldPlatforms, libsystemdDevPkgName). - Add(devtools.Linux386, libsystemdPkgName, libgcryptPkgName) -) - -func selectImage(platform string) (string, error) { - tagSuffix := "main" - - switch { - case strings.HasPrefix(platform, "linux/armv7"): - tagSuffix = "armhf" - case strings.HasPrefix(platform, "linux/arm"): - tagSuffix = "arm" - if runtime.GOARCH == "arm64" { - tagSuffix = "base-arm-debian9" - } - case strings.HasPrefix(platform, "linux/mips"): - tagSuffix = "mips" - case strings.HasPrefix(platform, "linux/ppc"): - tagSuffix = "ppc" - case platform == "linux/s390x": - tagSuffix = "s390x" - case strings.HasPrefix(platform, "linux"): - tagSuffix = "main-debian8" - } - - goVersion, err := devtools.GoVersion() - if err != nil { - return "", err - } - - return devtools.BeatsCrossBuildImage + ":" + goVersion + "-" + tagSuffix, nil -} - -// Config generates both the short/reference/docker configs. -func Config() error { - p := devtools.DefaultConfigFileParams() - p.Templates = append(p.Templates, devtools.OSSBeatDir("_meta/config/*.tmpl")) - return devtools.Config(devtools.AllConfigTypes, p, ".") -} diff --git a/journalbeat/main.go b/journalbeat/main.go deleted file mode 100644 index 56c0e645406b..000000000000 --- a/journalbeat/main.go +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package main - -import ( - "os" - - "github.com/elastic/beats/v7/journalbeat/cmd" -) - -func main() { - if err := cmd.RootCmd.Execute(); err != nil { - os.Exit(1) - } -} diff --git a/journalbeat/main_test.go b/journalbeat/main_test.go deleted file mode 100644 index 7881c30d52cb..000000000000 --- a/journalbeat/main_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package main - -// This file is mandatory as otherwise the journalbeat.test binary is not generated correctly. - -import ( - "flag" - "testing" - - "github.com/elastic/beats/v7/journalbeat/cmd" - "github.com/elastic/beats/v7/libbeat/tests/system/template" -) - -var systemTest *bool - -func init() { - testing.Init() - systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") - - cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) - cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) -} - -// Test started when the test binary is started. Only calls main. -func TestSystem(t *testing.T) { - if *systemTest { - main() - } -} - -func TestTemplate(t *testing.T) { - template.TestTemplate(t, cmd.Name, false) -} diff --git a/journalbeat/reader/config.go b/journalbeat/reader/config.go deleted file mode 100644 index e559681aea79..000000000000 --- a/journalbeat/reader/config.go +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package reader - -import ( - "time" - - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" - "github.com/elastic/beats/v7/journalbeat/pkg/journalread" -) - -// Config stores the options of a reder. -type Config struct { - // Path is the path to the journal file. - Path string - // Seek specifies the seeking stategy. - // Possible values: head, tail, cursor. - Seek journalread.SeekMode - // CursorSeekFallback sets where to seek if registry file is not available. - CursorSeekFallback journalread.SeekMode - // MaxBackoff is the limit of the backoff time. - MaxBackoff time.Duration - // Backoff is the current interval to wait before - // attemting to read again from the journal. - Backoff time.Duration - // Matches store the key value pairs to match entries. - Matches []journalfield.Matcher - // SaveRemoteHostname defines if the original source of the entry needs to be saved. - SaveRemoteHostname bool - // CheckpointID is the identifier to use when persisting state. - CheckpointID string -} - -const ( - // LocalSystemJournalID is the ID of the local system journal. - LocalSystemJournalID = "LOCAL_SYSTEM_JOURNAL" -) diff --git a/journalbeat/reader/fields.go b/journalbeat/reader/fields.go deleted file mode 100644 index 7076a92a19de..000000000000 --- a/journalbeat/reader/fields.go +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build linux && cgo -// +build linux,cgo - -package reader diff --git a/journalbeat/reader/journal.go b/journalbeat/reader/journal.go deleted file mode 100644 index 93fc39633486..000000000000 --- a/journalbeat/reader/journal.go +++ /dev/null @@ -1,151 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build linux && cgo -// +build linux,cgo - -package reader - -import ( - "time" - - "github.com/coreos/go-systemd/v22/sdjournal" - - "github.com/elastic/beats/v7/journalbeat/checkpoint" - "github.com/elastic/beats/v7/journalbeat/cmd/instance" - "github.com/elastic/beats/v7/journalbeat/pkg/journalfield" - "github.com/elastic/beats/v7/journalbeat/pkg/journalread" - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/common/backoff" - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/go-concert/ctxtool" -) - -// Reader reads entries from journal(s). -type Reader struct { - r *journalread.Reader - journal *sdjournal.Journal - config Config - ctx ctxtool.CancelContext - logger *logp.Logger - backoff backoff.Backoff -} - -// New creates a new journal reader and moves the FP to the configured position. -func New(c Config, done <-chan struct{}, state checkpoint.JournalState, logger *logp.Logger) (*Reader, error) { - return newReader(c.Path, c, done, state, logger) -} - -// NewLocal creates a reader to read form the local journal and moves the FP -// to the configured position. -func NewLocal(c Config, done <-chan struct{}, state checkpoint.JournalState, logger *logp.Logger) (*Reader, error) { - return newReader(LocalSystemJournalID, c, done, state, logger) -} - -func newReader(path string, c Config, done <-chan struct{}, state checkpoint.JournalState, logger *logp.Logger) (*Reader, error) { - logger = logger.With("path", path) - backoff := backoff.NewExpBackoff(done, c.Backoff, c.MaxBackoff) - - var journal *sdjournal.Journal - r, err := journalread.Open(logger, c.Path, backoff, func(j *sdjournal.Journal) error { - journal = j - return journalfield.ApplyMatchersOr(j, c.Matches) - }) - if err != nil { - return nil, err - } - - if err := r.Seek(seekBy(logger, c, state)); err != nil { - logger.Error("Continue from current position. Seek failed with: %v", err) - } - - logger.Debug("New journal is opened for reading") - instance.AddJournalToMonitor(c.Path, journal) - - return &Reader{ - r: r, - journal: journal, - config: c, - ctx: ctxtool.WithCancelContext(ctxtool.FromChannel(done)), - logger: logger, - backoff: backoff, - }, nil -} - -func seekBy(log *logp.Logger, c Config, state checkpoint.JournalState) (journalread.SeekMode, string) { - mode := c.Seek - if mode == journalread.SeekCursor && state.Cursor == "" { - mode = c.CursorSeekFallback - if mode != journalread.SeekHead && mode != journalread.SeekTail { - log.Error("Invalid option for cursor_seek_fallback") - mode = journalread.SeekHead - } - } - return mode, state.Cursor -} - -// Close closes the underlying journal reader. -func (r *Reader) Close() { - instance.StopMonitoringJournal(r.config.Path) - r.ctx.Cancel() - r.r.Close() -} - -// Next waits until a new event shows up and returns it. -// It blocks until an event is returned or an error occurs. -func (r *Reader) Next() (*beat.Event, error) { - entry, err := r.r.Next(r.ctx) - if err != nil { - return nil, err - } - - event := toEvent(r.logger, r.config.CheckpointID, entry, r.config.SaveRemoteHostname) - return event, nil -} - -// toEvent creates a beat.Event from journal entries. -func toEvent(logger *logp.Logger, id string, entry *sdjournal.JournalEntry, saveRemoteHostname bool) *beat.Event { - created := time.Now() - fields := journalfield.NewConverter(logger, nil).Convert(entry.Fields) - fields.Put("event.kind", "event") - - // if entry is coming from a remote journal, add_host_metadata overwrites the source hostname, so it - // has to be copied to a different field - if saveRemoteHostname { - remoteHostname, err := fields.GetValue("host.hostname") - if err == nil { - fields.Put("log.source.address", remoteHostname) - } - } - - state := checkpoint.JournalState{ - Path: id, - Cursor: entry.Cursor, - RealtimeTimestamp: entry.RealtimeTimestamp, - MonotonicTimestamp: entry.MonotonicTimestamp, - } - - fields.Put("event.created", created) - receivedByJournal := time.Unix(0, int64(entry.RealtimeTimestamp)*1000) - - event := beat.Event{ - Timestamp: receivedByJournal, - Fields: fields, - Private: state, - } - return &event -} diff --git a/journalbeat/reader/journal_other.go b/journalbeat/reader/journal_other.go deleted file mode 100644 index a44d1a07db0c..000000000000 --- a/journalbeat/reader/journal_other.go +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !linux || !cgo -// +build !linux !cgo - -package reader - -import ( - "errors" - - "github.com/elastic/beats/v7/journalbeat/checkpoint" - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/logp" -) - -// Reader stub for non linux builds. -type Reader struct{} - -// New creates a new journal reader and moves the FP to the configured position. -// -// Note: New fails if journalbeat is not compiled for linux -func New(c Config, done chan struct{}, state checkpoint.JournalState, logger *logp.Logger) (*Reader, error) { - return nil, errors.New("journald reader only supported on linux") -} - -// NewLocal creates a reader to read form the local journal and moves the FP -// to the configured position. -// -// Note: NewLocal fails if journalbeat is not compiled for linux -func NewLocal(c Config, done chan struct{}, state checkpoint.JournalState, logger *logp.Logger) (*Reader, error) { - return nil, errors.New("journald reader only supported on linux") -} - -// Next waits until a new event shows up and returns it. -// It blocks until an event is returned or an error occurs. -func (r *Reader) Next() (*beat.Event, error) { - return nil, nil -} - -// Close closes the underlying journal reader. -func (r *Reader) Close() {} diff --git a/journalbeat/tests/system/config/journalbeat.yml.j2 b/journalbeat/tests/system/config/journalbeat.yml.j2 deleted file mode 100644 index 858181ca4097..000000000000 --- a/journalbeat/tests/system/config/journalbeat.yml.j2 +++ /dev/null @@ -1,13 +0,0 @@ -journalbeat.inputs: -{% for input in inputs %} -- {{ input | tojson }} -{% endfor %} - -{% if registry_file is defined %} -journalbeat.registry_file: {{ registry_file }} -{% endif %} - -output: - file: - path: {{ output_file_path|default(beat.working_dir + "/output") }} - filename: {{ output_file_filename|default("journalbeat") }} diff --git a/journalbeat/tests/system/input/test.journal b/journalbeat/tests/system/input/test.journal deleted file mode 100644 index c42b825e62dcb7e934e0dc17cc218e46de463a66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8388608 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 z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfWYA;uz6HIDJbIMRh?=G5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfWW>9ly1u<10(L+ETaezAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ 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 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+0D=E+hYm;p00004{eRt#KqqLxfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r a3>YwAz<>b*1`HT5V8DO@0|pEj7!CwYf~a}` diff --git a/journalbeat/tests/system/input/test.registry b/journalbeat/tests/system/input/test.registry deleted file mode 100644 index 9b9dee108b3a..000000000000 --- a/journalbeat/tests/system/input/test.registry +++ /dev/null @@ -1,6 +0,0 @@ -update_time: 2018-09-11T10:06:50.895829905Z -journal_entries: -- path: /home/n/go/src/github.com/elastic/beats/journalbeat/tests/system/input/test.journal - cursor: s=018329e08e3a45a0ae03694421c4f553;i=2015d;b=fa3c2e3080dc4cd5be5cb5a43e140d51;m=29102136a4;t=5ab0792b1dc62;x=84a1467480b8f1af - realtime_timestamp: 1595423897803874 - monotonic_timestamp: 176364271268 diff --git a/journalbeat/tests/system/journalbeat.py b/journalbeat/tests/system/journalbeat.py deleted file mode 100644 index 2ad3bd3c37fc..000000000000 --- a/journalbeat/tests/system/journalbeat.py +++ /dev/null @@ -1,12 +0,0 @@ -import os -import sys -from beat.beat import TestCase - - -class BaseTest(TestCase): - - @classmethod - def setUpClass(self): - self.beat_name = "journalbeat" - self.beat_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) - super(BaseTest, self).setUpClass() diff --git a/journalbeat/tests/system/test_base.py b/journalbeat/tests/system/test_base.py deleted file mode 100644 index 2d7269dd5f4d..000000000000 --- a/journalbeat/tests/system/test_base.py +++ /dev/null @@ -1,210 +0,0 @@ -from journalbeat import BaseTest - -import os -import sys -import unittest -import time -import yaml -from shutil import copyfile -from beat import common_tests - - -class Test(BaseTest, common_tests.TestExportsMixin): - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_start_with_local_journal(self): - """ - Journalbeat is able to start with the local journal. - """ - - self.render_config_template( - inputs=[{ - "paths": [], - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.log_contains("journalbeat is running")) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_start_with_journal_directory(self): - """ - Journalbeat is able to open a directory of journal files and starts tailing them. - """ - - self.render_config_template( - inputs=[{ - "paths": [ - self.beat_path + "/tests/system/input/", - ], - "seek": "tail", - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.log_contains("journalbeat is running")) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - # journalbeat is tailing an inactive journal - assert self.output_is_empty() - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_start_with_selected_journal_file(self): - """ - Journalbeat is able to open a journal file and start to read it from the begining. - """ - - self.render_config_template( - inputs=[{ - "paths": [ - self.beat_path + "/tests/system/input/test.journal", - ], - "seek": "head", - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.output_has(lines=23)) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_start_with_selected_journal_file_with_cursor_fallback(self): - """ - Journalbeat is able to open a journal file and start to read it from the position configured by seek and cursor_seek_fallback. - """ - - self.render_config_template( - inputs=[{ - "paths": [ - self.beat_path + "/tests/system/input/test.journal", - ], - "seek": "cursor", - "cursor_seek_fallback": "tail", - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.log_contains("journalbeat is running")) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - # journalbeat is tailing an inactive journal with no cursor data - assert self.output_is_empty() - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_read_events_with_existing_registry(self): - """ - Journalbeat is able to follow reading a from a journal with an existing registry file. - """ - - registry_path = os.path.join(os.path.abspath(self.working_dir), "data", "registry") - os.mkdir(os.path.dirname(registry_path)) - copyfile(self.beat_path + "/tests/system/input/test.registry", - os.path.join(os.path.abspath(self.working_dir), "data/registry")) - input_path = self.beat_path + "/tests/system/input/test.journal" - self._prepare_registry_file(registry_path, input_path) - - self.render_config_template( - inputs=[{ - "paths": [input_path], - "seek": "cursor", - "cursor_seek_fallback": "tail", - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.output_has(lines=9)) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_read_events_with_include_matches(self): - """ - Journalbeat is able to pass matchers to the journal reader and read filtered messages. - """ - - self.render_config_template( - inputs=[{ - "paths": [ - self.beat_path + "/tests/system/input/test.journal", - ], - "seek": "head", - "include_matches": [ - "syslog.priority=6", - ] - }], - ) - journalbeat_proc = self.start_beat() - - self.wait_until(lambda: self.output_has(lines=6)) - - exit_code = journalbeat_proc.kill_and_wait() - assert exit_code == 0 - - @unittest.skipUnless(sys.platform.startswith("linux"), "Journald only on Linux") - def test_input_id(self): - """ - Journalbeat persists states with IDs. - """ - - self.render_config_template( - inputs=[ - { - "id": "serviceA.unit", - "paths": [ - self.beat_path + "/tests/system/input/test.journal", - ], - }, - { - "id": "serviceB unit", - "paths": [ - self.beat_path + "/tests/system/input/test.journal", - ], - } - ], - ) - - # Run the beat until it publishes events from both inputs. - journalbeat_proc = self.start_beat() - expected_msg = 'successfully published events' - self.wait_until(lambda: self.log_contains(expected_msg)) - self.wait_until(lambda: self.log_contains(expected_msg)) - journalbeat_proc.check_kill_and_wait() - - # Verify that registry paths are prefixed with an ID. - registry_data = self.read_registry() - self.assertIn("journal_entries", registry_data) - journal_entries = registry_data['journal_entries'] - self.assertGreater(len(journal_entries), 0) - for item in journal_entries: - self.assertTrue(item['path'].startswith('journald::'), "starts with journald::") - self.assertTrue(item['path'].find('::service'), "ends with ::") - - def _prepare_registry_file(self, registry_path, journal_path): - lines = [] - with open(registry_path, "r") as registry_file: - lines = registry_file.readlines() - lines[2] = "- path: " + journal_path + "\n" - - with open(registry_path, "w") as registry_file: - for line in lines: - registry_file.write(line) - - def read_registry(self): - registry_path = os.path.join(os.path.abspath(self.working_dir), "data", "registry") - - with open(registry_path, "r") as stream: - return yaml.safe_load(stream) - - -if __name__ == '__main__': - unittest.main() diff --git a/libbeat/docs/getting-started.asciidoc b/libbeat/docs/getting-started.asciidoc index 619ed2e03cb5..7bb7043ae704 100644 --- a/libbeat/docs/getting-started.asciidoc +++ b/libbeat/docs/getting-started.asciidoc @@ -13,4 +13,4 @@ Each Beat is a separately installable product. To learn how to get started, see: If you're planning to use the {metrics-app} or the {logs-app} in {kib}, see {observability-guide}/analyze-metrics.html[Analyze metrics] -and {observability-guide}/monitor-logs.html[Monitor logs]. \ No newline at end of file +and {observability-guide}/monitor-logs.html[Monitor logs]. diff --git a/libbeat/docs/overview.asciidoc b/libbeat/docs/overview.asciidoc index 6306874112fb..c76aa8558e54 100644 --- a/libbeat/docs/overview.asciidoc +++ b/libbeat/docs/overview.asciidoc @@ -8,7 +8,7 @@ for capturing: [horizontal] Audit data:: https://www.elastic.co/products/beats/auditbeat[Auditbeat] -Log files:: https://www.elastic.co/products/beats/filebeat[Filebeat] +Log files and journals:: https://www.elastic.co/products/beats/filebeat[Filebeat] Cloud data:: https://www.elastic.co/products/beats/functionbeat[Functionbeat] Availability:: https://www.elastic.co/products/beats/heartbeat[Heartbeat] Metrics:: https://www.elastic.co/products/beats/metricbeat[Metricbeat] diff --git a/libbeat/docs/shared-docker.asciidoc b/libbeat/docs/shared-docker.asciidoc index 2e7e04e6c7a9..389bedb7b54f 100644 --- a/libbeat/docs/shared-docker.asciidoc +++ b/libbeat/docs/shared-docker.asciidoc @@ -80,16 +80,6 @@ setup -E setup.kibana.host=kibana:5601 \ -------------------------------------------- endif::[] -ifeval::["{beatname_lc}"=="journalbeat"] -["source", "sh", subs="attributes"] --------------------------------------------- -docker run \ -{dockerimage} \ -setup -E setup.kibana.host=kibana:5601 \ --E output.elasticsearch.hosts=["elasticsearch:9200"] <1> <2> --------------------------------------------- -endif::[] - ifeval::["{beatname_lc}"=="packetbeat"] ["source", "sh", subs="attributes"] -------------------------------------------- @@ -161,24 +151,6 @@ docker run -d \ -------------------------------------------- endif::[] -ifeval::["{beatname_lc}"=="journalbeat"] -Make sure you include the path to the host's journal. The path might be -`/var/log/journal` or `/run/log/journal`. - -["source", "sh", subs="attributes"] --------------------------------------------- -sudo docker run -d \ - --name={beatname_lc} \ - --user=root \ - --volume="/var/log/journal:/var/log/journal" \ - --volume="/etc/machine-id:/etc/machine-id" \ - --volume="/run/systemd:/run/systemd" \ - --volume="/etc/hostname:/etc/hostname:ro" \ - {dockerimage} {beatname_lc} -e -strict.perms=false \ - -E output.elasticsearch.hosts=["elasticsearch:9200"] <1> <2> --------------------------------------------- -endif::[] - ifeval::["{beatname_lc}"=="metricbeat"] ["source", "sh", subs="attributes"] -------------------------------------------- diff --git a/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc b/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc index 53cc3787543d..117460409705 100644 --- a/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc +++ b/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc @@ -9,7 +9,7 @@ experimental[] The `decode_csv_fields` processor decodes fields containing records in comma-separated format (CSV). It will output the values as an array of strings. -This processor is available for Filebeat and Journalbeat. +This processor is available for Filebeat. [source,yaml] ----------------------------------------------------- diff --git a/libbeat/scripts/Makefile b/libbeat/scripts/Makefile index 00d3231c3717..7b16cf7cea86 100755 --- a/libbeat/scripts/Makefile +++ b/libbeat/scripts/Makefile @@ -141,11 +141,9 @@ ${BEAT_NAME}.test: $(GOFILES_ALL) .PHONY: crosscompile crosscompile: ## @build Cross-compile beat for the OS'es specified in GOX_OS variable. The binaries are placed in the build/bin directory. crosscompile: $(GOFILES) -ifneq ($(shell [[ $(BEAT_NAME) == journalbeat ]] && echo true ),true) go ${INSTALL_CMD} github.com/mitchellh/gox mkdir -p ${BUILD_DIR}/bin gox -output="${BUILD_DIR}/bin/{{.Dir}}-{{.OS}}-{{.Arch}}" -os="$(strip $(GOX_OS))" -osarch="$(strip $(GOX_OSARCH))" ${GOX_FLAGS} -endif .PHONY: check check: check-headers mage ## @build Checks project and source code if everything is according to standard diff --git a/script/renamed_fields.py b/script/renamed_fields.py index 2de05c012b48..08059698bf19 100644 --- a/script/renamed_fields.py +++ b/script/renamed_fields.py @@ -3,7 +3,7 @@ def migration(): - beats = ["Auditbeat", "Filebeat", "Heartbeat", "Journalbeat", "Metricbeat", "Packetbeat", "Winlogbeat"] + beats = ["Auditbeat", "Filebeat", "Heartbeat", "Metricbeat", "Packetbeat", "Winlogbeat"] for beat in beats: print(".{} renamed fields in 7.0".format(beat)) diff --git a/x-pack/elastic-agent/pkg/agent/program/program_test.go b/x-pack/elastic-agent/pkg/agent/program/program_test.go index 04c3519af65d..b75ac9dceaa6 100644 --- a/x-pack/elastic-agent/pkg/agent/program/program_test.go +++ b/x-pack/elastic-agent/pkg/agent/program/program_test.go @@ -400,10 +400,6 @@ func TestConfiguration(t *testing.T) { // programs: []string{"auditbeat"}, // expected: 1, // }, - // "journal_config": { - // programs: []string{"journalbeat"}, - // expected: 1, - // }, "fleet_server": { programs: []string{"fleet-server"}, expected: 1, diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/journal_config-journalbeat.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/journal_config-journalbeat.yml deleted file mode 100644 index 60e6261fc0eb..000000000000 --- a/x-pack/elastic-agent/pkg/agent/program/testdata/journal_config-journalbeat.yml +++ /dev/null @@ -1,15 +0,0 @@ -journalbeat: - inputs: - - type: log/journal - paths: [] - backoff: 1s - max_backoff: 20s - seek: cursor - cursor_seek_fallback: head - include_matches: [] - save_remote_hostname: false -output: - elasticsearch: - hosts: [127.0.0.1:9200, 127.0.0.1:9300] - username: elastic - password: changeme diff --git a/x-pack/elastic-agent/spec/journalbeat.yml.disabled b/x-pack/elastic-agent/spec/journalbeat.yml.disabled deleted file mode 100644 index ce35cc75aaf8..000000000000 --- a/x-pack/elastic-agent/spec/journalbeat.yml.disabled +++ /dev/null @@ -1,22 +0,0 @@ -name: Journalbeat -cmd: journalbeat -args: ["-E", "setup.ilm.enabled=false", "-E", "setup.template.enabled=false"] -rules: -- filter_values: - selector: streams - key: type - values: - - log/journal -- copy: - from: streams - to: journalbeat -- rename: - from: journalbeat.streams - to: inputs -- filter: - selectors: - - journalbeat - - output - - keystore -when: HasItems(%{[journalbeat.inputs]}) && HasNamespace('output', 'elasticsearch', - 'redis', 'kafka', 'logstash') diff --git a/x-pack/journalbeat/cmd/root.go b/x-pack/journalbeat/cmd/root.go deleted file mode 100644 index d549011f73a3..000000000000 --- a/x-pack/journalbeat/cmd/root.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 cmd - -import ( - journalbeatCmd "github.com/elastic/beats/v7/journalbeat/cmd" - "github.com/elastic/beats/v7/libbeat/cmd" - - _ "github.com/elastic/beats/v7/x-pack/libbeat/include" -) - -// RootCmd to handle beats cli -var RootCmd *cmd.BeatsRootCmd - -func init() { - settings := journalbeatCmd.JournalbeatSettings() - settings.ElasticLicensed = true - RootCmd = journalbeatCmd.Initialize(settings) -} diff --git a/x-pack/journalbeat/main.go b/x-pack/journalbeat/main.go deleted file mode 100644 index 232a3e6fc498..000000000000 --- a/x-pack/journalbeat/main.go +++ /dev/null @@ -1,19 +0,0 @@ -// 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 main - -import ( - "os" - - "github.com/elastic/beats/v7/x-pack/journalbeat/cmd" - - _ "github.com/elastic/beats/v7/journalbeat/include" -) - -func main() { - if err := cmd.RootCmd.Execute(); err != nil { - os.Exit(1) - } -} diff --git a/x-pack/journalbeat/main_test.go b/x-pack/journalbeat/main_test.go deleted file mode 100644 index fcac188a31cb..000000000000 --- a/x-pack/journalbeat/main_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// 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 main - -// This file is mandatory as otherwise the journalbeat.test binary is not generated correctly. -import ( - "flag" - "testing" - - "github.com/elastic/beats/v7/journalbeat/cmd" - "github.com/elastic/beats/v7/libbeat/tests/system/template" -) - -var systemTest *bool - -func init() { - testing.Init() - systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") - cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) - cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) -} - -// Test started when the test binary is started. Only calls main. -func TestSystem(t *testing.T) { - if *systemTest { - main() - } -} - -func TestTemplate(t *testing.T) { - template.TestTemplate(t, cmd.Name, true) -} From 180e7f3e6d285f715880b87a4062981712cc1799 Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Tue, 30 Nov 2021 21:34:22 +1030 Subject: [PATCH 037/172] winlogbeat/sys/winevent: use reflect IsZero method (#29190) --- winlogbeat/sys/winevent/event_test.go | 22 ++++++++++++++++++---- winlogbeat/sys/winevent/maputil.go | 26 +++++++------------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/winlogbeat/sys/winevent/event_test.go b/winlogbeat/sys/winevent/event_test.go index 4ed391b91bec..b6d893957ed1 100644 --- a/winlogbeat/sys/winevent/event_test.go +++ b/winlogbeat/sys/winevent/event_test.go @@ -26,6 +26,8 @@ import ( "time" "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/libbeat/common" ) const allXML = ` @@ -79,9 +81,10 @@ const allXML = ` func TestXML(t *testing.T) { allXMLTimeCreated, _ := time.Parse(time.RFC3339Nano, "2016-01-28T20:33:27.990735300Z") - var tests = []struct { - xml string - event Event + tests := []struct { + xml string + event Event + mapstr common.MapStr }{ { xml: allXML, @@ -150,6 +153,14 @@ func TestXML(t *testing.T) { }, }, }, + mapstr: common.MapStr{ + "event_id": "0", + "time_created": time.Time{}, + "user_data": common.MapStr{ + "Id": "{00000000-0000-0000-0000-000000000000}", + "xml_name": "Operation_ClientFailure", + }, + }, }, } @@ -160,6 +171,9 @@ func TestXML(t *testing.T) { continue } assert.Equal(t, test.event, event) + if test.mapstr != nil { + assert.Equal(t, test.mapstr, event.Fields()) + } if testing.Verbose() { json, err := json.MarshalIndent(event, "", " ") @@ -174,7 +188,7 @@ func TestXML(t *testing.T) { // Tests that control characters other than CR and LF are escaped // when the event is decoded. func TestInvalidXML(t *testing.T) { - evXML := strings.Replace(allXML, "%1", "\t \n\x1b", -1) + evXML := strings.ReplaceAll(allXML, "%1", "\t \n\x1b") ev, err := UnmarshalXML([]byte(evXML)) assert.Equal(t, nil, err) assert.Equal(t, "Creating WSMan shell on server with ResourceUri: \t\r\n\\u001b", ev.Message) diff --git a/winlogbeat/sys/winevent/maputil.go b/winlogbeat/sys/winevent/maputil.go index 45a265ae8c6b..82ae2ad2a3c1 100644 --- a/winlogbeat/sys/winevent/maputil.go +++ b/winlogbeat/sys/winevent/maputil.go @@ -20,6 +20,7 @@ package winevent import ( "fmt" "reflect" + "time" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/winlogbeat/sys" @@ -80,25 +81,12 @@ func AddPairs(m common.MapStr, key string, pairs []KeyValue) common.MapStr { // isZero return true if the given value is the zero value for its type. func isZero(i interface{}) bool { - if i == nil { + switch i := i.(type) { + case nil: return true + case time.Time: + return false + default: + return reflect.ValueOf(i).IsZero() } - - v := reflect.ValueOf(i) - switch v.Kind() { - case reflect.Array, reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - - return false } From 51463bf4ebcd4b425f8e751fa10edc651f0c2001 Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Tue, 30 Nov 2021 14:50:15 +0100 Subject: [PATCH 038/172] [Elastic Agent] Add process error handling guidelines (#29152) We don't have a good place yet to document expectations around services run by Elastic Agent. I'm starting this document to have a place to add more content to it but I expect long term we need to figure out a better place. This guideline comes out of recent issues we had in Cloud and local setups of fleet-server (https://github.com/elastic/fleet-server/pull/883). We never set clear guidlines on what the expectation is of a service run by Elastic Agent and Elastic Agent itself. This PR is kick off the discussion. Co-authored-by: Gil Raphaelli --- x-pack/elastic-agent/GUIDELINES.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 x-pack/elastic-agent/GUIDELINES.md diff --git a/x-pack/elastic-agent/GUIDELINES.md b/x-pack/elastic-agent/GUIDELINES.md new file mode 100644 index 000000000000..3fa741fc9917 --- /dev/null +++ b/x-pack/elastic-agent/GUIDELINES.md @@ -0,0 +1,9 @@ +# Guidelines + +This document contains architecture details around Elastic Agent and guidelines on how new inputs and processes should be built. + +## Processes running as service and error handling + +All the processes started by Elastic Agent are running as service. Each service is expected to handle local errors on its own and continue working. A process should only fail on startup if an invalid configuration is passed in. As soon as a process is running and partial updates to the config are made without restart, the service is expected to keep running but report the errors. + +A service that needs to do setup tasks on startup is expected to retry until it succeeds and not error out after a certain timeout. From 8fcad13cb02b26e881303ee3e6cb70d0c6be9b85 Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Tue, 30 Nov 2021 16:54:27 +0000 Subject: [PATCH 039/172] Adopt `parsers` in Filebeat's journald input (#29070) One test is added that runs Filebeat reading from a journald file, it only tests one parser, however that should be enough to ensure parsers are supported on journald input. Splits from #26130 --- CHANGELOG.next.asciidoc | 1 + .../config/filebeat.inputs.reference.yml.tmpl | 19 ++ filebeat/filebeat.reference.yml | 19 ++ filebeat/input/journald/config.go | 4 + filebeat/input/journald/environment_test.go | 286 ++++++++++++++++++ filebeat/input/journald/input.go | 62 +++- filebeat/input/journald/input_parsers_test.go | 62 ++++ .../testdata/input-multiline-parser.journal | Bin 0 -> 8388608 bytes libbeat/reader/message.go | 3 +- x-pack/filebeat/filebeat.reference.yml | 19 ++ 10 files changed, 464 insertions(+), 11 deletions(-) create mode 100644 filebeat/input/journald/environment_test.go create mode 100644 filebeat/input/journald/input_parsers_test.go create mode 100644 filebeat/input/journald/testdata/input-multiline-parser.journal diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b8bb5c5d5421..99e82e6dc321 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -345,6 +345,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support in aws-s3 input for s3 notification from SNS to SQS. {pull}28800[28800] - Add support in aws-s3 input for custom script parsing of s3 notifications. {pull}28946[28946] - Improve error handling in aws-s3 input for malformed s3 notifications. {issue}28828[28828] {pull}28946[28946] +- Add support for parsers on journald input {pull}29070[29070] *Heartbeat* diff --git a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl index 8da4a2e75fd1..a1c7166cac06 100644 --- a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl +++ b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl @@ -559,3 +559,22 @@ filebeat.inputs: # Configure stream to filter to a specific stream: stdout, stderr or all (default) #stream: all +#------------------------------ Journald input -------------------------------- +# Journald input is experimental. +#- type: journald + #enabled: true + #id: service-foo + + # You may wish to have separate inputs for each service. You can use + # include_matches to specify a list of filter expressions that are + # applied as a logical OR. You may specify filter + #include_matches: + #- _SYSTEMD_UNIT=foo.service + + # Parsers are also supported, here is an example of the multiline + # parser. + #parsers: + #- multiline: + #type: count + #count_lines: 3 + diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 6f85f929d280..9b6a421d6c43 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -966,6 +966,25 @@ filebeat.inputs: # Configure stream to filter to a specific stream: stdout, stderr or all (default) #stream: all +#------------------------------ Journald input -------------------------------- +# Journald input is experimental. +#- type: journald + #enabled: true + #id: service-foo + + # You may wish to have separate inputs for each service. You can use + # include_matches to specify a list of filter expressions that are + # applied as a logical OR. You may specify filter + #include_matches: + #- _SYSTEMD_UNIT=foo.service + + # Parsers are also supported, here is an example of the multiline + # parser. + #parsers: + #- multiline: + #type: count + #count_lines: 3 + # =========================== Filebeat autodiscover ============================ diff --git a/filebeat/input/journald/config.go b/filebeat/input/journald/config.go index e3bf6bdd5090..cb3b32e14c97 100644 --- a/filebeat/input/journald/config.go +++ b/filebeat/input/journald/config.go @@ -26,6 +26,7 @@ import ( "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalfield" "github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalread" + "github.com/elastic/beats/v7/libbeat/reader/parser" ) // Config stores the options of a journald input. @@ -51,6 +52,9 @@ type config struct { // SaveRemoteHostname defines if the original source of the entry needs to be saved. SaveRemoteHostname bool `config:"save_remote_hostname"` + + // Parsers configuration + Parsers parser.Config `config:",inline"` } var errInvalidSeekFallback = errors.New("invalid setting for cursor_seek_fallback") diff --git a/filebeat/input/journald/environment_test.go b/filebeat/input/journald/environment_test.go new file mode 100644 index 000000000000..5c05759b2c2f --- /dev/null +++ b/filebeat/input/journald/environment_test.go @@ -0,0 +1,286 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build linux && cgo && withjournald +// +build linux,cgo,withjournald + +package journald + +import ( + "context" + "fmt" + "os" + "path/filepath" + "sync" + "testing" + "time" + + input "github.com/elastic/beats/v7/filebeat/input/v2" + v2 "github.com/elastic/beats/v7/filebeat/input/v2" + "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/acker" + "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/statestore" + "github.com/elastic/beats/v7/libbeat/statestore/storetest" + "github.com/elastic/go-concert/unison" +) + +type inputTestingEnvironment struct { + t *testing.T + workingDir string + stateStore *testInputStore + pipeline *mockPipelineConnector + + pluginInitOnce sync.Once + plugin v2.Plugin + + wg sync.WaitGroup + grp unison.TaskGroup +} + +func newInputTestingEnvironment(t *testing.T) *inputTestingEnvironment { + return &inputTestingEnvironment{ + t: t, + workingDir: t.TempDir(), + stateStore: openTestStatestore(), + pipeline: &mockPipelineConnector{}, + } +} + +func (e *inputTestingEnvironment) getManager() v2.InputManager { + e.pluginInitOnce.Do(func() { + e.plugin = Plugin(logp.L(), e.stateStore) + }) + return e.plugin.Manager +} + +func (e *inputTestingEnvironment) mustCreateInput(config map[string]interface{}) v2.Input { + e.t.Helper() + e.grp = unison.TaskGroup{} + manager := e.getManager() + if err := manager.Init(&e.grp, v2.ModeRun); err != nil { + e.t.Fatalf("failed to initialise manager: %+v", err) + } + + c := common.MustNewConfigFrom(config) + inp, err := manager.Create(c) + if err != nil { + e.t.Fatalf("failed to create input using manager: %+v", err) + } + + return inp +} + +func (e *inputTestingEnvironment) startInput(ctx context.Context, inp v2.Input) { + e.wg.Add(1) + go func(wg *sync.WaitGroup, grp *unison.TaskGroup) { + defer wg.Done() + defer grp.Stop() + + inputCtx := input.Context{Logger: logp.L(), Cancelation: ctx} + inp.Run(inputCtx, e.pipeline) + }(&e.wg, &e.grp) +} + +// waitUntilEventCount waits until total count events arrive to the client. +func (e *inputTestingEnvironment) waitUntilEventCount(count int) { + e.t.Helper() + for { + sum := len(e.pipeline.GetAllEvents()) + if sum == count { + return + } + if count < sum { + e.t.Fatalf("too many events; expected: %d, actual: %d", count, sum) + } + time.Sleep(10 * time.Millisecond) + } +} + +func (e *inputTestingEnvironment) waitUntilInputStops() { + e.wg.Wait() +} + +func (e *inputTestingEnvironment) abspath(filename string) string { + return filepath.Join(e.workingDir, filename) +} + +func (e *inputTestingEnvironment) mustWriteFile(filename string, lines []byte) { + e.t.Helper() + path := e.abspath(filename) + if err := os.WriteFile(path, lines, 0644); err != nil { + e.t.Fatalf("failed to write file '%s': %+v", path, err) + } +} + +type testInputStore struct { + registry *statestore.Registry +} + +func openTestStatestore() *testInputStore { + return &testInputStore{ + registry: statestore.NewRegistry(storetest.NewMemoryStoreBackend()), + } +} + +func (s *testInputStore) Close() { + s.registry.Close() +} + +func (s *testInputStore) Access() (*statestore.Store, error) { + return s.registry.Get("filebeat") +} + +func (s *testInputStore) CleanupInterval() time.Duration { + return 24 * time.Hour +} + +type mockClient struct { + publishing []beat.Event + published []beat.Event + ackHandler beat.ACKer + closed bool + mtx sync.Mutex + canceler context.CancelFunc +} + +// GetEvents returns the published events +func (c *mockClient) GetEvents() []beat.Event { + c.mtx.Lock() + defer c.mtx.Unlock() + + return c.published +} + +// Publish mocks the Client Publish method +func (c *mockClient) Publish(e beat.Event) { + c.PublishAll([]beat.Event{e}) +} + +// PublishAll mocks the Client PublishAll method +func (c *mockClient) PublishAll(events []beat.Event) { + c.mtx.Lock() + defer c.mtx.Unlock() + + c.publishing = append(c.publishing, events...) + for _, event := range events { + c.ackHandler.AddEvent(event, true) + } + c.ackHandler.ACKEvents(len(events)) + + for _, event := range events { + c.published = append(c.published, event) + } +} + +func (c *mockClient) waitUntilPublishingHasStarted() { + for len(c.publishing) == 0 { + time.Sleep(10 * time.Millisecond) + } +} + +// Close mocks the Client Close method +func (c *mockClient) Close() error { + c.mtx.Lock() + defer c.mtx.Unlock() + + if c.closed { + return fmt.Errorf("mock client already closed") + } + + c.closed = true + return nil +} + +// mockPipelineConnector mocks the PipelineConnector interface +type mockPipelineConnector struct { + blocking bool + clients []*mockClient + mtx sync.Mutex +} + +// GetAllEvents returns all events associated with a pipeline +func (pc *mockPipelineConnector) GetAllEvents() []beat.Event { + pc.mtx.Lock() + defer pc.mtx.Unlock() + + var evList []beat.Event + for _, clientEvents := range pc.clients { + evList = append(evList, clientEvents.GetEvents()...) + } + + return evList +} + +// Connect mocks the PipelineConnector Connect method +func (pc *mockPipelineConnector) Connect() (beat.Client, error) { + return pc.ConnectWith(beat.ClientConfig{}) +} + +// ConnectWith mocks the PipelineConnector ConnectWith method +func (pc *mockPipelineConnector) ConnectWith(config beat.ClientConfig) (beat.Client, error) { + pc.mtx.Lock() + defer pc.mtx.Unlock() + + ctx, cancel := context.WithCancel(context.Background()) + c := &mockClient{ + canceler: cancel, + ackHandler: newMockACKHandler(ctx, pc.blocking, config), + } + + pc.clients = append(pc.clients, c) + + return c, nil + +} + +func (pc *mockPipelineConnector) cancelAllClients() { + pc.mtx.Lock() + defer pc.mtx.Unlock() + + for _, client := range pc.clients { + client.canceler() + } +} + +func (pc *mockPipelineConnector) cancelClient(i int) { + pc.mtx.Lock() + defer pc.mtx.Unlock() + + if len(pc.clients) < i+1 { + return + } + + pc.clients[i].canceler() +} + +func newMockACKHandler(starter context.Context, blocking bool, config beat.ClientConfig) beat.ACKer { + if !blocking { + return config.ACKHandler + } + + return acker.Combine(blockingACKer(starter), config.ACKHandler) + +} + +func blockingACKer(starter context.Context) beat.ACKer { + return acker.EventPrivateReporter(func(acked int, private []interface{}) { + for starter.Err() == nil { + } + }) +} diff --git a/filebeat/input/journald/input.go b/filebeat/input/journald/input.go index 7c8f5085dead..e9e2f0b40c48 100644 --- a/filebeat/input/journald/input.go +++ b/filebeat/input/journald/input.go @@ -34,6 +34,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common/backoff" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/reader" + "github.com/elastic/beats/v7/libbeat/reader/parser" ) type journald struct { @@ -43,6 +45,7 @@ type journald struct { CursorSeekFallback journalread.SeekMode Matches []journalfield.Matcher SaveRemoteHostname bool + Parsers parser.Config } type checkpoint struct { @@ -103,6 +106,7 @@ func configure(cfg *common.Config) ([]cursor.Source, cursor.Input, error) { CursorSeekFallback: config.CursorSeekFallback, Matches: config.Matches, SaveRemoteHostname: config.SaveRemoteHostname, + Parsers: config.Parsers, }, nil } @@ -123,7 +127,7 @@ func (inp *journald) Run( publisher cursor.Publisher, ) error { log := ctx.Logger.With("path", src.Name()) - checkpoint := initCheckpoint(log, cursor) + currentCheckpoint := initCheckpoint(log, cursor) reader, err := inp.open(ctx.Logger, ctx.Cancelation, src) if err != nil { @@ -131,23 +135,20 @@ func (inp *journald) Run( } defer reader.Close() - if err := reader.Seek(seekBy(ctx.Logger, checkpoint, inp.Seek, inp.CursorSeekFallback)); err != nil { + if err := reader.Seek(seekBy(ctx.Logger, currentCheckpoint, inp.Seek, inp.CursorSeekFallback)); err != nil { log.Error("Continue from current position. Seek failed with: %v", err) } + parser := inp.Parsers.Create(&readerAdapter{r: reader, canceler: ctx.Cancelation}) + for { - entry, err := reader.Next(ctx.Cancelation) + entry, err := parser.Next() if err != nil { return err } - event := eventFromFields(ctx.Logger, entry.RealtimeTimestamp, entry.Fields, inp.SaveRemoteHostname) - - checkpoint.Position = entry.Cursor - checkpoint.RealtimeTimestamp = entry.RealtimeTimestamp - checkpoint.MonotonicTimestamp = entry.MonotonicTimestamp - - if err := publisher.Publish(event, checkpoint); err != nil { + event := entry.ToEvent() + if err := publisher.Publish(event, event.Private); err != nil { return err } } @@ -204,3 +205,44 @@ func seekBy(log *logp.Logger, cp checkpoint, seek, defaultSeek journalread.SeekM } return mode, cp.Position } + +// readerAdapter is an adapter so journalread.Reader can +// behave like reader.Reader +type readerAdapter struct { + r *journalread.Reader + canceler input.Canceler +} + +func (r *readerAdapter) Close() error { + return r.r.Close() +} + +func (r *readerAdapter) Next() (reader.Message, error) { + data, err := r.r.Next(r.canceler) + if err != nil { + return reader.Message{}, err + } + + content := []byte(data.Fields["MESSAGE"]) + delete(data.Fields, "MESSAGE") + + fields := make(map[string]interface{}, len(data.Fields)) + for k, v := range data.Fields { + fields[k] = v + } + + m := reader.Message{ + Ts: time.UnixMicro(int64(data.RealtimeTimestamp)), + Content: content, + Bytes: len(content), + Fields: fields, + Private: checkpoint{ + Version: cursorVersion, + RealtimeTimestamp: data.RealtimeTimestamp, + MonotonicTimestamp: data.MonotonicTimestamp, + Position: data.Cursor, + }, + } + + return m, nil +} diff --git a/filebeat/input/journald/input_parsers_test.go b/filebeat/input/journald/input_parsers_test.go new file mode 100644 index 000000000000..6aadb031cd2c --- /dev/null +++ b/filebeat/input/journald/input_parsers_test.go @@ -0,0 +1,62 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build linux && cgo && withjournald +// +build linux,cgo,withjournald + +package journald + +import ( + "context" + "path" + "testing" + + "github.com/elastic/beats/v7/libbeat/common" +) + +// TestInputParsers ensures journald input support parsers, +// it only tests a single parser, but that is enough to ensure +// we're correctly using the parsers +func TestInputParsers(t *testing.T) { + inputParsersExpected := []string{"1st line\n2nd line\n3rd line", "4th line\n5th line\n6th line"} + env := newInputTestingEnvironment(t) + + inp := env.mustCreateInput(common.MapStr{ + "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, + "include_matches": []string{"_SYSTEMD_USER_UNIT=log-service.service"}, + "parsers": []common.MapStr{ + { + "multiline": common.MapStr{ + "type": "count", + "count_lines": 3, + }, + }, + }, + }) + + ctx, cancelInput := context.WithCancel(context.Background()) + env.startInput(ctx, inp) + env.waitUntilEventCount(len(inputParsersExpected)) + + for idx, event := range env.pipeline.clients[0].GetEvents() { + if got, expected := event.Fields["message"], inputParsersExpected[idx]; got != expected { + t.Errorf("expecting event message %q, got %q", expected, got) + } + } + + cancelInput() +} diff --git a/filebeat/input/journald/testdata/input-multiline-parser.journal b/filebeat/input/journald/testdata/input-multiline-parser.journal new file mode 100644 index 0000000000000000000000000000000000000000..9aecfd442f0c394344f7edc70ed4897419dc3800 GIT binary patch literal 8388608 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 zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNApP6C@>&n0oAmQ!|F2@oJafB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkKc=m_kclutGrb?EHeP6-eoK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72n>FK?z8jBCZi7i z9or!R0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z28O`cG5I7&)Pa#o3IYTO5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNC9H-W~n>A%kxwQt=<6Cgl<009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs zfmC46hh+(1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK%o2tx-U72NzAC_kXc3o1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF9FM?(bJM>+74>*}j3GdP009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjU};Lg+YNu;O)EuTCD2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV6R+2<*EspKK%QVAzvA5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U 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 z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB=F2X@?F3000001o>MJav@~EfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r T3>YwAz<>b*1`HT5VBkFvBU;nY literal 0 HcmV?d00001 diff --git a/libbeat/reader/message.go b/libbeat/reader/message.go index 79116bfcfad3..0eae606f80bf 100644 --- a/libbeat/reader/message.go +++ b/libbeat/reader/message.go @@ -31,7 +31,8 @@ type Message struct { Content []byte // actual content read Bytes int // total number of bytes read to generate the message Fields common.MapStr // optional fields that can be added by reader - Meta common.MapStr + Meta common.MapStr // deprecated + Private interface{} } // IsEmpty returns true in case the message is empty diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 50cb79578be8..fae9d78fb5da 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -2954,6 +2954,25 @@ filebeat.inputs: # Configure stream to filter to a specific stream: stdout, stderr or all (default) #stream: all +#------------------------------ Journald input -------------------------------- +# Journald input is experimental. +#- type: journald + #enabled: true + #id: service-foo + + # You may wish to have separate inputs for each service. You can use + # include_matches to specify a list of filter expressions that are + # applied as a logical OR. You may specify filter + #include_matches: + #- _SYSTEMD_UNIT=foo.service + + # Parsers are also supported, here is an example of the multiline + # parser. + #parsers: + #- multiline: + #type: count + #count_lines: 3 + #------------------------------ NetFlow input -------------------------------- # Experimental: Config options for the Netflow/IPFIX collector over UDP input From db2903b1d35cce2d5f53f0aba80354b5ed4f6150 Mon Sep 17 00:00:00 2001 From: Alan Hinchliff Date: Tue, 30 Nov 2021 12:24:38 -0500 Subject: [PATCH 040/172] #28472 fix flaky tests in libbeat fmtstr to use time.UTC instead of time.Local (#28473) From 37b240a73bb3d8acd079fbcae388d0aff931e39c Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Tue, 30 Nov 2021 12:00:18 -0800 Subject: [PATCH 041/172] Change elastic-agent pprof default to false (#29155) Change agent.monitoring.pprof to false, allow it to toggle beat behaviour as well as the agent's. --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 2 +- x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl | 2 +- .../elastic-agent/_meta/config/common.reference.p2.yml.tmpl | 2 +- .../_meta/config/elastic-agent.docker.yml.tmpl | 2 +- x-pack/elastic-agent/elastic-agent.docker.yml | 2 +- x-pack/elastic-agent/elastic-agent.reference.yml | 2 +- x-pack/elastic-agent/elastic-agent.yml | 2 +- .../pkg/core/monitoring/beats/beats_monitor.go | 6 +++++- x-pack/elastic-agent/pkg/core/monitoring/config/config.go | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index d0de29fdea8e..759fe4078537 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -149,4 +149,4 @@ - Add diagnostics command to gather beat metadata. {pull}28265[28265] - Add diagnostics collect command to gather beat metadata, config, policy, and logs and bundle it into an archive. {pull}28461[28461] - Add `KIBANA_FLEET_SERVICE_TOKEN` to Elastic Agent container. {pull}28096[28096] -- Enable pprof endpoints for beats processes. Allow pprof endpoints for elastic-agent if enabled. {pull}28983[28983] +- Allow pprof endpoints for elastic-agent or beats if enabled. {pull}28983[28983] {pull}29155[29155] diff --git a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl index a451165969f5..de16df8ea7f7 100644 --- a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl @@ -35,7 +35,7 @@ inputs: # metrics: true # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl index 922e6a4dd6a8..43e484646306 100644 --- a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl index a82360333039..69a80678db87 100644 --- a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.docker.yml b/x-pack/elastic-agent/elastic-agent.docker.yml index a1ef12ae4059..9bf7307aacfd 100644 --- a/x-pack/elastic-agent/elastic-agent.docker.yml +++ b/x-pack/elastic-agent/elastic-agent.docker.yml @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.reference.yml b/x-pack/elastic-agent/elastic-agent.reference.yml index d41b7c54ed8b..67922a1d89cc 100644 --- a/x-pack/elastic-agent/elastic-agent.reference.yml +++ b/x-pack/elastic-agent/elastic-agent.reference.yml @@ -115,7 +115,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.yml b/x-pack/elastic-agent/elastic-agent.yml index 2ea81fda476d..d40b6518e8d5 100644 --- a/x-pack/elastic-agent/elastic-agent.yml +++ b/x-pack/elastic-agent/elastic-agent.yml @@ -41,7 +41,7 @@ inputs: # metrics: true # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: true +# pprof: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go index d506c22a6cba..cb0519f98063 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go @@ -122,8 +122,12 @@ func (b *Monitor) EnrichArgs(spec program.Spec, pipelineID string, args []string appendix = append(appendix, "-E", "http.enabled=true", "-E", "http.host="+endpoint, - "-E", "http.pprof.enabled=true", ) + if b.config.Pprof { + appendix = append(appendix, + "-E", "http.pprof.enabled=true", + ) + } } loggingPath := b.generateLoggingPath(spec, pipelineID) diff --git a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go index 10a3a6bd4a91..10f220fcc5af 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go @@ -39,6 +39,6 @@ func DefaultConfig() *MonitoringConfig { Port: defaultPort, }, Namespace: defaultNamespace, - Pprof: true, + Pprof: false, } } From 1dd971490b684aa3d2e37bbe70526343ceece087 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 30 Nov 2021 21:47:25 -0500 Subject: [PATCH 042/172] [libbeat] Fix add_labels flattening of arrays values (#29211) * Fix add_labels flattening of arrays values The processor was not working as described in the docs. For example: ```yaml processors: - add_labels: labels: number: 1 with.dots: test nested: with.dots: nested array: - do - re - with.field: mi ``` ```json { "labels": { "array": [ "do", "re", { "with": { "field": "mi" } } ], "nested.with.dots": "nested", "number": 1, "with.dots": "test" } ``` ```json { "labels": { "number": 1, "with.dots": "test", "nested.with.dots": "nested", "array.0": "do", "array.1": "re", "array.2.with.field": "mi" } } ``` * Expose ucfg FlattenedKeys() in common.Config --- CHANGELOG.next.asciidoc | 3 +- libbeat/common/config.go | 5 +++ libbeat/processors/actions/add_labels.go | 39 ++++++++++++++++--- libbeat/processors/actions/add_labels_test.go | 11 ++++++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 99e82e6dc321..fbef98864e66 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -142,6 +142,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] - Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] - Fix `decode_json_processor` to always respect `add_error_key` {pull}29107[29107] +- Fix `add_labels` flattening of array values. {pull}29211[29211] *Auditbeat* @@ -188,7 +189,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Revert usageDetails api version to 2019-01-01. {pull}28995[28995] - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] - Fix `threatintel.misp` filters configuration. {issue}27970[27970] -- Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] +- Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] *Heartbeat* diff --git a/libbeat/common/config.go b/libbeat/common/config.go index e4155c4f3afb..3efff0b702c1 100644 --- a/libbeat/common/config.go +++ b/libbeat/common/config.go @@ -259,6 +259,11 @@ func (c *Config) IsArray() bool { return c.access().IsArray() } +// FlattenedKeys return a sorted flattened views of the set keys in the configuration. +func (c *Config) FlattenedKeys() []string { + return c.access().FlattenedKeys(configOpts...) +} + func (c *Config) PrintDebugf(msg string, params ...interface{}) { selector := selectorConfigWithPassword filtered := false diff --git a/libbeat/processors/actions/add_labels.go b/libbeat/processors/actions/add_labels.go index 766966592652..93096898960f 100644 --- a/libbeat/processors/actions/add_labels.go +++ b/libbeat/processors/actions/add_labels.go @@ -41,10 +41,15 @@ func createAddLabels(c *common.Config) (processors.Processor, error) { }{} err := c.Unpack(&config) if err != nil { - return nil, fmt.Errorf("fail to unpack the add_fields configuration: %s", err) + return nil, fmt.Errorf("fail to unpack the add_fields configuration: %w", err) } - return makeFieldsProcessor(LabelsKey, config.Labels.Flatten(), true), nil + flatLabels, err := flattenLabels(config.Labels) + if err != nil { + return nil, fmt.Errorf("failed to flatten labels: %w", err) + } + + return makeFieldsProcessor(LabelsKey, flatLabels, true), nil } // NewAddLabels creates a new processor adding the given object to events. Set @@ -53,8 +58,32 @@ func createAddLabels(c *common.Config) (processors.Processor, error) { // If labels contains nested objects, NewAddLabels will flatten keys into labels by // by joining names with a dot ('.') . // The labels will be inserted into the 'labels' field. -func NewAddLabels(labels common.MapStr, shared bool) processors.Processor { +func NewAddLabels(labels common.MapStr, shared bool) (processors.Processor, error) { + flatLabels, err := flattenLabels(labels) + if err != nil { + return nil, fmt.Errorf("failed to flatten labels: %w", err) + } + return NewAddFields(common.MapStr{ - LabelsKey: labels.Flatten(), - }, shared, true) + LabelsKey: flatLabels, + }, shared, true), nil +} + +func flattenLabels(labels common.MapStr) (common.MapStr, error) { + labelConfig, err := common.NewConfigFrom(labels) + if err != nil { + return nil, err + } + + flatKeys := labelConfig.FlattenedKeys() + flatMap := make(common.MapStr, len(flatKeys)) + for _, k := range flatKeys { + v, err := labelConfig.String(k, -1) + if err != nil { + return nil, err + } + flatMap[k] = v + } + + return flatMap, nil } diff --git a/libbeat/processors/actions/add_labels_test.go b/libbeat/processors/actions/add_labels_test.go index 24ddcbab58f2..ca9dd22a5280 100644 --- a/libbeat/processors/actions/add_labels_test.go +++ b/libbeat/processors/actions/add_labels_test.go @@ -59,5 +59,16 @@ func TestAddLabels(t *testing.T) { `{add_labels.labels: {l2: b, lc: b}}`, ), }, + "add array": { + event: common.MapStr{}, + want: common.MapStr{ + "labels": common.MapStr{ + "array.0": "foo", + "array.1": "bar", + "array.2.hello": "world", + }, + }, + cfg: single(`{add_labels: {labels: {array: ["foo", "bar", {"hello": "world"}]}}}`), + }, }) } From e0bb4b8dc0608648912bf21d262f2c0c3864b64b Mon Sep 17 00:00:00 2001 From: Tetiana Kravchenko Date: Wed, 1 Dec 2021 10:45:43 +0100 Subject: [PATCH 043/172] Add how-to for testing elastic-agent on k8s (#28697) * add how-to testing es-agent on k8s Signed-off-by: Tetiana Kravchenko * rename 'Testing on Kubernetes' -> 'Testing Elastic Agent in standalone mode on Kubernetes' Signed-off-by: Tetiana Kravchenko * generalize Testing Elastic Agent on Kubernetes how to Signed-off-by: Tetiana Kravchenko --- x-pack/elastic-agent/README.md | 66 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/x-pack/elastic-agent/README.md b/x-pack/elastic-agent/README.md index 8d70b9b84202..de45ded8e461 100644 --- a/x-pack/elastic-agent/README.md +++ b/x-pack/elastic-agent/README.md @@ -3,7 +3,12 @@ The source files for the general Elastic Agent documentation are currently stored in the [observability-docs](https://github.com/elastic/observability-docs) repo. The following docs are only focused on getting developers started building code for Elastic Agent. -## Testing docker container +## Testing + +Prerequisites: +- installed [mage](https://github.com/magefile/mage) + +### Testing docker container Running Elastic Agent in a docker container is a common use case. To build the Elastic Agent and create a docker image run the following command: @@ -19,4 +24,61 @@ elastic-package stack up --version=7.13.0-SNAPSHOT -v Please note that the docker container is built in both standard and 'complete' variants. The 'complete' variant contains extra files, like the chromium browser, that are too large -for the standard variant. \ No newline at end of file +for the standard variant. + +### Testing Elastic Agent on Kubernetes + +#### Prerequisites +- create kubernetes cluster using kind, check [here](https://github.com/elastic/beats/blob/master/metricbeat/module/kubernetes/_meta/test/docs/README.md) for details +- deploy kube-state-metrics, check [here](https://github.com/elastic/beats/blob/master/metricbeat/module/kubernetes/_meta/test/docs/README.md) for details +- deploy required infrastructure: + - for elastic agent in standalone mode: EK stack or use [elastic cloud](https://cloud.elastic.co), check [here](https://github.com/elastic/beats/blob/master/metricbeat/module/kubernetes/_meta/test/docs/README.md) for details + - for managed mode: use [elastic cloud](https://cloud.elastic.co) or bring up the stack on docker and then connect docker network with kubernetes kind nodes: + ``` + elastic-package stack up -d -v + docker network connect elastic-package-stack_default + ``` + +1. Build elastic-agent: +```bash +cd x-pack/elastic-agent +DEV=true PLATFORMS=linux/amd64 TYPES=docker mage package +``` +2. Build docker image: +```bash +cd build/package/elastic-agent/elastic-agent-linux-amd64.docker/docker-build +docker build -t custom-agent-image . +``` +3. Load this image in your kind cluster: +``` +kind load docker-image custom-agent-image:latest +``` +4. Deploy agent with that image: +- download all-in-ome manifest for elastic-agent in standalone or managed mode, change version if needed +``` +ELASTIC_AGENT_VERSION="8.0" +ELASTIC_AGENT_MODE="standalone" # ELASTIC_AGENT_MODE="managed" +curl -L -O https://raw.githubusercontent.com/elastic/beats/${ELASTIC_AGENT_VERSION}/deploy/kubernetes/elastic-agent-${ELASTIC_AGENT_MODE}-kubernetes.yaml +``` +- Modify downloaded manifest: + - change image name to the one, that was created in the previous step and add `imagePullPolicy: Never`: + ``` + containers: + - name: elastic-agent + image: custom-agent-image:latest + imagePullPolicy: Never + ``` + - set environment variables accordingly to the used setup. + + Elastic-agent in standalone mode: set `ES_USERNAME`, `ES_PASSWORD`,`ES_HOST`. + + Elastic-agent in managed mode: set `FLEET_URL` and `FLEET_ENROLLMENT_TOKEN`. + +- create +``` +kubectl apply -f elastic-agent-${ELASTIC_AGENT_MODE}-kubernetes.yaml +``` +5. Check status of elastic-agent: +``` +kubectl -n kube-system get pods -l app=elastic-agent +``` From 95bdebf7cfd5d53f0ce4278bdb30b6e2ec72dec3 Mon Sep 17 00:00:00 2001 From: Tetiana Kravchenko Date: Wed, 1 Dec 2021 13:08:09 +0100 Subject: [PATCH 044/172] Align k8s metadata configurations in Kubernetes module: add addResourceMetadata config (#29133) * use addResourceMetadata config instead of hardcoded bool Signed-off-by: Tetiana Kravchenko * revert config for local dev Signed-off-by: Tetiana Kravchenko * update doc; use common function to create all watchers; add nodeWatcher and nsWatcher to enricher Signed-off-by: Tetiana Kravchenko * revert ek_stack Signed-off-by: Tetiana Kravchenko * add stop watchers; adjust test for dedoting labels; fix overriding config that leads to 'failed to parse field' error Signed-off-by: Tetiana Kravchenko * adjust log messages; check that watcher is not nil Signed-off-by: Tetiana Kravchenko * fix error message format; rename getPodMetadataWatchers -> getResourceMetadataWatchers; return resource watcher if nodeWatcher/nsWatcher failed to be created Signed-off-by: Tetiana Kravchenko * add changelog Signed-off-by: Tetiana Kravchenko --- CHANGELOG.next.asciidoc | 1 + .../autodiscover/providers/kubernetes/pod.go | 3 - .../providers/kubernetes/pod_test.go | 2 +- .../common/kubernetes/metadata/metadata.go | 3 +- .../kubernetes/metadata/namespace_test.go | 3 + libbeat/common/kubernetes/metadata/pod.go | 33 +-- .../common/kubernetes/metadata/pod_test.go | 155 ++++++++++++- .../common/kubernetes/metadata/resource.go | 2 +- .../add_kubernetes_metadata/indexers_test.go | 8 +- .../add_kubernetes_metadata/kubernetes.go | 3 - metricbeat/docs/modules/kubernetes.asciidoc | 20 ++ metricbeat/metricbeat.reference.yml | 20 ++ .../kubernetes/_meta/config.reference.yml | 20 ++ metricbeat/module/kubernetes/_meta/config.yml | 10 + .../module/kubernetes/util/kubernetes.go | 205 +++++++++++------- .../module/kubernetes/util/kubernetes_test.go | 4 +- metricbeat/modules.d/kubernetes.yml.disabled | 10 + .../composable/providers/kubernetes/pod.go | 4 +- x-pack/metricbeat/metricbeat.reference.yml | 20 ++ 19 files changed, 414 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index fbef98864e66..7173d86e206d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -371,6 +371,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Register additional name for `storage` metricset in the azure module. {pull}28447[28447] - Update reference to gosigar pacakge for filesystem windows fix. {pull}28909[28909] - Override `Host()` on statsd MetricSet {pull}29103[29103] +- Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] *Packetbeat* diff --git a/libbeat/autodiscover/providers/kubernetes/pod.go b/libbeat/autodiscover/providers/kubernetes/pod.go index 2e637cda41dd..945e39467b56 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod.go +++ b/libbeat/autodiscover/providers/kubernetes/pod.go @@ -100,9 +100,6 @@ func NewPodEventer(uuid uuid.UUID, cfg *common.Config, client k8s.Interface, pub options.Namespace = config.Namespace } metaConf := config.AddResourceMetadata - if metaConf == nil { - metaConf = metadata.GetDefaultResourceMetadataConfig() - } nodeWatcher, err := kubernetes.NewNamedWatcher("node", client, &kubernetes.Node{}, options, nil) if err != nil { logger.Errorf("couldn't create watcher for %T due to error %+v", &kubernetes.Node{}, err) diff --git a/libbeat/autodiscover/providers/kubernetes/pod_test.go b/libbeat/autodiscover/providers/kubernetes/pod_test.go index ed24f4554169..5388eeb4e6dc 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod_test.go +++ b/libbeat/autodiscover/providers/kubernetes/pod_test.go @@ -1907,7 +1907,7 @@ func TestPod_EmitEvent(t *testing.T) { t.Fatal(err) } - metaGen := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, client, nil, nil, true) + metaGen := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, client, nil, nil, nil) p := &Provider{ config: defaultConfig(), bus: bus.New(logp.NewLogger("bus"), "test"), diff --git a/libbeat/common/kubernetes/metadata/metadata.go b/libbeat/common/kubernetes/metadata/metadata.go index 7195d47ab0c4..eb55856081b5 100644 --- a/libbeat/common/kubernetes/metadata/metadata.go +++ b/libbeat/common/kubernetes/metadata/metadata.go @@ -96,8 +96,7 @@ func GetPodMetaGen( if namespaceWatcher != nil && metaConf.Namespace.Enabled() { namespaceMetaGen = NewNamespaceMetadataGenerator(metaConf.Namespace, namespaceWatcher.Store(), namespaceWatcher.Client()) } - metaGen := NewPodMetadataGenerator(cfg, podWatcher.Store(), podWatcher.Client(), nodeMetaGen, namespaceMetaGen, metaConf.Deployment) - + metaGen := NewPodMetadataGenerator(cfg, podWatcher.Store(), podWatcher.Client(), nodeMetaGen, namespaceMetaGen, metaConf) return metaGen } diff --git a/libbeat/common/kubernetes/metadata/namespace_test.go b/libbeat/common/kubernetes/metadata/namespace_test.go index 65ae39d8f5f4..88cc7859cdd7 100644 --- a/libbeat/common/kubernetes/metadata/namespace_test.go +++ b/libbeat/common/kubernetes/metadata/namespace_test.go @@ -51,9 +51,11 @@ func TestNamespace_Generate(t *testing.T) { UID: types.UID(uid), Labels: map[string]string{ "foo": "bar", + "key": "value", }, Annotations: map[string]string{ "spam": "baz", + "key": "value", }, }, TypeMeta: metav1.TypeMeta{ @@ -75,6 +77,7 @@ func TestNamespace_Generate(t *testing.T) { } cfg, err := common.NewConfigFrom(Config{ + IncludeLabels: []string{"foo"}, IncludeAnnotations: []string{"spam"}, }) if err != nil { diff --git a/libbeat/common/kubernetes/metadata/pod.go b/libbeat/common/kubernetes/metadata/pod.go index 5ec63292b6c8..ec6328aee968 100644 --- a/libbeat/common/kubernetes/metadata/pod.go +++ b/libbeat/common/kubernetes/metadata/pod.go @@ -29,12 +29,12 @@ import ( ) type pod struct { - store cache.Store - client k8s.Interface - node MetaGen - namespace MetaGen - resource *Resource - addDeployment bool + store cache.Store + client k8s.Interface + node MetaGen + namespace MetaGen + resource *Resource + addResourceMetadata *AddResourceMetadataConfig } // NewPodMetadataGenerator creates a metagen for pod resources @@ -44,14 +44,19 @@ func NewPodMetadataGenerator( client k8s.Interface, node MetaGen, namespace MetaGen, - addDeploymentMeta bool) MetaGen { + addResourceMetadata *AddResourceMetadataConfig) MetaGen { + + if addResourceMetadata == nil { + addResourceMetadata = GetDefaultResourceMetadataConfig() + } + return &pod{ - resource: NewResourceMetadataGenerator(cfg, client), - store: pods, - node: node, - namespace: namespace, - client: client, - addDeployment: addDeploymentMeta, + resource: NewResourceMetadataGenerator(cfg, client), + store: pods, + node: node, + namespace: namespace, + client: client, + addResourceMetadata: addResourceMetadata, } } @@ -87,7 +92,7 @@ func (p *pod) GenerateK8s(obj kubernetes.Resource, opts ...FieldOptions) common. out := p.resource.GenerateK8s("pod", obj, opts...) // check if Pod is handled by a ReplicaSet which is controlled by a Deployment - if p.addDeployment { + if p.addResourceMetadata.Deployment { rsName, _ := out.GetValue("replicaset.name") if rsName, ok := rsName.(string); ok { dep := p.getRSDeployment(rsName, po.GetNamespace()) diff --git a/libbeat/common/kubernetes/metadata/pod_test.go b/libbeat/common/kubernetes/metadata/pod_test.go index 12e2da4fd3c9..a780d3d2daf4 100644 --- a/libbeat/common/kubernetes/metadata/pod_test.go +++ b/libbeat/common/kubernetes/metadata/pod_test.go @@ -374,7 +374,7 @@ func TestPod_Generate(t *testing.T) { }) assert.NoError(t, err) - metagen := NewPodMetadataGenerator(config, nil, client, nil, nil, true) + metagen := NewPodMetadataGenerator(config, nil, client, nil, nil, nil) for _, test := range tests { t.Run(test.name, func(t *testing.T) { assert.Equal(t, test.output, metagen.Generate(test.input)) @@ -496,7 +496,7 @@ func TestPod_GenerateFromName(t *testing.T) { assert.NoError(t, err) pods := cache.NewStore(cache.MetaNamespaceKeyFunc) pods.Add(test.input) - metagen := NewPodMetadataGenerator(config, pods, client, nil, nil, true) + metagen := NewPodMetadataGenerator(config, pods, client, nil, nil, nil) accessor, err := meta.Accessor(test.input) require.NoError(t, err) @@ -618,7 +618,156 @@ func TestPod_GenerateWithNodeNamespace(t *testing.T) { namespaces.Add(test.namespace) nsMeta := NewNamespaceMetadataGenerator(config, namespaces, client) - metagen := NewPodMetadataGenerator(config, pods, client, nodeMeta, nsMeta, true) + metagen := NewPodMetadataGenerator(config, pods, client, nodeMeta, nsMeta, nil) + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.output, metagen.Generate(test.input)) + }) + } +} + +func TestPod_GenerateWithNodeNamespaceWithAddResourceConfig(t *testing.T) { + client := k8sfake.NewSimpleClientset() + uid := "005f3b90-4b9d-12f8-acf0-31020a840133" + namespace := "default" + name := "obj" + boolean := true + + tests := []struct { + input kubernetes.Resource + node kubernetes.Resource + namespace kubernetes.Resource + output common.MapStr + name string + }{ + { + name: "test simple object", + input: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + UID: types.UID(uid), + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "exporter", + }, + Annotations: map[string]string{ + "app": "production", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "apps", + Kind: "ReplicaSet", + Name: "nginx-rs", + UID: "005f3b90-4b9d-12f8-acf0-31020a8409087", + Controller: &boolean, + }, + }, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + APIVersion: "v1", + }, + + Spec: v1.PodSpec{ + NodeName: "testnode", + }, + Status: v1.PodStatus{PodIP: "127.0.0.5"}, + }, + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testnode", + UID: types.UID(uid), + Labels: map[string]string{ + "nodekey": "nodevalue", + "nodekey2": "nodevalue2", + }, + Annotations: map[string]string{}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Node", + APIVersion: "v1", + }, + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{{Type: v1.NodeHostName, Address: "node1"}}, + }, + }, + namespace: &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + UID: types.UID(uid), + Labels: map[string]string{ + "app.kubernetes.io/name": "kube-state-metrics", + "nskey2": "nsvalue2", + }, + Annotations: map[string]string{}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Namespace", + APIVersion: "v1", + }, + }, + output: common.MapStr{"kubernetes": common.MapStr{ + "pod": common.MapStr{ + "name": "obj", + "uid": uid, + "ip": "127.0.0.5", + }, + "namespace": "default", + "namespace_uid": uid, + "namespace_labels": common.MapStr{ + "app_kubernetes_io/name": "kube-state-metrics", + }, + "node": common.MapStr{ + "name": "testnode", + "uid": uid, + "labels": common.MapStr{ + "nodekey2": "nodevalue2", + }, + "hostname": "node1", + }, + "labels": common.MapStr{ + "app_kubernetes_io/component": "exporter", + }, + "annotations": common.MapStr{ + "app": "production", + }, + "replicaset": common.MapStr{ + "name": "nginx-rs", + }, + }}, + }, + } + + for _, test := range tests { + config, err := common.NewConfigFrom(map[string]interface{}{ + "include_annotations": []string{"app"}, + }) + + assert.NoError(t, err) + + namespaceConfig, _ := common.NewConfigFrom(map[string]interface{}{ + "include_labels": []string{"app.kubernetes.io/name"}, + }) + nodeConfig, _ := common.NewConfigFrom(map[string]interface{}{ + "include_labels": []string{"nodekey2"}, + }) + metaConfig := AddResourceMetadataConfig{ + Namespace: namespaceConfig, + Node: nodeConfig, + Deployment: false, + } + + pods := cache.NewStore(cache.MetaNamespaceKeyFunc) + pods.Add(test.input) + + nodes := cache.NewStore(cache.MetaNamespaceKeyFunc) + nodes.Add(test.node) + nodeMeta := NewNodeMetadataGenerator(nodeConfig, nodes, client) + + namespaces := cache.NewStore(cache.MetaNamespaceKeyFunc) + namespaces.Add(test.namespace) + nsMeta := NewNamespaceMetadataGenerator(namespaceConfig, namespaces, client) + + metagen := NewPodMetadataGenerator(config, pods, client, nodeMeta, nsMeta, &metaConfig) t.Run(test.name, func(t *testing.T) { assert.Equal(t, test.output, metagen.Generate(test.input)) }) diff --git a/libbeat/common/kubernetes/metadata/resource.go b/libbeat/common/kubernetes/metadata/resource.go index b15e39b3775c..152c2be37a3b 100644 --- a/libbeat/common/kubernetes/metadata/resource.go +++ b/libbeat/common/kubernetes/metadata/resource.go @@ -85,7 +85,7 @@ func (r *Resource) GenerateK8s(kind string, obj kubernetes.Resource, options ... return nil } - labelMap := common.MapStr{} + var labelMap common.MapStr if len(r.config.IncludeLabels) == 0 { labelMap = GenerateMap(accessor.GetLabels(), r.config.LabelsDedot) } else { diff --git a/libbeat/processors/add_kubernetes_metadata/indexers_test.go b/libbeat/processors/add_kubernetes_metadata/indexers_test.go index 853345c8bd57..51ba288974c6 100644 --- a/libbeat/processors/add_kubernetes_metadata/indexers_test.go +++ b/libbeat/processors/add_kubernetes_metadata/indexers_test.go @@ -32,7 +32,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/kubernetes" ) -var metagen = metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, true) +var metagen = metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, nil) func TestPodIndexer(t *testing.T) { var testConfig = common.NewConfig() @@ -90,7 +90,7 @@ func TestPodIndexer(t *testing.T) { func TestPodUIDIndexer(t *testing.T) { var testConfig = common.NewConfig() - metaGenWithPodUID := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, true) + metaGenWithPodUID := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, nil) podUIDIndexer, err := NewPodUIDIndexer(*testConfig, metaGenWithPodUID) assert.NoError(t, err) @@ -301,7 +301,7 @@ func TestFilteredGenMeta(t *testing.T) { }) assert.NoError(t, err) - filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, true) + filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, nil) podIndexer, err = NewPodNameIndexer(*testConfig, filteredGen) assert.NoError(t, err) @@ -338,7 +338,7 @@ func TestFilteredGenMetaExclusion(t *testing.T) { }) assert.NoError(t, err) - filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, true) + filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, nil) podIndexer, err := NewPodNameIndexer(*testConfig, filteredGen) assert.NoError(t, err) diff --git a/libbeat/processors/add_kubernetes_metadata/kubernetes.go b/libbeat/processors/add_kubernetes_metadata/kubernetes.go index 2255bed3f6bd..a4b40b9655d9 100644 --- a/libbeat/processors/add_kubernetes_metadata/kubernetes.go +++ b/libbeat/processors/add_kubernetes_metadata/kubernetes.go @@ -191,9 +191,6 @@ func (k *kubernetesAnnotator) init(config kubeAnnotatorConfig, cfg *common.Confi } metaConf := config.AddResourceMetadata - if metaConf == nil { - metaConf = metadata.GetDefaultResourceMetadataConfig() - } options := kubernetes.WatchOptions{ SyncTimeout: config.SyncPeriod, diff --git a/metricbeat/docs/modules/kubernetes.asciidoc b/metricbeat/docs/modules/kubernetes.asciidoc index e7b82455189b..52f0b07a75fc 100644 --- a/metricbeat/docs/modules/kubernetes.asciidoc +++ b/metricbeat/docs/modules/kubernetes.asciidoc @@ -222,6 +222,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 @@ -256,6 +266,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 7673d7b01b50..c036073f011a 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -500,6 +500,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 @@ -534,6 +544,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 diff --git a/metricbeat/module/kubernetes/_meta/config.reference.yml b/metricbeat/module/kubernetes/_meta/config.reference.yml index 09fb14662a21..2a9f4601f869 100644 --- a/metricbeat/module/kubernetes/_meta/config.reference.yml +++ b/metricbeat/module/kubernetes/_meta/config.reference.yml @@ -23,6 +23,16 @@ # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 @@ -57,6 +67,16 @@ # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 diff --git a/metricbeat/module/kubernetes/_meta/config.yml b/metricbeat/module/kubernetes/_meta/config.yml index dc9b3697ead8..94b0a00427fe 100644 --- a/metricbeat/module/kubernetes/_meta/config.yml +++ b/metricbeat/module/kubernetes/_meta/config.yml @@ -22,6 +22,16 @@ #host: node_name # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false #kube_config: ~/.kube/config # Kubernetes client QPS and burst can be configured additionally #kube_client_options: diff --git a/metricbeat/module/kubernetes/util/kubernetes.go b/metricbeat/module/kubernetes/util/kubernetes.go index 6f4b7c44d281..b173c6de3600 100644 --- a/metricbeat/module/kubernetes/util/kubernetes.go +++ b/metricbeat/module/kubernetes/util/kubernetes.go @@ -48,12 +48,15 @@ type Enricher interface { } type kubernetesConfig struct { - // AddMetadata enables enriching metricset events with metadata from the API server - AddMetadata bool `config:"add_metadata"` KubeConfig string `config:"kube_config"` - Host string `config:"host"` - SyncPeriod time.Duration `config:"sync_period"` KubeClientOptions kubernetes.KubeClientOptions `config:"kube_client_options"` + + Host string `config:"host"` + SyncPeriod time.Duration `config:"sync_period"` + + // AddMetadata enables enriching metricset events with metadata from the API server + AddMetadata bool `config:"add_metadata"` + AddResourceMetadata *metadata.AddResourceMetadataConfig `config:"add_resource_metadata"` } type enricher struct { @@ -63,90 +66,45 @@ type enricher struct { watcher kubernetes.Watcher watcherStarted bool watcherStartedLock sync.Mutex + namespaceWatcher kubernetes.Watcher + nodeWatcher kubernetes.Watcher isPod bool } const selector = "kubernetes" -// GetWatcher initializes a kubernetes watcher with the given -// scope (node or cluster), and resource type -func GetWatcher(base mb.BaseMetricSet, resource kubernetes.Resource, nodeScope bool) (kubernetes.Watcher, error) { - return GetNamedWatcher("", base, resource, nodeScope) -} - -func GetNamedWatcher(name string, base mb.BaseMetricSet, resource kubernetes.Resource, nodeScope bool) (kubernetes.Watcher, error) { - config := kubernetesConfig{ - AddMetadata: true, - SyncPeriod: time.Minute * 10, - } - if err := base.Module().UnpackConfig(&config); err != nil { - return nil, err - } - - // Return nil if metadata enriching is disabled: - if !config.AddMetadata { - return nil, nil - } - - client, err := kubernetes.GetKubernetesClient(config.KubeConfig, config.KubeClientOptions) - if err != nil { - return nil, err - } - - options := kubernetes.WatchOptions{ - SyncTimeout: config.SyncPeriod, - } - - log := logp.NewLogger(selector) - - // Watch objects in the node only - if nodeScope { - nd := &kubernetes.DiscoverKubernetesNodeParams{ - ConfigHost: config.Host, - Client: client, - IsInCluster: kubernetes.IsInCluster(config.KubeConfig), - HostUtils: &kubernetes.DefaultDiscoveryUtils{}, - } - options.Node, err = kubernetes.DiscoverKubernetesNode(log, nd) - if err != nil { - return nil, fmt.Errorf("couldn't discover kubernetes node: %w", err) - } - } - - log.Debugf("Initializing a new Kubernetes watcher using host: %v", config.Host) - - return kubernetes.NewNamedWatcher(name, client, resource, options, nil) -} - // NewResourceMetadataEnricher returns an Enricher configured for kubernetes resource events func NewResourceMetadataEnricher( base mb.BaseMetricSet, res kubernetes.Resource, nodeScope bool) Enricher { - watcher, err := GetNamedWatcher("resource_metadata_enricher", base, res, nodeScope) - if err != nil { - logp.Err("Error initializing Kubernetes metadata enricher: %s", err) + config := validatedConfig(base) + if config == nil { + logp.Info("Kubernetes metricset enriching is disabled") return &nilEnricher{} } + watcher, nodeWatcher, namespaceWatcher := getResourceMetadataWatchers(config, res, nodeScope) + if watcher == nil { - logp.Info("Kubernetes metricset enriching is disabled") return &nilEnricher{} } - metaConfig := metadata.Config{} - if err := base.Module().UnpackConfig(&metaConfig); err != nil { + // GetPodMetaGen requires cfg of type Config + commonMetaConfig := metadata.Config{} + if err := base.Module().UnpackConfig(&commonMetaConfig); err != nil { logp.Err("Error initializing Kubernetes metadata enricher: %s", err) return &nilEnricher{} } - - cfg, _ := common.NewConfigFrom(&metaConfig) + cfg, _ := common.NewConfigFrom(&commonMetaConfig) metaGen := metadata.NewResourceMetadataGenerator(cfg, watcher.Client()) - podMetaGen := metadata.NewPodMetadataGenerator(cfg, nil, watcher.Client(), nil, nil, true) - serviceMetaGen := metadata.NewServiceMetadataGenerator(cfg, nil, nil, watcher.Client()) - enricher := buildMetadataEnricher(watcher, + podMetaGen := metadata.GetPodMetaGen(cfg, watcher, nodeWatcher, namespaceWatcher, config.AddResourceMetadata) + + namespaceMeta := metadata.NewNamespaceMetadataGenerator(config.AddResourceMetadata.Namespace, namespaceWatcher.Store(), watcher.Client()) + serviceMetaGen := metadata.NewServiceMetadataGenerator(cfg, watcher.Store(), namespaceMeta, watcher.Client()) + enricher := buildMetadataEnricher(watcher, nodeWatcher, namespaceWatcher, // update func(m map[string]common.MapStr, r kubernetes.Resource) { accessor, _ := meta.Accessor(r) @@ -214,27 +172,27 @@ func NewContainerMetadataEnricher( base mb.BaseMetricSet, nodeScope bool) Enricher { - watcher, err := GetNamedWatcher("container_metadata_enricher", base, &kubernetes.Pod{}, nodeScope) - if err != nil { - logp.Err("Error initializing Kubernetes metadata enricher: %s", err) + config := validatedConfig(base) + if config == nil { + logp.Info("Kubernetes metricset enriching is disabled") return &nilEnricher{} } + watcher, nodeWatcher, namespaceWatcher := getResourceMetadataWatchers(config, &kubernetes.Pod{}, nodeScope) if watcher == nil { - logp.Info("Kubernetes metricset enriching is disabled") return &nilEnricher{} } - metaConfig := metadata.Config{} - if err := base.Module().UnpackConfig(&metaConfig); err != nil { + commonMetaConfig := metadata.Config{} + if err := base.Module().UnpackConfig(&commonMetaConfig); err != nil { logp.Err("Error initializing Kubernetes metadata enricher: %s", err) return &nilEnricher{} } + cfg, _ := common.NewConfigFrom(&commonMetaConfig) - cfg, _ := common.NewConfigFrom(&metaConfig) + metaGen := metadata.GetPodMetaGen(cfg, watcher, nodeWatcher, namespaceWatcher, config.AddResourceMetadata) - metaGen := metadata.NewPodMetadataGenerator(cfg, nil, watcher.Client(), nil, nil, true) - enricher := buildMetadataEnricher(watcher, + enricher := buildMetadataEnricher(watcher, nodeWatcher, namespaceWatcher, // update func(m map[string]common.MapStr, r kubernetes.Resource) { pod := r.(*kubernetes.Pod) @@ -276,6 +234,76 @@ func NewContainerMetadataEnricher( return enricher } +func getResourceMetadataWatchers(config *kubernetesConfig, resource kubernetes.Resource, nodeScope bool) (kubernetes.Watcher, kubernetes.Watcher, kubernetes.Watcher) { + client, err := kubernetes.GetKubernetesClient(config.KubeConfig, config.KubeClientOptions) + if err != nil { + logp.Err("Error creating Kubernetes client: %s", err) + return nil, nil, nil + } + + options := kubernetes.WatchOptions{ + SyncTimeout: config.SyncPeriod, + } + + log := logp.NewLogger(selector) + + // Watch objects in the node only + if nodeScope { + nd := &kubernetes.DiscoverKubernetesNodeParams{ + ConfigHost: config.Host, + Client: client, + IsInCluster: kubernetes.IsInCluster(config.KubeConfig), + HostUtils: &kubernetes.DefaultDiscoveryUtils{}, + } + options.Node, err = kubernetes.DiscoverKubernetesNode(log, nd) + if err != nil { + logp.Err("Couldn't discover kubernetes node: %s", err) + return nil, nil, nil + } + } + + log.Debugf("Initializing a new Kubernetes watcher using host: %v", config.Host) + + watcher, err := kubernetes.NewNamedWatcher("resource_metadata_enricher", client, resource, options, nil) + if err != nil { + logp.Err("Error initializing Kubernetes watcher: %s", err) + return nil, nil, nil + } + + nodeWatcher, err := kubernetes.NewNamedWatcher("resource_metadata_enricher_node", client, &kubernetes.Node{}, options, nil) + if err != nil { + logp.Err("Error creating watcher for %T due to error %+v", &kubernetes.Node{}, err) + return watcher, nil, nil + } + + namespaceWatcher, err := kubernetes.NewNamedWatcher("resource_metadata_enricher_namespace", client, &kubernetes.Namespace{}, kubernetes.WatchOptions{ + SyncTimeout: config.SyncPeriod, + }, nil) + if err != nil { + logp.Err("Error creating watcher for %T due to error %+v", &kubernetes.Namespace{}, err) + return watcher, nodeWatcher, nil + } + + return watcher, nodeWatcher, namespaceWatcher +} + +func validatedConfig(base mb.BaseMetricSet) *kubernetesConfig { + config := kubernetesConfig{ + AddMetadata: true, + SyncPeriod: time.Minute * 10, + AddResourceMetadata: metadata.GetDefaultResourceMetadataConfig(), + } + if err := base.Module().UnpackConfig(&config); err != nil { + return nil + } + + // Return nil if metadata enriching is disabled: + if !config.AddMetadata { + return nil + } + return &config +} + func getString(m common.MapStr, key string) string { val, err := m.GetValue(key) if err != nil { @@ -292,14 +320,18 @@ func join(fields ...string) string { func buildMetadataEnricher( watcher kubernetes.Watcher, + nodeWatcher kubernetes.Watcher, + namespaceWatcher kubernetes.Watcher, update func(map[string]common.MapStr, kubernetes.Resource), delete func(map[string]common.MapStr, kubernetes.Resource), index func(e common.MapStr) string) *enricher { enricher := enricher{ - metadata: map[string]common.MapStr{}, - index: index, - watcher: watcher, + metadata: map[string]common.MapStr{}, + index: index, + watcher: watcher, + nodeWatcher: nodeWatcher, + namespaceWatcher: namespaceWatcher, } watcher.AddEventHandler(kubernetes.ResourceEventHandlerFuncs{ @@ -326,6 +358,18 @@ func buildMetadataEnricher( func (m *enricher) Start() { m.watcherStartedLock.Lock() defer m.watcherStartedLock.Unlock() + if m.nodeWatcher != nil { + if err := m.nodeWatcher.Start(); err != nil { + logp.Warn("Error starting node watcher: %s", err) + } + } + + if m.namespaceWatcher != nil { + if err := m.namespaceWatcher.Start(); err != nil { + logp.Warn("Error starting namespace watcher: %s", err) + } + } + if !m.watcherStarted { err := m.watcher.Start() if err != nil { @@ -342,6 +386,13 @@ func (m *enricher) Stop() { m.watcher.Stop() m.watcherStarted = false } + if m.namespaceWatcher != nil { + m.namespaceWatcher.Stop() + } + + if m.nodeWatcher != nil { + m.nodeWatcher.Stop() + } } func (m *enricher) Enrich(events []common.MapStr) { diff --git a/metricbeat/module/kubernetes/util/kubernetes_test.go b/metricbeat/module/kubernetes/util/kubernetes_test.go index 4ab9acc9d5d5..83bbd3dd1f7a 100644 --- a/metricbeat/module/kubernetes/util/kubernetes_test.go +++ b/metricbeat/module/kubernetes/util/kubernetes_test.go @@ -36,6 +36,8 @@ import ( func TestBuildMetadataEnricher(t *testing.T) { watcher := mockWatcher{} + nodeWatcher := mockWatcher{} + namespaceWatcher := mockWatcher{} funcs := mockFuncs{} resource := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -48,7 +50,7 @@ func TestBuildMetadataEnricher(t *testing.T) { }, } - enricher := buildMetadataEnricher(&watcher, funcs.update, funcs.delete, funcs.index) + enricher := buildMetadataEnricher(&watcher, &nodeWatcher, &namespaceWatcher, funcs.update, funcs.delete, funcs.index) assert.NotNil(t, watcher.handler) enricher.Start() diff --git a/metricbeat/modules.d/kubernetes.yml.disabled b/metricbeat/modules.d/kubernetes.yml.disabled index 08203350e93d..144d13fb301b 100644 --- a/metricbeat/modules.d/kubernetes.yml.disabled +++ b/metricbeat/modules.d/kubernetes.yml.disabled @@ -25,6 +25,16 @@ #host: node_name # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false #kube_config: ~/.kube/config # Kubernetes client QPS and burst can be configured additionally #kube_client_options: diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go index 3a702b95c0e0..bb9ec52887fe 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go @@ -89,9 +89,7 @@ func NewPodEventer( Node: cfg.Node, } metaConf := cfg.AddResourceMetadata - if metaConf == nil { - metaConf = metadata.GetDefaultResourceMetadataConfig() - } + nodeWatcher, err := kubernetes.NewNamedWatcher("agent-node", client, &kubernetes.Node{}, options, nil) if err != nil { logger.Errorf("couldn't create watcher for %T due to error %+v", &kubernetes.Node{}, err) diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index be4adb144c8a..4d1d41aa0d52 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -872,6 +872,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 @@ -906,6 +916,16 @@ metricbeat.modules: # If kube_config is not set, KUBECONFIG environment variable will be checked # and if not present it will fall back to InCluster #kube_config: ~/.kube/config + # To configure additionally node and namespace metadata, added to pod, service and container resource types, + # `add_resource_metadata` can be defined. + # By default all labels will be included while annotations are not added by default. + # add_resource_metadata: + # namespace: + # include_labels: ["namespacelabel1"] + # node: + # include_labels: ["nodelabel2"] + # include_annotations: ["nodeannotation1"] + # deployment: false # Kubernetes client QPS and burst can be configured additionally #kube_client_options: # qps: 5 From 9d6ea3bd364d39375a4451b41f7a4e71cd3ef068 Mon Sep 17 00:00:00 2001 From: Henadzi Siardziukou <92367828+nxei@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:10:13 +0300 Subject: [PATCH 045/172] [mergify] use merge queue (#29179) --- .mergify.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index d2ee975b7e1f..c76feb76e984 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,3 +1,7 @@ +queue_rules: + - name: default + conditions: + - check-success=beats-ci/pr-merge pull_request_rules: - name: forward-port patches to master branch conditions: @@ -45,9 +49,9 @@ pull_request_rules: - files~=^testing/environments/snapshot.*\.yml$ - "#approved-reviews-by>=1" actions: - merge: + queue: method: squash - strict: false + name: default - name: delete upstream branch after merging changes on testing/environments/snapshot* or it's closed conditions: - or: @@ -89,9 +93,9 @@ pull_request_rules: - head~=^add-backport-next.* - "#approved-reviews-by>=1" actions: - merge: + queue: method: squash - strict: false + name: default - name: delete upstream branch with changes on ^.mergify.yml that has been merged or closed conditions: - or: From 6d61810981cb3a61968f7a489cf24aa8e3f80cad Mon Sep 17 00:00:00 2001 From: Fae Charlton Date: Wed, 1 Dec 2021 10:27:39 -0500 Subject: [PATCH 046/172] Remove beta warning for SASL/SCRAM on Kafka GA (#29126) --- CHANGELOG.next.asciidoc | 1 + libbeat/outputs/kafka/docs/kafka.asciidoc | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 7173d86e206d..43bb6e61e2f5 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -288,6 +288,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Update to ECS 8.0 fields. {pull}28620[28620] - Add http.pprof.enabled option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] - Support custom analyzers in fields.yml. {issue}28540[28540] {pull}28926[28926] +- SASL/SCRAM in the Kafka output is no longer beta. {pull}29126[29126] *Auditbeat* diff --git a/libbeat/outputs/kafka/docs/kafka.asciidoc b/libbeat/outputs/kafka/docs/kafka.asciidoc index 85b467ab3f20..28892f57aa01 100644 --- a/libbeat/outputs/kafka/docs/kafka.asciidoc +++ b/libbeat/outputs/kafka/docs/kafka.asciidoc @@ -79,8 +79,6 @@ The password for connecting to Kafka. ===== `sasl.mechanism` -beta[] - The SASL mechanism to use when connecting to Kafka. It can be one of: * `PLAIN` for SASL/PLAIN. From 4b30bc76fce751d7966e20a922370db471e644df Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 1 Dec 2021 16:30:45 +0100 Subject: [PATCH 047/172] [Elastic Agent] Include osquerybeat in builds (#29196) [Elastic Agent] Include osquerybeat in builds --- dev-tools/packaging/packages.yml | 48 ++++++++++++++++++++++++++++++++ x-pack/elastic-agent/magefile.go | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index 4978d4ffb4d8..09efabf28260 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -94,6 +94,18 @@ shared: source: '{{.AgentDropPath}}/metricbeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' mode: 0644 skip_on_missing: true + /var/lib/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' + mode: 0644 + skip_on_missing: true + /var/lib/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512' + mode: 0644 + skip_on_missing: true + /var/lib/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' + mode: 0644 + skip_on_missing: true /var/lib/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz: source: '{{.AgentDropPath}}/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' mode: 0644 @@ -210,6 +222,18 @@ shared: source: '{{.AgentDropPath}}/metricbeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' mode: 0644 skip_on_missing: true + /etc/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' + mode: 0644 + skip_on_missing: true + /etc/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512' + mode: 0644 + skip_on_missing: true + /etc/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc: + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' + mode: 0644 + skip_on_missing: true /etc/{{.BeatName}}/data/{{.BeatName}}-{{ commit_short }}/downloads/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz: source: '{{.AgentDropPath}}/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' mode: 0644 @@ -314,6 +338,18 @@ shared: source: '{{.AgentDropPath}}/metricbeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' mode: 0644 skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' + mode: 0644 + skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.sha512' + mode: 0644 + skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz.asc' + mode: 0644 + skip_on_missing: true 'data/{{.BeatName}}-{{ commit_short }}/downloads/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz': source: '{{.AgentDropPath}}/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz' mode: 0644 @@ -387,6 +423,18 @@ shared: source: '{{.AgentDropPath}}/metricbeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip.asc' mode: 0644 skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip' + mode: 0644 + skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip.sha512': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip.sha512' + mode: 0644 + skip_on_missing: true + 'data/{{.BeatName}}-{{ commit_short }}/downloads/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip.asc': + source: '{{.AgentDropPath}}/osquerybeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip.asc' + mode: 0644 + skip_on_missing: true 'data/{{.BeatName}}-{{ commit_short }}/downloads/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip': source: '{{.AgentDropPath}}/endpoint-security-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.zip' mode: 0644 diff --git a/x-pack/elastic-agent/magefile.go b/x-pack/elastic-agent/magefile.go index 102ba5b86b0e..ccceaf06935e 100644 --- a/x-pack/elastic-agent/magefile.go +++ b/x-pack/elastic-agent/magefile.go @@ -595,7 +595,7 @@ func packageAgent(requiredPackages []string, packagingFn func()) { defer os.RemoveAll(dropPath) defer os.Unsetenv(agentDropPath) - packedBeats := []string{"filebeat", "heartbeat", "metricbeat"} + packedBeats := []string{"filebeat", "heartbeat", "metricbeat", "osquerybeat"} for _, b := range packedBeats { pwd, err := filepath.Abs(filepath.Join("..", b)) From 8fa9aba9cf97bc3991ea6f5b704293e21fd466c1 Mon Sep 17 00:00:00 2001 From: Silvia Mitter Date: Wed, 1 Dec 2021 16:34:45 +0100 Subject: [PATCH 048/172] Allow Accept and Content-Type headers to be set (#29176) --- libbeat/esleg/eslegclient/connection.go | 6 +++- libbeat/esleg/eslegclient/connection_test.go | 36 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/libbeat/esleg/eslegclient/connection.go b/libbeat/esleg/eslegclient/connection.go index 8db37a9b0efd..d14ba8544f06 100644 --- a/libbeat/esleg/eslegclient/connection.go +++ b/libbeat/esleg/eslegclient/connection.go @@ -421,7 +421,11 @@ func (conn *Connection) execHTTPRequest(req *http.Request) (int, []byte, error) } for name, value := range conn.Headers { - req.Header.Add(name, value) + if name == "Content-Type" || name == "Accept" { + req.Header.Set(name, value) + } else { + req.Header.Add(name, value) + } } // The stlib will override the value in the header based on the configured `Host` diff --git a/libbeat/esleg/eslegclient/connection_test.go b/libbeat/esleg/eslegclient/connection_test.go index 72b78f27e1d9..e0735ebe992d 100644 --- a/libbeat/esleg/eslegclient/connection_test.go +++ b/libbeat/esleg/eslegclient/connection_test.go @@ -64,3 +64,39 @@ func (c *mockClient) CloseIdleConnections() {} func newMockClient() *mockClient { return &mockClient{} } + +func TestHeaders(t *testing.T) { + for _, td := range []struct { + input map[string]string + expected map[string][]string + }{ + {input: map[string]string{ + "Accept": "application/vnd.elasticsearch+json;compatible-with=7", + "Content-Type": "application/vnd.elasticsearch+json;compatible-with=7", + "X-My-Header": "true"}, + expected: map[string][]string{ + "Accept": {"application/vnd.elasticsearch+json;compatible-with=7"}, + "Content-Type": {"application/vnd.elasticsearch+json;compatible-with=7"}, + "X-My-Header": {"true"}}}, + {input: map[string]string{ + "X-My-Header": "true"}, + expected: map[string][]string{ + "Accept": {"application/json"}, + "X-My-Header": {"true"}}}, + } { + conn, err := NewConnection(ConnectionSettings{ + Headers: td.input, + }) + require.NoError(t, err) + + httpClient := newMockClient() + conn.HTTP = httpClient + + req, err := http.NewRequest("GET", "http://fakehost/some/path", nil) + require.NoError(t, err) + _, _, err = conn.execHTTPRequest(req) + require.NoError(t, err) + + require.Equal(t, req.Header, http.Header(td.expected)) + } +} From ee97b2f22dae0ee50ad9bbad77e5945674f93db3 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Wed, 1 Dec 2021 17:20:25 +0100 Subject: [PATCH 049/172] Fix flakiness in goroutines checker tests (#29157) Goroutines of one test case might be still running on the following ones, affecting the results. Add an object that helps keeping track of started goroutines and ensures that they are stopped before continuing with the next case. --- libbeat/tests/resources/goroutines.go | 35 +++++++---- libbeat/tests/resources/goroutines_test.go | 73 +++++++++++++++------- 2 files changed, 73 insertions(+), 35 deletions(-) diff --git a/libbeat/tests/resources/goroutines.go b/libbeat/tests/resources/goroutines.go index 7ab2c6803ae5..7c9ab170dff3 100644 --- a/libbeat/tests/resources/goroutines.go +++ b/libbeat/tests/resources/goroutines.go @@ -52,21 +52,24 @@ func NewGoroutinesChecker() GoroutinesChecker { // was created func (c GoroutinesChecker) Check(t testing.TB) { t.Helper() - err := c.check(t) + err := c.check() if err != nil { + dumpGoroutines() t.Error(err) } } -func (c GoroutinesChecker) check(t testing.TB) error { - after := c.WaitUntilOriginalCount() - if after == 0 { - return nil - } - +func dumpGoroutines() { profile := pprof.Lookup("goroutine") profile.WriteTo(os.Stdout, 2) - return fmt.Errorf("Possible goroutines leak, before: %d, after: %d", c.before, after) +} + +func (c GoroutinesChecker) check() error { + after, err := c.WaitUntilOriginalCount() + if err == ErrTimeout { + return fmt.Errorf("possible goroutines leak, before: %d, after: %d", c.before, after) + } + return err } // CallAndCheckGoroutines calls a function and checks if it has increased @@ -78,21 +81,29 @@ func CallAndCheckGoroutines(t testing.TB, f func()) { c.Check(t) } +// ErrTimeout is the error returned when WaitUntilOriginalCount timeouts. +var ErrTimeout = fmt.Errorf("timeout waiting for finalization of goroutines") + // WaitUntilOriginalCount waits until the original number of goroutines are -// present before we has created the resource checker. -func (c GoroutinesChecker) WaitUntilOriginalCount() int { +// present before we created the resource checker. +// It returns the number of goroutines after the check and a timeout error +// in case the wait has expired. +func (c GoroutinesChecker) WaitUntilOriginalCount() (int, error) { timeout := time.Now().Add(c.FinalizationTimeout) + var after int for time.Now().Before(timeout) { after = runtime.NumGoroutine() if after <= c.before { - return 0 + return after, nil } time.Sleep(10 * time.Millisecond) } - return after + return after, ErrTimeout } +// WaitUntilIncreased waits till the number of goroutines is n plus the number +// before creating the checker. func (c *GoroutinesChecker) WaitUntilIncreased(n int) { for runtime.NumGoroutine() < c.before+n { time.Sleep(10 * time.Millisecond) diff --git a/libbeat/tests/resources/goroutines_test.go b/libbeat/tests/resources/goroutines_test.go index 7f146318a663..369ba0c1ad1e 100644 --- a/libbeat/tests/resources/goroutines_test.go +++ b/libbeat/tests/resources/goroutines_test.go @@ -25,54 +25,45 @@ import ( ) func TestGoroutinesChecker(t *testing.T) { - block := make(chan struct{}) - defer close(block) - cases := []struct { title string - test func() + test func(ctl *goroutineTesterControl) timeout time.Duration fail bool }{ { title: "no goroutines", - test: func() {}, + test: func(ctl *goroutineTesterControl) {}, }, { title: "fast goroutine", - test: func() { - started := make(chan struct{}) - go func() { - started <- struct{}{} - }() - <-started + test: func(ctl *goroutineTesterControl) { + ctl.startGoroutine(func() {}) }, }, - /* Skipped due to flakyness: https://github.com/elastic/beats/issues/12692 { title: "blocked goroutine", - test: func() { - started := make(chan struct{}) - go func() { - started <- struct{}{} - <-block - }() - <-started + test: func(ctl *goroutineTesterControl) { + ctl.startGoroutine(func() { + ctl.block() + }) }, - timeout: 500 * time.Millisecond, + timeout: 10 * time.Millisecond, fail: true, }, - */ } for _, c := range cases { t.Run(c.title, func(t *testing.T) { + ctl := newControl() + defer ctl.cleanup(t) + goroutines := NewGoroutinesChecker() if c.timeout > 0 { goroutines.FinalizationTimeout = c.timeout } - c.test() - err := goroutines.check(t) + c.test(ctl) + err := goroutines.check() if c.fail { assert.Error(t, err) } else { @@ -81,3 +72,39 @@ func TestGoroutinesChecker(t *testing.T) { }) } } + +// goroutineTesterControl helps keeping track of goroutines started for each test case. +type goroutineTesterControl struct { + checker GoroutinesChecker + blocker chan struct{} +} + +func newControl() *goroutineTesterControl { + return &goroutineTesterControl{ + checker: NewGoroutinesChecker(), + blocker: make(chan struct{}), + } +} + +// startGoroutine ensures that a goroutine is started before continuing. +func (c *goroutineTesterControl) startGoroutine(f func()) { + started := make(chan struct{}) + go func() { + started <- struct{}{} + f() + }() + <-started +} + +// block blocks forever (being "ever" the life of the test). +func (c *goroutineTesterControl) block() { + <-c.blocker +} + +// cleanup ensures that all started goroutines are finished. +func (c *goroutineTesterControl) cleanup(t *testing.T) { + close(c.blocker) + if _, err := c.checker.WaitUntilOriginalCount(); err != nil { + t.Fatal("goroutines in test cases should be started using startGoroutine") + } +} From 1bd0da5c9198c0443fe87410fc3892fd14c986a5 Mon Sep 17 00:00:00 2001 From: Taylor Swanson <90622908+taylor-swanson@users.noreply.github.com> Date: Wed, 1 Dec 2021 10:47:24 -0600 Subject: [PATCH 050/172] [Winlogbeat] Add configuration for registry file flush timeout (#29053) - Added a new option ("winlogbeat.registry_flush") for configuring the timeout for writing registry entries to disk. The previously hard-coded value of 5 seconds is now the default value. --- CHANGELOG.next.asciidoc | 1 + winlogbeat/_meta/config/header.yml.tmpl | 6 +++ winlogbeat/beater/winlogbeat.go | 2 +- winlogbeat/checkpoint/checkpoint.go | 18 ++----- winlogbeat/checkpoint/checkpoint_test.go | 54 +-------------------- winlogbeat/config/config.go | 4 +- winlogbeat/docs/winlogbeat-options.asciidoc | 17 +++++++ winlogbeat/winlogbeat.reference.yml | 6 +++ x-pack/winlogbeat/winlogbeat.reference.yml | 6 +++ 9 files changed, 44 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 43bb6e61e2f5..b8d54c4d7617 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -384,6 +384,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add more DNS error codes to the Sysmon module. {issue}15685[15685] - Add support for event language selection from config file {pull}19818[19818] +- Add configuration option for registry file flush timeout {issue}29001[29001] {pull}29053[29053] *Elastic Log Driver* diff --git a/winlogbeat/_meta/config/header.yml.tmpl b/winlogbeat/_meta/config/header.yml.tmpl index 7ace0063a189..ec53124d5f3e 100644 --- a/winlogbeat/_meta/config/header.yml.tmpl +++ b/winlogbeat/_meta/config/header.yml.tmpl @@ -15,6 +15,12 @@ # directory in which it was started. #winlogbeat.registry_file: .winlogbeat.yml +# The timeout value that controls when registry entries are written to disk +# (flushed). When an unwritten update exceeds this value, it triggers a write +# to disk. When flush is set to 0s, the registry is written to disk after each +# batch of events has been published successfully. The default value is 5s. +#winlogbeat.registry_flush: 5s + {{end -}} # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of diff --git a/winlogbeat/beater/winlogbeat.go b/winlogbeat/beater/winlogbeat.go index baa798bef767..568bb911539d 100644 --- a/winlogbeat/beater/winlogbeat.go +++ b/winlogbeat/beater/winlogbeat.go @@ -110,7 +110,7 @@ func (eb *Winlogbeat) setup(b *beat.Beat) error { config := &eb.config var err error - eb.checkpoint, err = checkpoint.NewCheckpoint(config.RegistryFile, 10, 5*time.Second) + eb.checkpoint, err = checkpoint.NewCheckpoint(config.RegistryFile, config.RegistryFlush) if err != nil { return err } diff --git a/winlogbeat/checkpoint/checkpoint.go b/winlogbeat/checkpoint/checkpoint.go index 2ce455c97e30..a93b29abed1f 100644 --- a/winlogbeat/checkpoint/checkpoint.go +++ b/winlogbeat/checkpoint/checkpoint.go @@ -42,7 +42,6 @@ type Checkpoint struct { file string // File where the state is persisted. fileLock sync.RWMutex // Lock that protects concurrent reads/writes to file. numUpdates int // Number of updates received since last persisting to disk. - maxUpdates int // Maximum number of updates to buffer before persisting to disk. flushInterval time.Duration // Maximum time interval that can pass before persisting to disk. sort []string // Slice used for sorting states map (store to save on mallocs). @@ -72,26 +71,18 @@ type EventLogState struct { // guarantee any in-memory state information is flushed to disk. // // file is the name of the file where event log state is persisted as YAML. -// maxUpdates is the maximum number of updates checkpoint will accept before -// triggering a flush to disk. interval is maximum amount of time that can -// pass since the last flush before triggering a flush to disk (minimum value -// is 1s). -func NewCheckpoint(file string, maxUpdates int, interval time.Duration) (*Checkpoint, error) { +// interval is maximum amount of time that can pass since the last flush +// before triggering a flush to disk (minimum value is 1s). +func NewCheckpoint(file string, interval time.Duration) (*Checkpoint, error) { c := &Checkpoint{ done: make(chan struct{}), file: file, - maxUpdates: maxUpdates, flushInterval: interval, sort: make([]string, 0, 10), states: make(map[string]EventLogState), save: make(chan EventLogState, 1), } - // Minimum batch size. - if c.maxUpdates < 1 { - c.maxUpdates = 1 - } - // Minimum flush interval. if c.flushInterval < time.Second { c.flushInterval = time.Second @@ -139,9 +130,6 @@ loop: c.states[s.Name] = s c.lock.Unlock() c.numUpdates++ - if c.numUpdates < c.maxUpdates { - continue - } case <-flushTimer.C: } diff --git a/winlogbeat/checkpoint/checkpoint_test.go b/winlogbeat/checkpoint/checkpoint_test.go index 0f515cf6881a..ef9e70cbeb19 100644 --- a/winlogbeat/checkpoint/checkpoint_test.go +++ b/winlogbeat/checkpoint/checkpoint_test.go @@ -56,58 +56,6 @@ func eventually(t *testing.T, predicate func() (bool, error), timeout time.Durat t.Fatal("predicate is not true after", timeout) } -// Test that a write is triggered when the maximum number of updates is reached. -func TestWriteMaxUpdates(t *testing.T) { - dir, err := ioutil.TempDir("", "wlb-checkpoint-test") - if err != nil { - t.Fatal(err) - } - defer func() { - err := os.RemoveAll(dir) - if err != nil { - t.Fatal(err) - } - }() - - file := filepath.Join(dir, "some", "new", "dir", ".winlogbeat.yml") - if !assert.False(t, fileExists(file), "%s should not exist", file) { - return - } - - cp, err := NewCheckpoint(file, 2, time.Hour) - if err != nil { - t.Fatal(err) - } - defer cp.Shutdown() - - // Send update - it's not written to disk but it's in memory. - cp.Persist("App", 1, time.Now(), "") - found := false - eventually(t, func() (bool, error) { - _, found = cp.States()["App"] - return found, nil - }, time.Second*15) - assert.True(t, found) - - ps, err := cp.read() - if err != nil { - t.Fatal("read failed", err) - } - assert.Len(t, ps.States, 0) - - // Send update - it is written to disk. - cp.Persist("App", 2, time.Now(), "") - eventually(t, func() (bool, error) { - ps, err = cp.read() - return ps != nil && len(ps.States) > 0, err - }, time.Second*15) - - if assert.Len(t, ps.States, 1, "state not written, could be a flush timing issue, retry") { - assert.Equal(t, "App", ps.States[0].Name) - assert.Equal(t, uint64(2), ps.States[0].RecordNumber) - } -} - // Test that a write is triggered when the maximum time period since the last // write is reached. func TestWriteTimedFlush(t *testing.T) { @@ -127,7 +75,7 @@ func TestWriteTimedFlush(t *testing.T) { return } - cp, err := NewCheckpoint(file, 100, time.Second) + cp, err := NewCheckpoint(file, time.Second) if err != nil { t.Fatal(err) } diff --git a/winlogbeat/config/config.go b/winlogbeat/config/config.go index 9700554eacf6..1b8eab40c0a1 100644 --- a/winlogbeat/config/config.go +++ b/winlogbeat/config/config.go @@ -34,7 +34,8 @@ const ( var ( DefaultSettings = WinlogbeatConfig{ - RegistryFile: DefaultRegistryFile, + RegistryFile: DefaultRegistryFile, + RegistryFlush: 5 * time.Second, } ) @@ -42,6 +43,7 @@ var ( type WinlogbeatConfig struct { EventLogs []*common.Config `config:"event_logs"` RegistryFile string `config:"registry_file"` + RegistryFlush time.Duration `config:"registry_flush"` ShutdownTimeout time.Duration `config:"shutdown_timeout"` } diff --git a/winlogbeat/docs/winlogbeat-options.asciidoc b/winlogbeat/docs/winlogbeat-options.asciidoc index a9c968e03858..dd2353eb7291 100644 --- a/winlogbeat/docs/winlogbeat-options.asciidoc +++ b/winlogbeat/docs/winlogbeat-options.asciidoc @@ -46,6 +46,23 @@ backslashes (\) for Windows compatibility. You can use either forward or backslashes. Forward slashes are easier to work with in YAML because there is no need to escape them. +[float] +==== `registry_flush` + +The timeout value that controls when registry entries are written to disk +(flushed). When an unwritten update exceeds this value, it triggers a write +to disk. When flush is set to 0s, the registry is written to disk after each +batch of events has been published successfully. + +The default value is 5s. + +Valid time units are `ns`, `us`, `ms`, `s`, `m`, `h`. + +[source,yaml] +-------------------------------------------------------------------------------- +winlogbeat.registry_flush: 5s +-------------------------------------------------------------------------------- + [float] ==== `shutdown_timeout` diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 4cca1af761e6..305d1b5acce5 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -14,6 +14,12 @@ # directory in which it was started. #winlogbeat.registry_file: .winlogbeat.yml +# The timeout value that controls when registry entries are written to disk +# (flushed). When an unwritten update exceeds this value, it triggers a write +# to disk. When flush is set to 0s, the registry is written to disk after each +# batch of events has been published successfully. The default value is 5s. +#winlogbeat.registry_flush: 5s + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 5d06be1566a1..d6e9d30c50da 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -14,6 +14,12 @@ # directory in which it was started. #winlogbeat.registry_file: .winlogbeat.yml +# The timeout value that controls when registry entries are written to disk +# (flushed). When an unwritten update exceeds this value, it triggers a write +# to disk. When flush is set to 0s, the registry is written to disk after each +# batch of events has been published successfully. The default value is 5s. +#winlogbeat.registry_flush: 5s + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. From 303e4ed7173347b720a84f315a8346523604b3ac Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Wed, 1 Dec 2021 23:46:42 +0100 Subject: [PATCH 051/172] PANW: Fix bugs in globalprotect pipeline (#29154) Fixes bugs in panw/panos GLOBALPROTECT log parsing: - source.ip and source.nat.ip can be overwritten by empty data. - Processor can fail due to missing null-checks. --- CHANGELOG.next.asciidoc | 1 + .../panw/panos/ingest/globalprotect.yml | 8 +- .../module/panw/panos/test/global_protect.log | 4 +- .../test/global_protect.log-expected.json | 174 +++++++++++++++++- 4 files changed, 179 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b8d54c4d7617..df75c94927f5 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -190,6 +190,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] - Fix `threatintel.misp` filters configuration. {issue}27970[27970] - Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] +- Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] *Heartbeat* diff --git a/x-pack/filebeat/module/panw/panos/ingest/globalprotect.yml b/x-pack/filebeat/module/panw/panos/ingest/globalprotect.yml index 66edbd302f2f..e1c760d27a49 100644 --- a/x-pack/filebeat/module/panw/panos/ingest/globalprotect.yml +++ b/x-pack/filebeat/module/panw/panos/ingest/globalprotect.yml @@ -4,11 +4,11 @@ processors: - set: field: source.ip value: "{{_temp_.private_ipv6}}" - if: ctx?._temp_?.private_ipv6 != "" && ctx?._temp_?.private_ipv6 != "0.0.0.0" + if: (ctx.source?.ip == null || ctx.source?.ip == "0.0.0.0") && ctx._temp_?.private_ipv6 != null && ctx._temp_?.private_ipv6 != "0.0.0.0" - set: field: source.nat.ip value: "{{_temp_.public_ipv6}}" - if: ctx?._temp_?.public_ipv6 != "" && ctx?._temp_?.public_ipv6 != "0.0.0.0" + if: (ctx.source?.nat?.ip == null || ctx.source?.nat?.ip == "0.0.0.0") && ctx._temp_?.public_ipv6 != null && ctx._temp_?.public_ipv6 != "0.0.0.0" - grok: field: _temp_.srcuser ignore_missing: true @@ -20,11 +20,11 @@ processors: - set: field: network.type value: 'ipv4' - if: 'ctx?.network?.type == null && ctx?.source?.ip.contains(".")' + if: 'ctx.network?.type == null && ctx.source?.ip != null && ctx.source.ip.contains(".")' - set: field: network.type value: 'ipv6' - if: 'ctx?.network?.type == null && ctx?.source?.ip.contains(":")' + if: 'ctx.network?.type == null && ctx.source?.ip != null && ctx.source.ip.contains(":")' on_failure: - append: diff --git a/x-pack/filebeat/module/panw/panos/test/global_protect.log b/x-pack/filebeat/module/panw/panos/test/global_protect.log index 08918ad4946b..23b982e2a09a 100644 --- a/x-pack/filebeat/module/panw/panos/test/global_protect.log +++ b/x-pack/filebeat/module/panw/panos/test/global_protect.log @@ -3,8 +3,10 @@ 1,2021/04/07 17:41:30,013101305,GLOBALPROTECT,0,2305,2021/04/07 17:41:30,vsys1,gateway-hip-check,host-info,,,domain\user1,,HOST82878,7.2.2.193,0.0.0.0,67.43.156.14,0.0.0.0,523e8b-7efa-4397-a4d5-824dfa4d8a,F1SM2,5.2.4,,"",1,,,"HIP report is not needed",success,,0,,0,GlobalProtect_GW,6920071768563516860,0x0 1,2021/04/07 17:41:29,013101308,GLOBALPROTECT,0,2305,2021/04/07 17:41:29,vsys1,gateway-getconfig,configuration,,IPSec,pre-logon,BE,HOST73486,7.2.2.171,0.0.0.0,81.2.69.193,0.0.0.0,7d01b5-f538-4fa3-a2a2-83980d1325,5C261FNR,5.2.4,Windows,"Microsoft Windows 10 Pro , 64-bit",1,,,"Config name: , Client region: BE.",success,,0,,0,GlobalProtect_GW,6944137135219737,0x0 1,2021/04/07 17:41:28,0131001309,GLOBALPROTECT,0,2305,2021/04/07 17:41:28,vsys1,gateway-tunnel-latency,tunnel,,,,userlterso,HOSTP92413,7.2.17.120,0.0.0.0,0.0.0.0,0.0.0.0,2ba9f01-b83b-4902-a1fb-1748c0365,GJG98Y2,5.2.4,,"",1,,,"Pre-tunnel latency: 67ms, Post-tunnel latency: 47ms",success,,0,,0,GlobalProtect_GW,6920071768563516847,0x0 - 1,2021/03/02 09:55:42,12345678999,GLOBALPROTECT,0,2305,2021/03/02 09:55:39,vsys1,gateway-auth,login,Other,,maxmustermann,10.0.0.0-10.255.255.255,PC1234,10.20.30.40,0.0.0.0,0.0.0.0,0.0.0.0,985e865f-7da3-43b4-89a9-299b1bb0c975,SERIALNR,5.1.1,Windows,"Microsoft Windows 10 Enterprise, 64-bit",1,,,,success,,0,pre-logon,0,GP GW intern,6894571632887748064,0x8000000000000000,1970-01-01T01:00:00.000+01:00,,0,manual only,, 1,2021/03/02 11:01:03,123456789999,GLOBALPROTECT,0,2305,2021/03/02 11:01:02,vsys1,gateway-setup-ipsec,tunnel,,IPSec,domain\musterman,DE,Rechner67.43.156.12.123,0.0.0.0,10.20.30.40,0.0.0.0,96c43d47-8bb5-4f78-8dfc-413a189a29e0,SERIALNR,5.1.1,Windows,"Microsoft Windows 10 Enterprise, 64-bit",1,,,,success,,0,,0,GPGateway,6894571632887761989,0x8000000000000000,1970-01-01T01:00:00.000+01:00,,0,manual only,, 1,2021/03/02 09:39:33,12345678999,GLOBALPROTECT,0,2305,2021/03/02 09:39:26,vsys1,portal-prelogin,before-login,,,Max.Mustermann@domain.de,10.0.0.0-10.255.255.255,,10.20.30.40,0.0.0.0,0.0.0.0,0.0.0.0,0183d851-7ea2-4a0d-80de-fde1e04ce12f,,5.1.1,Windows,"Microsoft Windows 10 Enterprise, 64-bit",1,,,,success,,0,,0,GP Portal,6894571632887745099,0x8000000000000000,1970-01-01T01:00:00.000+01:00,,0,manual only,, 1,2021/03/02 09:47:18,12345678999,GLOBALPROTECT,0,2305,2021/03/02 09:47:13,vsys1,portal-getconfig,configuration,,,domain\maxmustermann,10.0.0.0-10.255.255.255,PC12345,10.20.30.40,0.0.0.0,0.0.0.0,0.0.0.0,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIENNR,5.1.1,Windows,"Microsoft Windows 10 Enterprise, 64-bit",1,,,"Config name: GP Clients, Machine Certificate CN : (null)",success,,0,pre-logon,0,GP Portal,6894571632887746544,0x8000000000000000,1970-01-01T01:00:00.000+01:00,,0,manual only,, +931201168,2021-10-22T16:10:10.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-10-22T16:10:05.000000Z,vsys1,gateway-hip-check,host-info,,,host\\user,,HOSTNAME,10.1.1.1,,10.2.2.2,fc00::1,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.6,,,1,,,HIP report is not needed,success,,0,,0,GlobalProtect_External_Gateway,1305925,true +931201168,2021-11-09T21:45:36.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-11-09T21:45:14.000000Z,vsys1,gateway-tunnel-latency,tunnel,,,user,,HOSTNAME,10.3.3.3,,10.4.4.4,,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.8,,,1,,,"Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms",success,,0,,0,GlobalProtect_External_Gateway,1041590,true +931201168,2021-11-09T21:45:36.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-11-09T21:45:14.000000Z,vsys1,gateway-tunnel-latency,tunnel,,,user,,HOSTNAME,,fc00::1234,,fc00::abcd,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.8,,,1,,,"Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms",success,,0,,0,GlobalProtect_External_Gateway,1041590,true diff --git a/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json b/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json index ac3648ccc191..cf432b8604bc 100644 --- a/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json +++ b/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json @@ -322,7 +322,7 @@ "host.os.family": "Windows", "host.os.full": "Microsoft Windows 10 Enterprise, 64-bit", "input.type": "log", - "log.offset": 1645, + "log.offset": 1644, "network.type": "ipv4", "observer.hostname": "GP GW intern", "observer.product": "PAN-OS", @@ -385,7 +385,7 @@ "host.os.family": "Windows", "host.os.full": "Microsoft Windows 10 Enterprise, 64-bit", "input.type": "log", - "log.offset": 2467, + "log.offset": 2466, "network.type": "ipv4", "observer.hostname": "GP Portal", "observer.product": "PAN-OS", @@ -447,7 +447,7 @@ "host.os.family": "Windows", "host.os.full": "Microsoft Windows 10 Enterprise, 64-bit", "input.type": "log", - "log.offset": 2874, + "log.offset": 2873, "network.type": "ipv4", "observer.hostname": "GP Portal", "observer.product": "PAN-OS", @@ -493,5 +493,173 @@ ], "user.domain": "domain", "user.name": "maxmustermann" + }, + { + "@timestamp": "2021-10-22T16:10:05.000Z", + "client.address": "10.2.2.2", + "client.ip": "10.2.2.2", + "client.nat.ip": "10.1.1.1", + "event.code": "gateway-hip-check", + "event.dataset": "panw.panos", + "event.duration": 0, + "event.module": "panw", + "event.original": "931201168,2021-10-22T16:10:10.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-10-22T16:10:05.000000Z,vsys1,gateway-hip-check,host-info,,,host\\\\user,,HOSTNAME,10.1.1.1,,10.2.2.2,fc00::1,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.6,,,1,,,HIP report is not needed,success,,0,,0,GlobalProtect_External_Gateway,1305925,true", + "event.outcome": "success", + "event.timezone": "-02:00", + "fileset.name": "panos", + "host.id": "8cbc136b-e262-4cf8-912c-95ea132d9fef", + "host.ip": "10.2.2.2", + "host.name": "HOSTNAME", + "input.type": "log", + "log.offset": 3360, + "network.type": "ipv4", + "observer.hostname": "GlobalProtect_External_Gateway", + "observer.product": "PAN-OS", + "observer.serial_number": "no-serial", + "observer.type": "firewall", + "observer.vendor": "Palo Alto Networks", + "panw.panos.actionflags": "true", + "panw.panos.client_ver": "5.2.6", + "panw.panos.description": "HIP report is not needed", + "panw.panos.error_code": "0", + "panw.panos.repeatcnt": 1, + "panw.panos.sequence_number": 1305925, + "panw.panos.serial_number": "SERIALNR", + "panw.panos.source.nat.ip": "10.1.1.1", + "panw.panos.stage": "host-info", + "panw.panos.sub_type": "globalprotect", + "panw.panos.type": "GLOBALPROTECT", + "panw.panos.virtual_sys": "vsys1", + "related.hosts": [ + "GlobalProtect_External_Gateway", + "HOSTNAME" + ], + "related.ip": [ + "10.1.1.1", + "10.2.2.2" + ], + "related.user": [ + "host" + ], + "service.type": "panw", + "source.address": "10.2.2.2", + "source.ip": "10.2.2.2", + "source.nat.ip": "10.1.1.1", + "source.user.name": "host", + "tags": [ + "forwarded", + "pan-os" + ], + "user.name": "host" + }, + { + "@timestamp": "2021-11-09T21:45:14.000Z", + "client.address": "10.4.4.4", + "client.ip": "10.4.4.4", + "client.nat.ip": "10.3.3.3", + "event.code": "gateway-tunnel-latency", + "event.dataset": "panw.panos", + "event.duration": 0, + "event.module": "panw", + "event.original": "931201168,2021-11-09T21:45:36.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-11-09T21:45:14.000000Z,vsys1,gateway-tunnel-latency,tunnel,,,user,,HOSTNAME,10.3.3.3,,10.4.4.4,,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.8,,,1,,,\"Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms\",success,,0,,0,GlobalProtect_External_Gateway,1041590,true", + "event.outcome": "success", + "event.timezone": "-02:00", + "fileset.name": "panos", + "host.id": "8cbc136b-e262-4cf8-912c-95ea132d9fef", + "host.ip": "10.4.4.4", + "host.name": "HOSTNAME", + "input.type": "log", + "log.offset": 3693, + "network.type": "ipv4", + "observer.hostname": "GlobalProtect_External_Gateway", + "observer.product": "PAN-OS", + "observer.serial_number": "no-serial", + "observer.type": "firewall", + "observer.vendor": "Palo Alto Networks", + "panw.panos.actionflags": "true", + "panw.panos.client_ver": "5.2.8", + "panw.panos.description": "Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms", + "panw.panos.error_code": "0", + "panw.panos.repeatcnt": 1, + "panw.panos.sequence_number": 1041590, + "panw.panos.serial_number": "SERIALNR", + "panw.panos.source.nat.ip": "10.3.3.3", + "panw.panos.stage": "tunnel", + "panw.panos.sub_type": "globalprotect", + "panw.panos.type": "GLOBALPROTECT", + "panw.panos.virtual_sys": "vsys1", + "related.hosts": [ + "GlobalProtect_External_Gateway", + "HOSTNAME" + ], + "related.ip": [ + "10.3.3.3", + "10.4.4.4" + ], + "related.user": [ + "user" + ], + "service.type": "panw", + "source.address": "10.4.4.4", + "source.ip": "10.4.4.4", + "source.nat.ip": "10.3.3.3", + "source.user.name": "user", + "tags": [ + "forwarded", + "pan-os" + ], + "user.name": "user" + }, + { + "@timestamp": "2021-11-09T21:45:14.000Z", + "event.code": "gateway-tunnel-latency", + "event.dataset": "panw.panos", + "event.duration": 0, + "event.module": "panw", + "event.original": "931201168,2021-11-09T21:45:36.000000Z,no-serial,GLOBALPROTECT,globalprotect,9.1,2021-11-09T21:45:14.000000Z,vsys1,gateway-tunnel-latency,tunnel,,,user,,HOSTNAME,,fc00::1234,,fc00::abcd,8cbc136b-e262-4cf8-912c-95ea132d9fef,SERIALNR,5.2.8,,,1,,,\"Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms\",success,,0,,0,GlobalProtect_External_Gateway,1041590,true", + "event.outcome": "success", + "event.timezone": "-02:00", + "fileset.name": "panos", + "host.id": "8cbc136b-e262-4cf8-912c-95ea132d9fef", + "host.name": "HOSTNAME", + "input.type": "log", + "log.offset": 4044, + "network.type": "ipv6", + "observer.hostname": "GlobalProtect_External_Gateway", + "observer.product": "PAN-OS", + "observer.serial_number": "no-serial", + "observer.type": "firewall", + "observer.vendor": "Palo Alto Networks", + "panw.panos.actionflags": "true", + "panw.panos.client_ver": "5.2.8", + "panw.panos.description": "Pre-tunnel latency: 35ms, Post-tunnel latency: 16ms", + "panw.panos.error_code": "0", + "panw.panos.repeatcnt": 1, + "panw.panos.sequence_number": 1041590, + "panw.panos.serial_number": "SERIALNR", + "panw.panos.stage": "tunnel", + "panw.panos.sub_type": "globalprotect", + "panw.panos.type": "GLOBALPROTECT", + "panw.panos.virtual_sys": "vsys1", + "related.hosts": [ + "GlobalProtect_External_Gateway", + "HOSTNAME" + ], + "related.ip": [ + "fc00::1234", + "fc00::abcd" + ], + "related.user": [ + "user" + ], + "service.type": "panw", + "source.ip": "fc00::abcd", + "source.nat.ip": "fc00::1234", + "source.user.name": "user", + "tags": [ + "forwarded", + "pan-os" + ], + "user.name": "user" } ] \ No newline at end of file From fab2197c8996fc8f8ac9e939ed34b89c4acd3f28 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Thu, 2 Dec 2021 08:15:40 +0100 Subject: [PATCH 052/172] Auditbeat: Fix processes misattribution in system/socket dataset (#29166) - Track forked processes - Make accept() create a new socket - Improve flow tracking - Set client/server depending on port number when direction is unknown - Use kernel's monotonic clock explicitly --- CHANGELOG.next.asciidoc | 1 + .../auditbeat/module/system/socket/events.go | 30 ++++++- .../auditbeat/module/system/socket/kprobes.go | 9 ++ .../auditbeat/module/system/socket/state.go | 82 +++++++++++++++---- .../module/system/socket/state_test.go | 8 +- .../module/system/socket/template.go | 1 + x-pack/auditbeat/tracing/perfevent.go | 3 +- 7 files changed, 110 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index df75c94927f5..b8f52aba7fec 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -150,6 +150,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - system module: Fix panic during initialisation when /proc/stat can't be read. {pull}17569[17569] - system/package: Fix an error that can occur while trying to persist package metadata. {issue}18536[18536] {pull}18887[18887] - Fix handling of root and relative paths {issue}24430[24430] {pull}28354[28354] +- system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] *Filebeat* diff --git a/x-pack/auditbeat/module/system/socket/events.go b/x-pack/auditbeat/module/system/socket/events.go index 157d5ec92d04..d0c37701d541 100644 --- a/x-pack/auditbeat/module/system/socket/events.go +++ b/x-pack/auditbeat/module/system/socket/events.go @@ -189,6 +189,7 @@ type tcpAcceptResult struct { } func (e *tcpAcceptResult) asFlow() flow { + evTime := kernelTime(e.Meta.Timestamp) f := flow{ sock: e.Sock, pid: e.Meta.PID, @@ -196,7 +197,8 @@ func (e *tcpAcceptResult) asFlow() flow { proto: protoTCP, dir: directionIngress, complete: true, - lastSeen: kernelTime(e.Meta.Timestamp), + lastSeen: evTime, + created: evTime, } if e.Af == unix.AF_INET { f.local = newEndpointIPv4(e.LAddr, e.LPort, 0, 0) @@ -217,7 +219,7 @@ func (e *tcpAcceptResult) String() string { // Update the state with the contents of this event. func (e *tcpAcceptResult) Update(s *state) error { if e.Sock != 0 { - return s.UpdateFlow(e.asFlow()) + return s.CreateSocket(e.asFlow()) } return nil } @@ -233,6 +235,7 @@ type tcpAcceptResult4 struct { } func (e *tcpAcceptResult4) asFlow() flow { + evTime := kernelTime(e.Meta.Timestamp) f := flow{ sock: e.Sock, pid: e.Meta.PID, @@ -240,7 +243,8 @@ func (e *tcpAcceptResult4) asFlow() flow { proto: protoTCP, dir: directionIngress, complete: true, - lastSeen: kernelTime(e.Meta.Timestamp), + lastSeen: evTime, + created: evTime, } f.local = newEndpointIPv4(e.LAddr, e.LPort, 0, 0) f.remote = newEndpointIPv4(e.RAddr, e.RPort, 0, 0) @@ -256,7 +260,7 @@ func (e *tcpAcceptResult4) String() string { // Update the state with the contents of this event. func (e *tcpAcceptResult4) Update(s *state) error { if e.Sock != 0 { - return s.UpdateFlow(e.asFlow()) + return s.CreateSocket(e.asFlow()) } return nil } @@ -948,6 +952,24 @@ func (e *execveRet) Update(s *state) error { return nil } +type forkRet struct { + Meta tracing.Metadata `kprobe:"metadata"` + Retval int `kprobe:"retval"` +} + +// String returns a representation of the event. +func (e *forkRet) String() string { + return fmt.Sprintf("%s <- fork %d", header(e.Meta), e.Retval) +} + +// Update the state with the contents of this event. +func (e *forkRet) Update(s *state) error { + if e.Retval <= 0 { + return nil + } + return s.ForkProcess(e.Meta.PID, uint32(e.Retval), kernelTime(e.Meta.Timestamp)) +} + type doExit struct { Meta tracing.Metadata `kprobe:"metadata"` } diff --git a/x-pack/auditbeat/module/system/socket/kprobes.go b/x-pack/auditbeat/module/system/socket/kprobes.go index e5f5695177ab..67d86d6237d6 100644 --- a/x-pack/auditbeat/module/system/socket/kprobes.go +++ b/x-pack/auditbeat/module/system/socket/kprobes.go @@ -186,6 +186,15 @@ var sharedKProbes = []helper.ProbeDef{ Decoder: helper.NewStructDecoder(func() interface{} { return new(commitCreds) }), }, + { + Probe: tracing.Probe{ + Type: tracing.TypeKRetProbe, + Name: "clone3_ret", + Address: "{{.DO_FORK}}", + Fetchargs: "retval={{.RET}}", + }, + Decoder: helper.NewStructDecoder(func() interface{} { return new(forkRet) }), + }, /*************************************************************************** * IPv4 **************************************************************************/ diff --git a/x-pack/auditbeat/module/system/socket/state.go b/x-pack/auditbeat/module/system/socket/state.go index dc17108b52ea..0ec22da3cb8c 100644 --- a/x-pack/auditbeat/module/system/socket/state.go +++ b/x-pack/auditbeat/module/system/socket/state.go @@ -563,6 +563,38 @@ func (s *state) CreateProcess(p *process) error { return nil } +func (s *state) ForkProcess(parentPID, childPID uint32, ts kernelTime) error { + if parentPID == childPID { + return nil + } + s.Lock() + defer s.Unlock() + if _, found := s.processes[childPID]; found { + return errors.New("fork: child pid already registered to another process") + } + if parent, found := s.processes[parentPID]; found { + child := &process{ + pid: childPID, + name: parent.name, + path: parent.path, + args: parent.args, + created: ts, + uid: parent.uid, + gid: parent.gid, + euid: parent.euid, + egid: parent.egid, + hasCreds: parent.hasCreds, + createdTime: s.kernTimestampToTime(ts), + } + child.resolvedDomains = make(map[string]string, len(parent.resolvedDomains)) + for k, v := range parent.resolvedDomains { + child.resolvedDomains[k] = v + } + s.processes[childPID] = child + } + return nil +} + func (s *state) TerminateProcess(pid uint32) error { if pid == 0 { return errors.New("can't terminate process with PID 0") @@ -631,8 +663,16 @@ func (s *state) CreateSocket(ref flow) error { defer s.Unlock() ref.createdTime = s.kernTimestampToTime(ref.created) ref.lastSeenTime = s.kernTimestampToTime(ref.lastSeen) - // terminate existing if sock ptr is reused if prev, found := s.socks[ref.sock]; found { + // Fetch existing flow in case of TCP negotiation + if initial, found := prev.flows[ref.remote.String()]; found && ref.local.String() == initial.local.String() { + initial.dir = ref.dir + initial.pid = ref.pid + initial.process = ref.process + ref.updateWith(*initial, s) + delete(prev.flows, ref.remote.String()) + } + // terminate existing if sock ptr is reused s.onSockTerminated(prev) } return s.createFlow(ref) @@ -662,22 +702,21 @@ func (s *state) mutualEnrich(sock *socket, f *flow) { f.dir = sock.dir } } - if sockNoPID := sock.pid == 0; sockNoPID != (f.pid == 0) { - if sockNoPID { - sock.pid = f.pid - } else { - f.pid = sock.pid - } + if sock.pid == 0 { + sock.pid = f.pid + sock.process = f.process } - if sockNoProcess := sock.process == nil; sockNoProcess != (f.process == nil) { - if sockNoProcess { - sock.process = f.process - } else { + if sock.pid == f.pid && sock.pid != 0 { + if sockNoProcess := sock.process == nil; sockNoProcess != (f.process == nil) { + if sockNoProcess { + sock.process = f.process + } else { + f.process = sock.process + } + } else if sock.process == nil && sock.pid != 0 { + sock.process = s.getProcess(sock.pid) f.process = sock.process } - } else if sock.process == nil && sock.pid != 0 { - sock.process = s.getProcess(sock.pid) - f.process = sock.process } if !sock.closing { sock.lastSeenTime = s.clock() @@ -764,6 +803,11 @@ func (s *state) UpdateFlowWithCondition(ref flow, cond func(*flow) bool) error { } prev, found := sock.flows[ref.remote.addr.String()] if !found { + // Sock has been already closed and it may be receiving a SYN for a different + // flow. + if sock.closing { + return nil + } return s.createFlow(ref) } if cond != nil && !cond(prev) { @@ -901,8 +945,16 @@ func (f *flow) toEvent(final bool) (ev mb.Event, err error) { } src, dst := local, remote - if f.dir == directionIngress { + switch f.dir { + case directionIngress: src, dst = dst, src + case directionUnknown: + // For some flows we can miss information to determine the source (dir=unknown). + // As a last resort, assume that the client side uses a higher port number + // than the server. + if localAddr.Port < remoteAddr.Port { + src, dst = dst, src + } } inetType := f.inetType diff --git a/x-pack/auditbeat/module/system/socket/state_test.go b/x-pack/auditbeat/module/system/socket/state_test.go index dc059f4a43d0..79f7838840eb 100644 --- a/x-pack/auditbeat/module/system/socket/state_test.go +++ b/x-pack/auditbeat/module/system/socket/state_test.go @@ -29,19 +29,19 @@ import ( type logWrapper testing.T func (l *logWrapper) Errorf(format string, args ...interface{}) { - l.Logf("error: "+format, args) + l.Logf("error: "+format, args...) } func (l *logWrapper) Warnf(format string, args ...interface{}) { - l.Logf("warning: "+format, args) + l.Logf("warning: "+format, args...) } func (l *logWrapper) Infof(format string, args ...interface{}) { - l.Logf("info: "+format, args) + l.Logf("info: "+format, args...) } func (l *logWrapper) Debugf(format string, args ...interface{}) { - l.Logf("debug: "+format, args) + l.Logf("debug: "+format, args...) } func TestTCPConnWithProcess(t *testing.T) { diff --git a/x-pack/auditbeat/module/system/socket/template.go b/x-pack/auditbeat/module/system/socket/template.go index c5f2b5555de0..7b90a2a4daaa 100644 --- a/x-pack/auditbeat/module/system/socket/template.go +++ b/x-pack/auditbeat/module/system/socket/template.go @@ -41,6 +41,7 @@ var functionAlternatives = map[string][]string{ "SYS_EXECVE": syscallAlternatives("execve"), "SYS_GETTIMEOFDAY": syscallAlternatives("gettimeofday"), "SYS_UNAME": syscallAlternatives("newuname"), + "DO_FORK": {"_do_fork", "do_fork"}, } func syscallAlternatives(syscall string) []string { diff --git a/x-pack/auditbeat/tracing/perfevent.go b/x-pack/auditbeat/tracing/perfevent.go index 181bc4801417..79112a1c8859 100644 --- a/x-pack/auditbeat/tracing/perfevent.go +++ b/x-pack/auditbeat/tracing/perfevent.go @@ -99,7 +99,8 @@ func NewPerfChannel(cfg ...PerfChannelConf) (channel *PerfChannel, err error) { streams: make(map[uint64]stream), pid: perf.AllThreads, attr: perf.Attr{ - Type: perf.TracepointEvent, + Type: perf.TracepointEvent, + ClockID: unix.CLOCK_MONOTONIC, SampleFormat: perf.SampleFormat{ Raw: true, StreamID: true, From 008182af34d2148034c226dfa238f04ef81d124e Mon Sep 17 00:00:00 2001 From: Kush Rana <89848966+kush-elastic@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:21:00 +0530 Subject: [PATCH 053/172] [Filebeat][httpjson] httpjson oauth2 authentication mechanism for salesforce events (#29087) * Add grant-type: passoword in httpjson oauth2 * refactor code and add new properties tests in config_test.go * Add grant_type: password in oAuth2ProviderDefault * Update CHANGELOG.next.asciidoc * update input-httpjson.asciidoc with new extended httpjson authentication method * add comment for authstyleparam variable * update user dummy value in the doc * Update input-httpjson.asciidoc - provider should be default only for user-passowrd method * refactor code and add new properties tests in config_test.go * Add grant_type: password in oAuth2ProviderDefault Co-authored-by: Sunny Chaudhari --- CHANGELOG.next.asciidoc | 1 + .../docs/inputs/input-httpjson.asciidoc | 29 ++++++++++++ x-pack/filebeat/input/httpjson/config_auth.go | 47 +++++++++++++++---- x-pack/filebeat/input/httpjson/config_test.go | 42 +++++++++++++++++ 4 files changed, 111 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b8f52aba7fec..733f5f366043 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -350,6 +350,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support in aws-s3 input for custom script parsing of s3 notifications. {pull}28946[28946] - Improve error handling in aws-s3 input for malformed s3 notifications. {issue}28828[28828] {pull}28946[28946] - Add support for parsers on journald input {pull}29070[29070] +- Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] *Heartbeat* diff --git a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc index 027ef66e3e70..cbde7b8b831e 100644 --- a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc @@ -85,6 +85,19 @@ filebeat.inputs: request.url: http://localhost ---- +["source","yaml",subs="attributes"] +---- +filebeat.inputs: +- type: httpjson + auth.oauth2: + client.id: 12345678901234567890abcdef + client.secret: abcdef12345678901234567890 + token_url: http://localhost/oauth2/token + user: user@domain.tld + password: P@$$W0₹D + request.url: http://localhost +---- + [[input-state]] ==== Input state @@ -265,6 +278,22 @@ except if using `google` as provider. Required for providers: `default`, `azure` The client secret used as part of the authentication flow. It is always required except if using `google` as provider. Required for providers: `default`, `azure`. +[float] +==== `auth.oauth2.user` + +The user used as part of the authentication flow. It is required for authentication + - grant type password. It is only available for provider `default`. + +[float] +==== `auth.oauth2.password` + +The password used as part of the authentication flow. It is required for authentication + - grant type password. It is only available for provider `default`. + +NOTE: user and password are required for grant_type password. If user and +password is not used then it will automatically use the `token_url` and +`client credential` method. + [float] ==== `auth.oauth2.scopes` diff --git a/x-pack/filebeat/input/httpjson/config_auth.go b/x-pack/filebeat/input/httpjson/config_auth.go index 88eac44edc10..7e8dae6dc0a8 100644 --- a/x-pack/filebeat/input/httpjson/config_auth.go +++ b/x-pack/filebeat/input/httpjson/config_auth.go @@ -22,6 +22,9 @@ import ( "github.com/elastic/beats/v7/libbeat/common" ) +// authStyleInParams sends the "client_id" and "client_secret" in the POST body as application/x-www-form-urlencoded parameters. +const authStyleInParams = 1 + type authConfig struct { Basic *basicAuthConfig `config:"basic"` OAuth2 *oAuth2Config `config:"oauth2"` @@ -83,9 +86,11 @@ type oAuth2Config struct { ClientID string `config:"client.id"` ClientSecret string `config:"client.secret"` EndpointParams map[string][]string `config:"endpoint_params"` + Password string `config:"password"` Provider oAuth2Provider `config:"provider"` Scopes []string `config:"scopes"` TokenURL string `config:"token_url"` + User string `config:"user"` // google specific GoogleCredentialsFile string `config:"google.credentials_file"` @@ -103,20 +108,43 @@ func (o *oAuth2Config) isEnabled() bool { return o != nil && (o.Enabled == nil || *o.Enabled) } +// clientCredentialsGrant creates http client from token_url and client credentials +func (o *oAuth2Config) clientCredentialsGrant(ctx context.Context, client *http.Client) *http.Client { + creds := clientcredentials.Config{ + ClientID: o.ClientID, + ClientSecret: o.ClientSecret, + TokenURL: o.getTokenURL(), + Scopes: o.Scopes, + EndpointParams: o.getEndpointParams(), + } + return creds.Client(ctx) +} + // Client wraps the given http.Client and returns a new one that will use the oauth authentication. func (o *oAuth2Config) client(ctx context.Context, client *http.Client) (*http.Client, error) { ctx = context.WithValue(ctx, oauth2.HTTPClient, client) switch o.getProvider() { - case oAuth2ProviderAzure, oAuth2ProviderDefault: - creds := clientcredentials.Config{ - ClientID: o.ClientID, - ClientSecret: o.ClientSecret, - TokenURL: o.getTokenURL(), - Scopes: o.Scopes, - EndpointParams: o.getEndpointParams(), + case oAuth2ProviderDefault: + if o.User != "" || o.Password != "" { + conf := &oauth2.Config{ + ClientID: o.ClientID, + ClientSecret: o.ClientSecret, + Endpoint: oauth2.Endpoint{ + TokenURL: o.TokenURL, + AuthStyle: authStyleInParams, + }, + } + token, err := conf.PasswordCredentialsToken(ctx, o.User, o.Password) + if err != nil { + return nil, fmt.Errorf("oauth2 client: error loading credentials using user and password: %w", err) + } + return conf.Client(ctx, token), nil + } else { + return o.clientCredentialsGrant(ctx, client), nil } - return creds.Client(ctx), nil + case oAuth2ProviderAzure: + return o.clientCredentialsGrant(ctx, client), nil case oAuth2ProviderGoogle: if o.GoogleJWTFile != "" { cfg, err := google.JWTConfigFromJSON(o.GoogleCredentialsJSON, o.Scopes...) @@ -184,6 +212,9 @@ func (o *oAuth2Config) Validate() error { if o.TokenURL == "" || o.ClientID == "" || o.ClientSecret == "" { return errors.New("both token_url and client credentials must be provided") } + if (o.User != "" && o.Password == "") || (o.User == "" && o.Password != "") { + return errors.New("both user and password credentials must be provided") + } default: return fmt.Errorf("unknown provider %q", o.getProvider()) } diff --git a/x-pack/filebeat/input/httpjson/config_test.go b/x-pack/filebeat/input/httpjson/config_test.go index 67662b407528..71ee7edb2465 100644 --- a/x-pack/filebeat/input/httpjson/config_test.go +++ b/x-pack/filebeat/input/httpjson/config_test.go @@ -152,6 +152,48 @@ func TestConfigOauth2Validation(t *testing.T) { "auth.oauth2": map[string]interface{}{}, }, }, + { + name: "if user and password is set oauth2 must use user-password authentication", + input: map[string]interface{}{ + "auth.oauth2": map[string]interface{}{ + "user": "a_client_user", + "password": "a_client_password", + "token_url": "localhost", + "client": map[string]interface{}{ + "id": "a_client_id", + "secret": "a_client_secret", + }, + }, + }, + }, + { + name: "if user is set password credentials must be set for user-password authentication", + expectedErr: "both user and password credentials must be provided accessing 'auth.oauth2'", + input: map[string]interface{}{ + "auth.oauth2": map[string]interface{}{ + "user": "a_client_user", + "token_url": "localhost", + "client": map[string]interface{}{ + "id": "a_client_id", + "secret": "a_client_secret", + }, + }, + }, + }, + { + name: "if password is set user credentials must be set for user-password authentication", + expectedErr: "both user and password credentials must be provided accessing 'auth.oauth2'", + input: map[string]interface{}{ + "auth.oauth2": map[string]interface{}{ + "password": "a_client_password", + "token_url": "localhost", + "client": map[string]interface{}{ + "id": "a_client_id", + "secret": "a_client_secret", + }, + }, + }, + }, { name: "must fail with an unknown provider", expectedErr: "unknown provider \"unknown\" accessing 'auth.oauth2'", From 8896fd319a257f3e0783119a7dd8d0978ef62197 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Thu, 2 Dec 2021 21:09:46 +0100 Subject: [PATCH 054/172] Fix Python environment activation (#29252) --- Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 40b081bf3edc..179d54f78550 100644 --- a/Makefile +++ b/Makefile @@ -128,8 +128,9 @@ check-no-changes: ## check-python : Python Linting. .PHONY: check-python check-python: python-env - @$(FIND) -name *.py -name *.py -not -path "*/build/*" -exec $(PYTHON_ENV)/bin/autopep8 -d --max-line-length 120 {} \; | (! grep . -q) || (echo "Code differs from autopep8's style" && false) - @$(FIND) -name *.py -not -path "*/build/*" | xargs $(PYTHON_ENV)/bin/pylint --py3k -E || (echo "Code is not compatible with Python 3" && false) + @. $(PYTHON_ENV)/bin/activate; \ + $(FIND) -name *.py -name *.py -not -path "*/build/*" -exec $(PYTHON_ENV)/bin/autopep8 -d --max-line-length 120 {} \; | (! grep . -q) || (echo "Code differs from autopep8's style" && false); \ + $(FIND) -name *.py -not -path "*/build/*" | xargs $(PYTHON_ENV)/bin/pylint --py3k -E || (echo "Code is not compatible with Python 3" && false) ## check-headers : Check the license headers. .PHONY: check-headers @@ -184,9 +185,10 @@ notice: .PHONY: python-env python-env: @test -d $(PYTHON_ENV) || ${PYTHON_EXE} -m venv $(VENV_PARAMS) $(PYTHON_ENV) - @$(PYTHON_ENV)/bin/pip install -q --upgrade pip autopep8==1.5.4 pylint==2.4.4 + @. $(PYTHON_ENV)/bin/activate; \ + ${PYTHON_EXE} -m pip install -q --upgrade pip autopep8==1.5.4 pylint==2.4.4; \ + find $(PYTHON_ENV) -type d -name dist-packages -exec sh -c "echo dist-packages > {}.pth" ';' @# Work around pip bug. See: https://github.com/pypa/pip/issues/4464 - @find $(PYTHON_ENV) -type d -name dist-packages -exec sh -c "echo dist-packages > {}.pth" ';' ## test-apm : Tests if apm works with the current code .PHONY: test-apm From c3d31a4f15eba857ee8076c5fbae5f7ba471f2bd Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Mon, 6 Dec 2021 19:41:25 +1030 Subject: [PATCH 055/172] libbeat,packetbeat,x-pack/filebeat/input/netflow: unify gopacket dependencies (#29167) --- CHANGELOG.next.asciidoc | 1 + NOTICE.txt | 44 +------------- go.mod | 5 +- go.sum | 7 +-- libbeat/common/flowhash/communityid_test.go | 11 ++-- .../common/seccomp/seccomp-profiler-allow.txt | 2 +- packetbeat/beater/worker.go | 2 +- packetbeat/decoder/decoder.go | 11 +++- packetbeat/decoder/decoder_test.go | 4 +- packetbeat/decoder/util.go | 2 +- packetbeat/protos/icmp/icmp.go | 4 +- packetbeat/protos/icmp/icmp_test.go | 6 +- packetbeat/protos/icmp/message.go | 2 +- packetbeat/protos/icmp/message_test.go | 4 +- packetbeat/protos/icmp/transaction_test.go | 2 +- packetbeat/protos/tcp/tcp.go | 4 +- packetbeat/protos/tcp/tcp_test.go | 3 +- packetbeat/sniffer/afpacket_linux.go | 29 +++++++-- packetbeat/sniffer/afpacket_nonlinux.go | 4 +- packetbeat/sniffer/device.go | 2 +- packetbeat/sniffer/device_test.go | 2 +- packetbeat/sniffer/file.go | 6 +- packetbeat/sniffer/sniffer.go | 59 +++++++------------ packetbeat/tests/system/test_0050_icmp.py | 8 +-- x-pack/filebeat/input/netflow/netflow_test.go | 6 +- 25 files changed, 98 insertions(+), 132 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 733f5f366043..34031ebe0dc0 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -92,6 +92,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - `event.category` no longer contains the value `network_traffic` because this is not a valid ECS event category value. {pull}20556[20556] - Remove deprecated TLS fields in favor of tls.server.x509 and tls.client.x509 ECS fields. {pull}28487[28487] - HTTP: The field `http.request.method` will maintain its original case. {pull}28620[28620] +- Unify gopacket dependencies. {pull}29167[29167] *Winlogbeat* diff --git a/NOTICE.txt b/NOTICE.txt index e4d0e19c26ca..8f660fe88437 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -10146,12 +10146,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/adriansr/gopacket -Version: v1.1.18-0.20200327165309-dd62abfa8a41 +Dependency : github.com/elastic/gopacket +Version: v1.1.20-0.20211202005954-d412fca7f83a Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/adriansr/gopacket@v1.1.18-0.20200327165309-dd62abfa8a41/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/gopacket@v1.1.20-0.20211202005954-d412fca7f83a/LICENSE: Copyright (c) 2012 Google, Inc. All rights reserved. Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. @@ -14841,44 +14841,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------- -Dependency : github.com/tsg/gopacket -Version: v0.0.0-20200626092518-2ab8e397a786 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/tsg/gopacket@v0.0.0-20200626092518-2ab8e397a786/LICENSE: - -Copyright (c) 2012 Google, Inc. All rights reserved. -Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Andreas Krennmair, Google, nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -------------------------------------------------------------------------------- Dependency : github.com/ugorji/go/codec Version: v1.1.8 diff --git a/go.mod b/go.mod index c47fcd15bc8b..5330c1dc46dc 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,7 @@ require ( github.com/gomodule/redigo v1.8.3 github.com/google/flatbuffers v1.12.1 github.com/google/go-cmp v0.5.6 - github.com/google/gopacket v1.1.18-0.20191009163724-0ad7f2610e34 + github.com/google/gopacket v1.1.19 github.com/google/uuid v1.3.0 github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 github.com/gorilla/mux v1.7.3 @@ -148,7 +148,6 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b - github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786 github.com/ugorji/go/codec v1.1.8 github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71 github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 @@ -292,7 +291,7 @@ replace ( github.com/fsnotify/fsevents => github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270 github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v1.4.8-0.20211018144411-a81f2b630e7c github.com/golang/glog => github.com/elastic/glog v1.0.1-0.20210831205241-7d8b5c89dfc4 - github.com/google/gopacket => github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41 + github.com/google/gopacket => github.com/elastic/gopacket v1.1.20-0.20211202005954-d412fca7f83a github.com/insomniacslk/dhcp => github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 // indirect github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c ) diff --git a/go.sum b/go.sum index 3ba3d94b54e4..64389aae72c6 100644 --- a/go.sum +++ b/go.sum @@ -169,8 +169,6 @@ github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6/go.mod h1:3eOhrU github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adriansr/fsnotify v1.4.8-0.20211018144411-a81f2b630e7c h1:LpOCwE9oTg0+1Dm8rB06dKxQs7yu5tdnM6A/Zm/juQQ= github.com/adriansr/fsnotify v1.4.8-0.20211018144411-a81f2b630e7c/go.mod h1:onXS6zmTa1LJcurVsOkzywEV/Q3pdEqqu362/8OQzAI= -github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41 h1:9OmEpkkO4vm8Wz+JKWHDLZdzYrqXr4dovxIJDkTltKE= -github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/aerospike/aerospike-client-go v1.27.1-0.20170612174108-0f3b54da6bdc h1:9iW/Fbn/R/nyUOiqo6AgwBe8uirqUIoTGF3vKG8qjoc= github.com/aerospike/aerospike-client-go v1.27.1-0.20170612174108-0f3b54da6bdc/go.mod h1:zj8LBEnWBDOVEIJt8LvaRvDG5ARAoa5dBeHaB472NRc= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= @@ -535,6 +533,8 @@ github.com/elastic/go-ucfg v0.8.3/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+F github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= +github.com/elastic/gopacket v1.1.20-0.20211202005954-d412fca7f83a h1:8WfL/X6fK11iyX5t3Dd9dDMMNqPfEZNc//JsWGIhEgQ= +github.com/elastic/gopacket v1.1.20-0.20211202005954-d412fca7f83a/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752 h1:5/RUNg7rkIvayjPhAIoI3v8p45NfWcfWs5DZSElycis= @@ -1496,8 +1496,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b h1:X/8hkb4rQq3+QuOxpJK7gWmAXmZucF0EI1s1BfBLq6U= github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b/go.mod h1:jAqhj/JBVC1PwcLTWd6rjQyGyItxxrhpiBl8LSuAGmw= -github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786 h1:B/IVHYiI0d04dudYw+CvCAGqSMq8d0yWy56eD6p85BQ= -github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber-go/tally v3.3.15+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= github.com/uber/athenadriver v1.1.4/go.mod h1:tQjho4NzXw55LGfSZEcETuYydpY1vtmixUabHkC1K/E= @@ -1527,6 +1525,7 @@ github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:tw github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 h1:NeNpIvfvaFOh0BH7nMEljE5Rk/VJlxhm58M41SeOD20= github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= diff --git a/libbeat/common/flowhash/communityid_test.go b/libbeat/common/flowhash/communityid_test.go index 7972fd24c27a..4398d60d946d 100644 --- a/libbeat/common/flowhash/communityid_test.go +++ b/libbeat/common/flowhash/communityid_test.go @@ -31,10 +31,11 @@ import ( "testing" "time" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/stretchr/testify/assert" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" - "github.com/tsg/gopacket/pcap" ) const ( @@ -42,9 +43,7 @@ const ( goldenDir = "testdata/golden" ) -var ( - update = flag.Bool("update", false, "updates the golden files") -) +var update = flag.Bool("update", false, "updates the golden files") func TestPCAPFiles(t *testing.T) { pcaps, err := filepath.Glob(filepath.Join(pcapDir, "*.pcap")) diff --git a/libbeat/common/seccomp/seccomp-profiler-allow.txt b/libbeat/common/seccomp/seccomp-profiler-allow.txt index a166cf6f7dac..e22f3db0eef1 100644 --- a/libbeat/common/seccomp/seccomp-profiler-allow.txt +++ b/libbeat/common/seccomp/seccomp-profiler-allow.txt @@ -9,7 +9,7 @@ access open stat -# cgo tsg/gopacket +# cgo google/gopacket poll fcntl64 diff --git a/packetbeat/beater/worker.go b/packetbeat/beater/worker.go index 5dd6a5144541..2c7f1d7eff60 100644 --- a/packetbeat/beater/worker.go +++ b/packetbeat/beater/worker.go @@ -18,7 +18,7 @@ package beater import ( - "github.com/tsg/gopacket/layers" + "github.com/google/gopacket/layers" "github.com/elastic/beats/v7/packetbeat/config" "github.com/elastic/beats/v7/packetbeat/decoder" diff --git a/packetbeat/decoder/decoder.go b/packetbeat/decoder/decoder.go index ae8eeb9d84bb..025b0899d00a 100644 --- a/packetbeat/decoder/decoder.go +++ b/packetbeat/decoder/decoder.go @@ -20,15 +20,15 @@ package decoder import ( "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/packetbeat/flows" "github.com/elastic/beats/v7/packetbeat/protos" "github.com/elastic/beats/v7/packetbeat/protos/icmp" "github.com/elastic/beats/v7/packetbeat/protos/tcp" "github.com/elastic/beats/v7/packetbeat/protos/udp" - - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" ) var debugf = logp.MakeDebug("decoder") @@ -313,6 +313,11 @@ func (d *Decoder) onICMPv6(packet *protos.Packet) { } if d.icmp6Proc != nil { + // google/gopacket treats the first four bytes + // after the typo, code and checksum as part of + // the payload. So drop those bytes. + // See https://github.com/google/gopacket/pull/423/ + d.icmp6.Payload = d.icmp6.Payload[4:] packet.Payload = d.icmp6.Payload packet.Tuple.ComputeHashables() d.icmp6Proc.ProcessICMPv6(d.flowID, &d.icmp6, packet) diff --git a/packetbeat/decoder/decoder_test.go b/packetbeat/decoder/decoder_test.go index 8e6fad990a8f..19cf7e51ab27 100644 --- a/packetbeat/decoder/decoder_test.go +++ b/packetbeat/decoder/decoder_test.go @@ -28,9 +28,9 @@ import ( "github.com/elastic/beats/v7/packetbeat/flows" "github.com/elastic/beats/v7/packetbeat/protos" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" "github.com/stretchr/testify/assert" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" ) type TestIcmp4Processor struct { diff --git a/packetbeat/decoder/util.go b/packetbeat/decoder/util.go index 4afa18262b78..ad53199ccceb 100644 --- a/packetbeat/decoder/util.go +++ b/packetbeat/decoder/util.go @@ -17,7 +17,7 @@ package decoder -import "github.com/tsg/gopacket" +import "github.com/google/gopacket" // implement DecodingLayer with support of switching between multiple layers to // remember outter layer results diff --git a/packetbeat/protos/icmp/icmp.go b/packetbeat/protos/icmp/icmp.go index c204b819adbc..d6804322c43e 100644 --- a/packetbeat/protos/icmp/icmp.go +++ b/packetbeat/protos/icmp/icmp.go @@ -21,6 +21,8 @@ import ( "net" "time" + "github.com/google/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/ecs" "github.com/elastic/beats/v7/libbeat/logp" @@ -30,8 +32,6 @@ import ( "github.com/elastic/beats/v7/packetbeat/pb" "github.com/elastic/beats/v7/packetbeat/procs" "github.com/elastic/beats/v7/packetbeat/protos" - - "github.com/tsg/gopacket/layers" ) type icmpPlugin struct { diff --git a/packetbeat/protos/icmp/icmp_test.go b/packetbeat/protos/icmp/icmp_test.go index a74e097fe047..6b03139396cb 100644 --- a/packetbeat/protos/icmp/icmp_test.go +++ b/packetbeat/protos/icmp/icmp_test.go @@ -25,6 +25,9 @@ import ( "net" "testing" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" @@ -32,9 +35,6 @@ import ( "github.com/elastic/beats/v7/packetbeat/procs" "github.com/elastic/beats/v7/packetbeat/protos" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" - "github.com/stretchr/testify/assert" ) diff --git a/packetbeat/protos/icmp/message.go b/packetbeat/protos/icmp/message.go index 873809a212a9..425505deffb9 100644 --- a/packetbeat/protos/icmp/message.go +++ b/packetbeat/protos/icmp/message.go @@ -21,7 +21,7 @@ import ( "encoding/binary" "time" - "github.com/tsg/gopacket/layers" + "github.com/google/gopacket/layers" "github.com/elastic/beats/v7/libbeat/logp" ) diff --git a/packetbeat/protos/icmp/message_test.go b/packetbeat/protos/icmp/message_test.go index 6ebc00fe3514..8f8ac56e3eed 100644 --- a/packetbeat/protos/icmp/message_test.go +++ b/packetbeat/protos/icmp/message_test.go @@ -23,7 +23,7 @@ package icmp import ( "testing" - "github.com/tsg/gopacket/layers" + "github.com/google/gopacket/layers" "github.com/stretchr/testify/assert" ) @@ -113,5 +113,5 @@ func TestIcmpMessageHumanReadableICMPv6(t *testing.T) { tuple := &icmpTuple{icmpVersion: 6} msg := &icmpMessage{Type: layers.ICMPv6TypeDestinationUnreachable, code: 3} - assert.Equal(t, "DestinationUnreachable(Address)", humanReadable(tuple, msg)) + assert.Equal(t, "DestinationUnreachable(AddressUnreachable)", humanReadable(tuple, msg)) } diff --git a/packetbeat/protos/icmp/transaction_test.go b/packetbeat/protos/icmp/transaction_test.go index 3c1f7fe64c54..1846b19e6719 100644 --- a/packetbeat/protos/icmp/transaction_test.go +++ b/packetbeat/protos/icmp/transaction_test.go @@ -23,7 +23,7 @@ package icmp import ( "testing" - "github.com/tsg/gopacket/layers" + "github.com/google/gopacket/layers" "github.com/stretchr/testify/assert" ) diff --git a/packetbeat/protos/tcp/tcp.go b/packetbeat/protos/tcp/tcp.go index 51ac46346a08..c275925cbcf7 100644 --- a/packetbeat/protos/tcp/tcp.go +++ b/packetbeat/protos/tcp/tcp.go @@ -22,14 +22,14 @@ import ( "sync" "time" + "github.com/google/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/monitoring" "github.com/elastic/beats/v7/packetbeat/flows" "github.com/elastic/beats/v7/packetbeat/protos" - - "github.com/tsg/gopacket/layers" ) const TCPMaxDataInStream = 10 * (1 << 20) diff --git a/packetbeat/protos/tcp/tcp_test.go b/packetbeat/protos/tcp/tcp_test.go index 5678924a7d6a..31aba7f39e40 100644 --- a/packetbeat/protos/tcp/tcp_test.go +++ b/packetbeat/protos/tcp/tcp_test.go @@ -26,12 +26,13 @@ import ( "testing" "time" + "github.com/google/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/packetbeat/procs" "github.com/elastic/beats/v7/packetbeat/protos" "github.com/stretchr/testify/assert" - "github.com/tsg/gopacket/layers" ) // Test Constants diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 5d4c60c53132..1660daefe0dc 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -26,15 +26,18 @@ import ( "time" "unsafe" - "github.com/elastic/beats/v7/libbeat/logp" + "github.com/google/gopacket" + "github.com/google/gopacket/afpacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "golang.org/x/net/bpf" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/afpacket" - "github.com/tsg/gopacket/layers" + "github.com/elastic/beats/v7/libbeat/logp" ) type afpacketHandle struct { TPacket *afpacket.TPacket + frameSize int promiscPreviousState bool promiscPreviousStateDetected bool device string @@ -61,6 +64,7 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in h := &afpacketHandle{ promiscPreviousState: promiscEnabled, + frameSize: snaplen, device: device, promiscPreviousStateDetected: autoPromiscMode && err == nil, } @@ -87,8 +91,21 @@ func (h *afpacketHandle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, return h.TPacket.ReadPacketData() } -func (h *afpacketHandle) SetBPFFilter(expr string) (_ error) { - return h.TPacket.SetBPFFilter(expr) +func (h *afpacketHandle) SetBPFFilter(expr string) error { + prog, err := pcap.CompileBPFFilter(layers.LinkTypeEthernet, h.frameSize, expr) + if err != nil { + return err + } + p := make([]bpf.RawInstruction, len(prog)) + for i, ins := range prog { + p[i] = bpf.RawInstruction{ + Op: ins.Code, + Jt: ins.Jt, + Jf: ins.Jf, + K: ins.K, + } + } + return h.TPacket.SetBPF(p) } func (h *afpacketHandle) LinkType() layers.LinkType { diff --git a/packetbeat/sniffer/afpacket_nonlinux.go b/packetbeat/sniffer/afpacket_nonlinux.go index 67e32e9b2671..9c3558c19f8f 100644 --- a/packetbeat/sniffer/afpacket_nonlinux.go +++ b/packetbeat/sniffer/afpacket_nonlinux.go @@ -24,8 +24,8 @@ import ( "fmt" "time" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" ) type afpacketHandle struct{} diff --git a/packetbeat/sniffer/device.go b/packetbeat/sniffer/device.go index fbe23d5ce2cc..3ec52f8d8e21 100644 --- a/packetbeat/sniffer/device.go +++ b/packetbeat/sniffer/device.go @@ -23,7 +23,7 @@ import ( "strconv" "strings" - "github.com/tsg/gopacket/pcap" + "github.com/google/gopacket/pcap" "github.com/elastic/beats/v7/libbeat/logp" ) diff --git a/packetbeat/sniffer/device_test.go b/packetbeat/sniffer/device_test.go index 189bc92a9cd7..e7bb9cfee5a4 100644 --- a/packetbeat/sniffer/device_test.go +++ b/packetbeat/sniffer/device_test.go @@ -22,7 +22,7 @@ import ( "reflect" "testing" - "github.com/tsg/gopacket/pcap" + "github.com/google/gopacket/pcap" ) var formatDeviceNamesTests = []struct { diff --git a/packetbeat/sniffer/file.go b/packetbeat/sniffer/file.go index b112e4c90edb..ec0d16f554d7 100644 --- a/packetbeat/sniffer/file.go +++ b/packetbeat/sniffer/file.go @@ -22,9 +22,9 @@ import ( "io" "time" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" - "github.com/tsg/gopacket/pcap" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" "github.com/elastic/beats/v7/libbeat/logp" ) diff --git a/packetbeat/sniffer/sniffer.go b/packetbeat/sniffer/sniffer.go index 07a7e3096a9b..de0a1683a5f8 100644 --- a/packetbeat/sniffer/sniffer.go +++ b/packetbeat/sniffer/sniffer.go @@ -25,9 +25,10 @@ import ( "syscall" "time" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/layers" - "github.com/tsg/gopacket/pcap" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/pcapgo" "github.com/elastic/beats/v7/libbeat/common/atomic" "github.com/elastic/beats/v7/libbeat/logp" @@ -139,24 +140,22 @@ func New( // Run opens the sniffing device and processes packets being read from that device. // Worker instances are instantiated as needed. func (s *Sniffer) Run() error { - var ( - counter = 0 - dumper *pcap.Dumper - ) - handle, err := s.open() if err != nil { return fmt.Errorf("Error starting sniffer: %s", err) } defer handle.Close() + var w *pcapgo.Writer if s.config.Dumpfile != "" { - dumper, err = openDumper(s.config.Dumpfile, handle.LinkType()) + f, err := os.Create(s.config.Dumpfile) if err != nil { return err } + defer f.Close() - defer dumper.Close() + w = pcapgo.NewWriterNanos(f) + w.WriteFileHeader(65535, handle.LinkType()) } worker, err := s.factory(handle.LinkType()) @@ -172,6 +171,7 @@ func (s *Sniffer) Run() error { } defer s.state.Store(snifferInactive) + var packets int for s.state.Load() == snifferActive { if s.config.OneAtATime { fmt.Println("Press enter to read packet") @@ -191,7 +191,7 @@ func (s *Sniffer) Run() error { } s.state.Store(snifferInactive) - return fmt.Errorf("Sniffing error: %s", err) + return fmt.Errorf("Sniffing error: %w", err) } if len(data) == 0 { @@ -199,12 +199,16 @@ func (s *Sniffer) Run() error { continue } - if dumper != nil { - dumper.WritePacketData(data, ci) + packets++ + + if w != nil { + err = w.WritePacket(ci, data) + if err != nil { + return fmt.Errorf("failed to write packet %d: %w", packets, err) + } } - counter++ - logp.Debug("sniffer", "Packet number: %d", counter) + logp.Debug("sniffer", "Packet number: %d", packets) worker.OnPacket(data, &ci) } @@ -263,20 +267,8 @@ func validatePcapFilter(expr string) error { if expr == "" { return nil } - - // Open a dummy pcap handle to compile the filter - p, err := pcap.OpenDead(layers.LinkTypeEthernet, 65535) - if err != nil { - return fmt.Errorf("OpenDead: %s", err) - } - - defer p.Close() - - _, err = p.NewBPF(expr) - if err != nil { - return fmt.Errorf("invalid filter '%s': %v", expr, err) - } - return nil + _, err := pcap.NewBPF(layers.LinkTypeEthernet, 65535, expr) + return err } func openPcap(filter string, cfg *config.InterfacesConfig) (snifferHandle, error) { @@ -316,12 +308,3 @@ func openAFPacket(filter string, cfg *config.InterfacesConfig) (snifferHandle, e return h, nil } - -func openDumper(file string, linkType layers.LinkType) (*pcap.Dumper, error) { - p, err := pcap.OpenDead(linkType, 65535) - if err != nil { - return nil, err - } - - return p.NewDumper(file) -} diff --git a/packetbeat/tests/system/test_0050_icmp.py b/packetbeat/tests/system/test_0050_icmp.py index c0f876c1b734..05b21b845eda 100644 --- a/packetbeat/tests/system/test_0050_icmp.py +++ b/packetbeat/tests/system/test_0050_icmp.py @@ -82,10 +82,10 @@ def assert_common_icmp4_fields(self, obj): assert obj["related.ip"] == ["10.0.0.1", "10.0.0.2"] assert obj["path"] == "10.0.0.2" assert obj["status"] == "OK" - assert obj["icmp.request.message"] == "EchoRequest(0)" + assert obj["icmp.request.message"] == "EchoRequest" assert obj["icmp.request.type"] == 8 assert obj["icmp.request.code"] == 0 - assert obj["icmp.response.message"] == "EchoReply(0)" + assert obj["icmp.response.message"] == "EchoReply" assert obj["icmp.response.type"] == 0 assert obj["icmp.response.code"] == 0 @@ -95,9 +95,9 @@ def assert_common_icmp6_fields(self, obj): assert obj["client.ip"] == "::1" assert obj["path"] == "::2" assert obj["status"] == "OK" - assert obj["icmp.request.message"] == "EchoRequest(0)" + assert obj["icmp.request.message"] == "EchoRequest" assert obj["icmp.request.type"] == 128 assert obj["icmp.request.code"] == 0 - assert obj["icmp.response.message"] == "EchoReply(0)" + assert obj["icmp.response.message"] == "EchoReply" assert obj["icmp.response.type"] == 129 assert obj["icmp.response.code"] == 0 diff --git a/x-pack/filebeat/input/netflow/netflow_test.go b/x-pack/filebeat/input/netflow/netflow_test.go index f1c138989c08..caaa438ebf36 100644 --- a/x-pack/filebeat/input/netflow/netflow_test.go +++ b/x-pack/filebeat/input/netflow/netflow_test.go @@ -16,9 +16,9 @@ import ( "strings" "testing" + "github.com/google/gopacket" + "github.com/google/gopacket/pcap" "github.com/stretchr/testify/assert" - "github.com/tsg/gopacket" - "github.com/tsg/gopacket/pcap" "gopkg.in/yaml.v2" "github.com/elastic/beats/v7/libbeat/beat" @@ -201,7 +201,7 @@ func getFlowsFromDat(t testing.TB, name string, testCase TestCase) TestResult { flow.Fields.Delete("event.created") ev[i] = flow } - //return TestResult{Name: name, Error: err.Error(), Events: flowsToEvents(flows)} + // return TestResult{Name: name, Error: err.Error(), Events: flowsToEvents(flows)} events = append(events, ev...) } } From 95c6b61f324b9e034c1c6b6c4768644a6e40ab0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Mon, 6 Dec 2021 11:45:53 +0100 Subject: [PATCH 056/172] Add missing format specifier in watchCmd() (#29251) --- x-pack/elastic-agent/pkg/agent/cmd/watch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/watch.go b/x-pack/elastic-agent/pkg/agent/cmd/watch.go index 2904d8361080..6ee05c40932e 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/watch.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/watch.go @@ -95,7 +95,7 @@ func watchCmd(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { ctx := context.Background() if err := watch(ctx, tilGrace, log); err != nil { - log.Debugf("Error detected proceeding to rollback", err) + log.Debugf("Error detected proceeding to rollback: %v", err) err = upgrade.Rollback(ctx, marker.PrevHash, marker.Hash) if err != nil { log.Error("rollback failed", err) From 405c3428b9f5c135c78058aa2c183feb3200edd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Mon, 6 Dec 2021 13:13:41 +0100 Subject: [PATCH 057/172] Setup data streams and send events to them (#28450) ## What does this PR do? We are introducing data streams to Beats. It means that all Beats are going to send events to data streams instead of indices regardless of ES version. Do not confuse it with the data stream naming convention we use in integrations. Naming does not change in Beats, only the underlying data storage method in Elasticsearch. The name of the data stream is going to be `{beatname}-{version}` and the index pattern is `{beatname}-{version}`. With this change, the option `setup.template.type` no longer makes sense. Hence, it is removed completely from 8.x. If you are loading JSON index templates by specifying a file in `setup.template.json.path`, make sure you move from the legacy format to composable index templates. Beats no longer load an alias to Elasticsearch, instead all data can be reached through the data stream. One of the limitations is that only create operations are supported in data streams. Thus, there is no way to use e.g. "index" or "delete" operation types when sending events to ES. ## Why is it important? Simplify loading ILM, templates, and use the specialized data streams for output events. --- CHANGELOG.next.asciidoc | 3 + auditbeat/auditbeat.reference.yml | 23 +-- filebeat/filebeat.reference.yml | 23 +-- filebeat/tests/system/config/filebeat.yml.j2 | 8 +- .../system/config/filebeat_inputs.yml.j2 | 8 +- filebeat/tests/system/test_modules.py | 4 +- heartbeat/heartbeat.reference.yml | 23 +-- .../_meta/config/setup.ilm.reference.yml.tmpl | 13 +- .../config/setup.template.reference.yml.tmpl | 10 +- .../docs/howto/load-index-templates.asciidoc | 2 +- libbeat/docs/template-config.asciidoc | 14 +- libbeat/idxmgmt/ilm/client_handler.go | 173 ++---------------- .../ilm/client_handler_integration_test.go | 94 ---------- libbeat/idxmgmt/ilm/config.go | 27 +-- libbeat/idxmgmt/ilm/error.go | 3 - libbeat/idxmgmt/ilm/ilm.go | 25 +-- libbeat/idxmgmt/ilm/ilm_test.go | 115 +----------- libbeat/idxmgmt/ilm/mockapihandler_test.go | 12 -- libbeat/idxmgmt/ilm/noop.go | 4 +- libbeat/idxmgmt/ilm/std.go | 52 ------ libbeat/idxmgmt/mockilm_test.go | 12 -- libbeat/idxmgmt/std.go | 67 +------ libbeat/idxmgmt/std_test.go | 112 ++++-------- libbeat/publisher/processing/processors.go | 6 + libbeat/template/config.go | 51 +----- libbeat/template/load.go | 86 ++------- libbeat/template/load_integration_test.go | 77 ++++---- libbeat/template/load_test.go | 157 ++++++++-------- libbeat/template/processor.go | 45 +---- libbeat/template/processor_test.go | 16 -- libbeat/template/template.go | 173 ++++-------------- libbeat/template/template_test.go | 47 ++--- libbeat/template/testdata/fields.json | 20 +- libbeat/template/testdata/fields.yml | 2 + libbeat/tests/files/template.json | 26 +-- libbeat/tests/system/beat/common_tests.py | 7 +- libbeat/tests/system/config/libbeat.yml.j2 | 3 - libbeat/tests/system/idxmgmt.py | 87 ++++----- libbeat/tests/system/template/template.go | 4 +- .../system/test_cmd_setup_index_management.py | 153 +++++----------- libbeat/tests/system/test_ilm.py | 141 +++----------- libbeat/tests/system/test_template.py | 134 ++++---------- metricbeat/metricbeat.reference.yml | 23 +-- metricbeat/tests/system/test_template.py | 2 +- packetbeat/packetbeat.reference.yml | 23 +-- winlogbeat/winlogbeat.reference.yml | 23 +-- x-pack/auditbeat/auditbeat.reference.yml | 23 +-- x-pack/filebeat/filebeat.reference.yml | 23 +-- .../module/ibmmq/errorlog/ingest/pipeline.yml | 6 +- .../test/AMQERR01_QM1.log-expected.json | 23 +++ .../module/snyk/audit/config/config.yml | 7 - .../snyk/vulnerabilities/config/config.yml | 7 - .../functionbeat/functionbeat.reference.yml | 23 +-- x-pack/heartbeat/heartbeat.reference.yml | 23 +-- x-pack/metricbeat/metricbeat.reference.yml | 23 +-- x-pack/osquerybeat/osquerybeat.reference.yml | 23 +-- x-pack/packetbeat/packetbeat.reference.yml | 23 +-- x-pack/winlogbeat/winlogbeat.reference.yml | 23 +-- 58 files changed, 536 insertions(+), 1824 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 34031ebe0dc0..0ad71e056376 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -25,6 +25,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove `auto` from the available options of `setup.ilm.enabled` and set the default value to `true`. {pull}28671[28671] - add_process_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - add_docker_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] +- Use data streams instead of indices for storing events from Beats. {pull}28450[28450] +- Remove option `setup.template.type` and always load composable template with data streams. {pull}28450[28450] +- Remove several ILM options (`rollover_alias` and `pattern`) as data streams does not require index aliases. {pull}28450[28450] - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 24bfac144149..fc685b6c231a 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -1145,19 +1145,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default auditbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "auditbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "auditbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "auditbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "auditbeat-%{[agent.version]}-*" +#setup.template.pattern: "auditbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1204,17 +1198,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'auditbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'auditbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 9b6a421d6c43..a8217924d4dd 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -2078,19 +2078,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default filebeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "filebeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "filebeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "filebeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "filebeat-%{[agent.version]}-*" +#setup.template.pattern: "filebeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -2137,17 +2131,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'filebeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'filebeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/filebeat/tests/system/config/filebeat.yml.j2 b/filebeat/tests/system/config/filebeat.yml.j2 index 4f74323ead17..f3b250c6b499 100644 --- a/filebeat/tests/system/config/filebeat.yml.j2 +++ b/filebeat/tests/system/config/filebeat.yml.j2 @@ -120,14 +120,8 @@ filebeat.config.{{ reload_type|default("inputs") }}: {% if ilm %} setup.ilm: - enabled: {{ ilm.enabled | default("auto") }} + enabled: {{ ilm.enabled | default("true") }} policy_name: libbeat-test-default-policy - {% if ilm.pattern %} - pattern: {{ ilm.pattern }} - {% endif %} - {% if ilm.rollover_alias %} - rollover_alias: {{ ilm.rollover_alias }} - {% endif %} {% endif %} diff --git a/filebeat/tests/system/config/filebeat_inputs.yml.j2 b/filebeat/tests/system/config/filebeat_inputs.yml.j2 index f9a6d725a92d..9757f60023a2 100644 --- a/filebeat/tests/system/config/filebeat_inputs.yml.j2 +++ b/filebeat/tests/system/config/filebeat_inputs.yml.j2 @@ -17,14 +17,8 @@ filebeat.registry: {% if ilm %} setup.ilm: - enabled: {{ ilm.enabled | default("auto") }} + enabled: {{ ilm.enabled | default("true") }} policy_name: libbeat-test-default-policy - {% if ilm.pattern %} - pattern: {{ ilm.pattern }} - {% endif %} - {% if ilm.rollover_alias %} - rollover_alias: {{ ilm.rollover_alias }} - {% endif %} {% endif %} diff --git a/filebeat/tests/system/test_modules.py b/filebeat/tests/system/test_modules.py index b552560f83cd..b4ee0c7b4872 100644 --- a/filebeat/tests/system/test_modules.py +++ b/filebeat/tests/system/test_modules.py @@ -104,7 +104,7 @@ def run_on_file(self, module, fileset, test_file, cfgfile): self.assert_explicit_ecs_version_set(module, fileset) try: - self.es.indices.delete(index=self.index_name) + self.es.indices.delete_data_stream(self.index_name) except BaseException: pass self.wait_until(lambda: not self.es.indices.exists(self.index_name)) @@ -242,7 +242,7 @@ def clean_keys(obj): host_keys.append("host.name") # The create timestamps area always new - time_keys = ["event.created", "event.ingested"] + time_keys = ["event.created", "event.ingested", "@timestamp"] # source path and agent.version can be different for each run other_keys = ["log.file.path", "agent.version"] # ECS versions change for any ECS release, large or small diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 8f0f019626bd..c3ae5c012145 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -1291,19 +1291,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default heartbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "heartbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "heartbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "heartbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "heartbeat-%{[agent.version]}-*" +#setup.template.pattern: "heartbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1350,17 +1344,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'heartbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'heartbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/libbeat/_meta/config/setup.ilm.reference.yml.tmpl b/libbeat/_meta/config/setup.ilm.reference.yml.tmpl index 1416da0cc8dc..5e4a2e642fe3 100644 --- a/libbeat/_meta/config/setup.ilm.reference.yml.tmpl +++ b/libbeat/_meta/config/setup.ilm.reference.yml.tmpl @@ -5,17 +5,8 @@ # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is '{{.BeatName}}-%{[agent.version]}'. -#setup.ilm.rollover_alias: '{{.BeatIndexPrefix}}' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/libbeat/_meta/config/setup.template.reference.yml.tmpl b/libbeat/_meta/config/setup.template.reference.yml.tmpl index 95d8d4a50c88..d3019c6f2b8a 100644 --- a/libbeat/_meta/config/setup.template.reference.yml.tmpl +++ b/libbeat/_meta/config/setup.template.reference.yml.tmpl @@ -7,19 +7,13 @@ # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default {{.BeatName}} uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "{{.BeatIndexPrefix}}-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "{{.BeatIndexPrefix}}-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "{{.BeatIndexPrefix}}-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "{{.BeatIndexPrefix}}-%{[agent.version]}-*" +#setup.template.pattern: "{{.BeatIndexPrefix}}-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" diff --git a/libbeat/docs/howto/load-index-templates.asciidoc b/libbeat/docs/howto/load-index-templates.asciidoc index 885432a26715..f62efecdc043 100644 --- a/libbeat/docs/howto/load-index-templates.asciidoc +++ b/libbeat/docs/howto/load-index-templates.asciidoc @@ -224,7 +224,7 @@ PS > Invoke-RestMethod -Method Delete "http://localhost:9200/{beatname_lc}-*" ---------------------------------------------------------------------- endif::win_os[] -This command deletes all indices that match the pattern +{beat_default_index_prefix}-*+. +This command deletes all indices that match the pattern +{beat_default_index_prefix}+. Before running this command, make sure you want to delete all indices that match the pattern. diff --git a/libbeat/docs/template-config.asciidoc b/libbeat/docs/template-config.asciidoc index 5699a46dd761..2ec64291b803 100644 --- a/libbeat/docs/template-config.asciidoc +++ b/libbeat/docs/template-config.asciidoc @@ -26,13 +26,6 @@ existing one. *`setup.template.enabled`*:: Set to false to disable template loading. If this is set to false, you must <>. -ifndef::apm-server[] -*`setup.template.type`*:: The type of template to use. Available options: `legacy` (default), index templates -before Elasticsearch v7.8. Use this to avoid breaking existing deployments. New options are `component` -and `index`. Selecting `component` loads a component template which can be included in new index templates. -The option `index` loads the new index template. -endif::[] - *`setup.template.name`*:: The name of the template. The default is +{beatname_lc}+. The {beatname_uc} version is always appended to the given name, so the final name is +{beatname_lc}-%{[{beat_version_key}]}+. @@ -44,17 +37,16 @@ name, so the final name is +{beatname_lc}-%{[{beat_version_key}]}+. // the example as expected. *`setup.template.pattern`*:: The template pattern to apply to the default index -settings. The default pattern is +{beat_default_index_prefix}-\*+. The {beatname_uc} version is always +settings. The default pattern is +{beat_default_index_prefix}+. The {beatname_uc} version is always included in the pattern, so the final pattern is -+{beat_default_index_prefix}-%{[{beat_version_key}]}-*+. The wildcard character `-*` is used to -match all daily indices. ++{beat_default_index_prefix}-%{[{beat_version_key}]}+. + Example: + ["source","yaml",subs="attributes"] ---------------------------------------------------------------------- setup.template.name: "{beatname_lc}" -setup.template.pattern: "{beat_default_index_prefix}-*" +setup.template.pattern: "{beat_default_index_prefix}" ---------------------------------------------------------------------- *`setup.template.fields`*:: The path to the YAML file describing the fields. The default is +fields.yml+. If a diff --git a/libbeat/idxmgmt/ilm/client_handler.go b/libbeat/idxmgmt/ilm/client_handler.go index 9ec4cc218d01..4d2163091aea 100644 --- a/libbeat/idxmgmt/ilm/client_handler.go +++ b/libbeat/idxmgmt/ilm/client_handler.go @@ -18,9 +18,7 @@ package ilm import ( - "encoding/json" "fmt" - "net/url" "path" "github.com/elastic/beats/v7/libbeat/common" @@ -29,10 +27,6 @@ import ( // ClientHandler defines the interface between a remote service and the Manager. type ClientHandler interface { CheckILMEnabled(bool) (bool, error) - - HasAlias(name string) (bool, error) - CreateAlias(alias Alias) error - HasILMPolicy(name string) (bool, error) CreateILMPolicy(policy Policy) error } @@ -42,10 +36,14 @@ type ESClientHandler struct { client ESClient } +type VersionCheckerClient interface { + GetVersion() common.Version +} + // ESClient defines the minimal interface required for the Loader to -// prepare a policy and write alias. +// prepare a policy. type ESClient interface { - GetVersion() common.Version + VersionCheckerClient Request( method, path string, pipeline string, @@ -60,24 +58,17 @@ type FileClientHandler struct { } // FileClient defines the minimal interface required for the Loader to -// prepare a policy and write alias. +// prepare a policy. type FileClient interface { GetVersion() common.Version Write(component string, name string, body string) error } const ( - // esFeaturesPath is used to query Elasticsearch for availability of licensed - // features. - esFeaturesPath = "/_xpack" - esILMPath = "/_ilm/policy" - - esAliasPath = "/_alias" ) var ( - esMinILMVersion = common.MustNewVersion("6.6.0") esMinDefaultILMVersion = common.MustNewVersion("7.0.0") ) @@ -93,31 +84,7 @@ func NewFileClientHandler(c FileClient) *FileClientHandler { // CheckILMEnabled indicates whether or not ILM is supported for the configured mode and ES instance. func (h *ESClientHandler) CheckILMEnabled(enabled bool) (bool, error) { - if !enabled { - return false, nil - } - - ver := h.client.GetVersion() - if !checkILMVersion(h.client.GetVersion()) { - return false, errf(ErrESVersionNotSupported, "Elasticsearch %v does not support ILM", ver.String()) - } - - avail, enabledILM, err := h.checkILMSupport() - if err != nil { - return false, err - } - - if !avail { - if enabledILM { - return false, errOf(ErrESVersionNotSupported) - } - return false, nil - } - - if !enabledILM && enabled { - return false, errOf(ErrESILMDisabled) - } - return enabled, nil + return checkILMEnabled(enabled, h.client) } // CreateILMPolicy loads the given policy to Elasticsearch. @@ -139,110 +106,21 @@ func (h *ESClientHandler) HasILMPolicy(name string) (bool, error) { return status == 200, nil } -// HasAlias queries Elasticsearch to see if alias exists. If other resource -// with the same name exists, it returns an error. -func (h *ESClientHandler) HasAlias(name string) (bool, error) { - status, b, err := h.client.Request("GET", esAliasPath+"/"+name, "", nil, nil) - if err != nil && status != 404 { - return false, wrapErrf(err, ErrRequestFailed, - "failed to check for alias '%v': (status=%v) %s", name, status, b) - } - if status == 200 { - return true, nil - } - - // Alias doesn't exist, check if there is an index with the same name - status, b, err = h.client.Request("HEAD", "/"+name, "", nil, nil) - if err != nil && status != 404 { - return false, wrapErrf(err, ErrRequestFailed, - "failed to check for alias '%v': (status=%v) %s", name, status, b) - } - if status == 200 { - return false, errf(ErrInvalidAlias, - "resource '%v' exists, but it is not an alias", name) - } - return false, nil -} - -// CreateAlias sends request to Elasticsearch for creating alias. -func (h *ESClientHandler) CreateAlias(alias Alias) error { - // Escaping because of date pattern - // This always assume it's a date pattern by sourrounding it by <...> - firstIndex := fmt.Sprintf("<%s-%s>", alias.Name, alias.Pattern) - firstIndex = url.PathEscape(firstIndex) - - body := common.MapStr{ - "aliases": common.MapStr{ - alias.Name: common.MapStr{ - "is_write_index": true, - }, - }, - } - - // Note: actual aliases are accessible via the index - if _, res, err := h.client.Request("PUT", "/"+firstIndex, "", nil, body); err != nil { - // Creating the index may fail for multiple reasons, e.g. because - // the index exists, or because the write alias exists and points - // to another index. - if ok, err := h.HasAlias(alias.Name); err != nil { - // HasAlias fails if there is an index with the same name. - return err - } else if ok { - return errOf(ErrAliasAlreadyExists) - } - return wrapErrf(err, ErrAliasCreateFailed, "failed to create alias: %s", res) - } - return nil -} - -func (h *ESClientHandler) checkILMSupport() (avail, enabled bool, err error) { - var response struct { - Features struct { - ILM struct { - Available bool `json:"available"` - Enabled bool `json:"enabled"` - } `json:"ilm"` - } `json:"features"` - } - status, err := h.queryFeatures(&response) - if status == 400 { - // If we get a 400, it's assumed to be the OSS version of Elasticsearch - return false, false, nil - } - if err != nil { - return false, false, wrapErr(err, ErrILMCheckRequestFailed) - } - - avail = response.Features.ILM.Available - enabled = response.Features.ILM.Enabled - return avail, enabled, nil -} - -func (h *ESClientHandler) queryFeatures(to interface{}) (int, error) { - status, body, err := h.client.Request("GET", esFeaturesPath, "", nil, nil) - if status >= 400 || err != nil { - return status, err - } - - if to != nil { - if err := json.Unmarshal(body, to); err != nil { - return status, wrapErrf(err, ErrInvalidResponse, "failed to parse JSON response") - } - } - return status, nil -} - // CheckILMEnabled indicates whether or not ILM is supported for the configured mode and client version. func (h *FileClientHandler) CheckILMEnabled(enabled bool) (bool, error) { + return checkILMEnabled(enabled, h.client) +} + +func checkILMEnabled(enabled bool, c VersionCheckerClient) (bool, error) { if !enabled { return false, nil } - version := h.client.GetVersion() - if checkILMVersion(version) { - return enabled, nil + + ver := c.GetVersion() + if ver.LessThan(esMinDefaultILMVersion) { + return false, errf(ErrESVersionNotSupported, "Elasticsearch %v does not support ILM", ver.String()) } - return false, errf(ErrESVersionNotSupported, - "Elasticsearch %v does not support ILM", version.String()) + return true, nil } // CreateILMPolicy writes given policy to the configured file. @@ -258,20 +136,3 @@ func (h *FileClientHandler) CreateILMPolicy(policy Policy) error { func (h *FileClientHandler) HasILMPolicy(name string) (bool, error) { return false, nil } - -// CreateAlias is a noop implementation. -func (h *FileClientHandler) CreateAlias(alias Alias) error { - return nil -} - -// HasAlias always returns false. -func (h *FileClientHandler) HasAlias(name string) (bool, error) { - return false, nil -} - -// avail: indicates whether version supports ILM -// probe: in case version potentially supports ILM, check the combination of mode + version -// to indicate whether or not ILM support should be enabled or disabled -func checkILMVersion(ver common.Version) (avail bool) { - return !ver.LessThan(esMinILMVersion) -} diff --git a/libbeat/idxmgmt/ilm/client_handler_integration_test.go b/libbeat/idxmgmt/ilm/client_handler_integration_test.go index b6f2755fd3d4..42b19cf44ae8 100644 --- a/libbeat/idxmgmt/ilm/client_handler_integration_test.go +++ b/libbeat/idxmgmt/ilm/client_handler_integration_test.go @@ -104,100 +104,6 @@ func TestESClientHandler_ILMPolicy(t *testing.T) { }) } -func TestESClientHandler_Alias(t *testing.T) { - makeAlias := func(base string) ilm.Alias { - return ilm.Alias{ - Name: makeName(base), - Pattern: "{now/d}-000001", - } - } - - t.Run("does not exist", func(t *testing.T) { - name := makeName("esch-alias-no") - h := newESClientHandler(t) - b, err := h.HasAlias(name) - assert.NoError(t, err) - assert.False(t, b) - }) - - t.Run("create new", func(t *testing.T) { - alias := makeAlias("esch-alias-create") - h := newESClientHandler(t) - err := h.CreateAlias(alias) - assert.NoError(t, err) - - b, err := h.HasAlias(alias.Name) - assert.NoError(t, err) - assert.True(t, b) - }) - - t.Run("create index exists", func(t *testing.T) { - alias := makeAlias("esch-alias-2create") - h := newESClientHandler(t) - - err := h.CreateAlias(alias) - assert.NoError(t, err) - - // Second time around creating the alias, ErrAliasAlreadyExists is returned: - // the initial index already exists and the write alias points to it. - err = h.CreateAlias(alias) - require.Error(t, err) - assert.Equal(t, ilm.ErrAliasAlreadyExists, ilm.ErrReason(err)) - - b, err := h.HasAlias(alias.Name) - assert.NoError(t, err) - assert.True(t, b) - }) - - t.Run("create alias exists", func(t *testing.T) { - alias := makeAlias("esch-alias-2create") - alias.Pattern = "000001" // no date math, so we get predictable index names - h := newESClientHandler(t) - - err := h.CreateAlias(alias) - assert.NoError(t, err) - - // Rollover, so write alias points at -000002. - es := newRawESClient(t) - _, _, err = es.Request("POST", "/"+alias.Name+"/_rollover", "", nil, nil) - require.NoError(t, err) - - // Delete -000001, simulating ILM delete. - _, _, err = es.Request("DELETE", "/"+alias.Name+"-"+alias.Pattern, "", nil, nil) - require.NoError(t, err) - - // Second time around creating the alias, ErrAliasAlreadyExists is returned: - // initial index does not exist, but the write alias exists and points to - // another index. - err = h.CreateAlias(alias) - require.Error(t, err) - assert.Equal(t, ilm.ErrAliasAlreadyExists, ilm.ErrReason(err)) - - b, err := h.HasAlias(alias.Name) - assert.NoError(t, err) - assert.True(t, b) - }) - - t.Run("resource exists but is not an alias", func(t *testing.T) { - alias := makeAlias("esch-alias-3create") - - es := newRawESClient(t) - - _, _, err := es.Request("PUT", "/"+alias.Name, "", nil, nil) - require.NoError(t, err) - - h := newESClientHandler(t) - - b, err := h.HasAlias(alias.Name) - assert.Equal(t, ilm.ErrInvalidAlias, ilm.ErrReason(err)) - assert.False(t, b) - - err = h.CreateAlias(alias) - require.Error(t, err) - assert.Equal(t, ilm.ErrInvalidAlias, ilm.ErrReason(err)) - }) -} - func newESClientHandler(t *testing.T) ilm.ClientHandler { client := newRawESClient(t) return ilm.NewESClientHandler(client) diff --git a/libbeat/idxmgmt/ilm/config.go b/libbeat/idxmgmt/ilm/config.go index f8e25f22f5b4..ea5cd9ac1e4b 100644 --- a/libbeat/idxmgmt/ilm/config.go +++ b/libbeat/idxmgmt/ilm/config.go @@ -18,8 +18,6 @@ package ilm import ( - "fmt" - "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/fmtstr" @@ -27,11 +25,9 @@ import ( // Config is used for unpacking a common.Config. type Config struct { - Enabled bool `config:"enabled"` - PolicyName fmtstr.EventFormatString `config:"policy_name"` - PolicyFile string `config:"policy_file"` - RolloverAlias fmtstr.EventFormatString `config:"rollover_alias"` - Pattern string `config:"pattern"` + Enabled bool `config:"enabled"` + PolicyName fmtstr.EventFormatString `config:"policy_name"` + PolicyFile string `config:"policy_file"` // CheckExists can disable the check for an existing policy. Check required // read_ilm privileges. If check is disabled the policy will only be @@ -42,8 +38,6 @@ type Config struct { Overwrite bool `config:"overwrite"` } -const ilmDefaultPattern = "{now/d}-000001" - // DefaultPolicy defines the default policy to be used if no custom policy is // configured. // By default the policy contains not warm, cold, or delete phase. @@ -65,23 +59,16 @@ var DefaultPolicy = common.MapStr{ //Validate verifies that expected config options are given and valid func (cfg *Config) Validate() error { - if cfg.RolloverAlias.IsEmpty() && cfg.Enabled { - return fmt.Errorf("rollover_alias must be set when ILM is not disabled") - } return nil } func defaultConfig(info beat.Info) Config { - name := info.Beat + "-%{[agent.version]}" - aliasFmt := fmtstr.MustCompileEvent(name) policyFmt := fmtstr.MustCompileEvent(info.Beat) return Config{ - Enabled: true, - PolicyName: *policyFmt, - RolloverAlias: *aliasFmt, - Pattern: ilmDefaultPattern, - PolicyFile: "", - CheckExists: true, + Enabled: true, + PolicyName: *policyFmt, + PolicyFile: "", + CheckExists: true, } } diff --git a/libbeat/idxmgmt/ilm/error.go b/libbeat/idxmgmt/ilm/error.go index a430ea87c4b0..b2e9830afd71 100644 --- a/libbeat/idxmgmt/ilm/error.go +++ b/libbeat/idxmgmt/ilm/error.go @@ -36,9 +36,6 @@ var ( ErrInvalidResponse = errors.New("invalid response received") ErrESILMDisabled = errors.New("ILM is disabled in Elasticsearch") ErrRequestFailed = errors.New("request failed") - ErrAliasAlreadyExists = errors.New("alias already exists") - ErrAliasCreateFailed = errors.New("failed to create write alias") - ErrInvalidAlias = errors.New("invalid alias") ErrOpNotAvailable = errors.New("operation not available") ) diff --git a/libbeat/idxmgmt/ilm/ilm.go b/libbeat/idxmgmt/ilm/ilm.go index a9e64e3cbd94..30d4e4f888ab 100644 --- a/libbeat/idxmgmt/ilm/ilm.go +++ b/libbeat/idxmgmt/ilm/ilm.go @@ -33,12 +33,11 @@ import ( // SupportFactory is used to define a policy type to be used. type SupportFactory func(*logp.Logger, beat.Info, *common.Config) (Supporter, error) -// Supporter implements ILM support. For loading the policies and creating -// write alias a manager instance must be generated. +// Supporter implements ILM support. For loading the policies +// a manager instance must be generated. type Supporter interface { // Query settings Enabled() bool - Alias() Alias Policy() Policy Overwrite() bool @@ -51,8 +50,6 @@ type Supporter interface { type Manager interface { CheckEnabled() (bool, error) - EnsureAlias() error - // EnsurePolicy installs a policy if it does not exist. The policy is always // written if overwrite is set. // The created flag is set to true only if a new policy is created. `created` @@ -67,12 +64,6 @@ type Policy struct { Body common.MapStr } -// Alias describes the alias to be created in Elasticsearch. -type Alias struct { - Name string - Pattern string -} - // DefaultSupport configures a new default ILM support implementation. func DefaultSupport(log *logp.Logger, info beat.Info, config *common.Config) (Supporter, error) { cfg := defaultConfig(info) @@ -109,16 +100,6 @@ func StdSupport(log *logp.Logger, info beat.Info, config *common.Config) (Suppor return nil, errors.Wrap(err, "failed to read ilm policy name") } - rolloverAlias, err := applyStaticFmtstr(info, &cfg.RolloverAlias) - if err != nil { - return nil, errors.Wrap(err, "failed to read the ilm rollover alias") - } - - alias := Alias{ - Name: rolloverAlias, - Pattern: cfg.Pattern, - } - policy := Policy{ Name: name, Body: DefaultPolicy, @@ -137,7 +118,7 @@ func StdSupport(log *logp.Logger, info beat.Info, config *common.Config) (Suppor policy.Body = body } - return NewStdSupport(log, cfg.Enabled, alias, policy, cfg.Overwrite, cfg.CheckExists), nil + return NewStdSupport(log, cfg.Enabled, policy, cfg.Overwrite, cfg.CheckExists), nil } // NoopSupport configures a new noop ILM support implementation, diff --git a/libbeat/idxmgmt/ilm/ilm_test.go b/libbeat/idxmgmt/ilm/ilm_test.go index 196b48e08ba0..d6e33c2a8920 100644 --- a/libbeat/idxmgmt/ilm/ilm_test.go +++ b/libbeat/idxmgmt/ilm/ilm_test.go @@ -31,28 +31,13 @@ import ( func TestDefaultSupport_Init(t *testing.T) { info := beat.Info{Beat: "test", Version: "9.9.9"} - t.Run("with an empty rollover_alias", func(t *testing.T) { - _, err := DefaultSupport(nil, info, common.MustNewConfigFrom( - map[string]interface{}{ - "enabled": true, - "rollover_alias": "", - "pattern": "01", - "check_exists": false, - "overwrite": true, - }, - )) - require.Error(t, err) - }) - t.Run("with custom config", func(t *testing.T) { tmp, err := DefaultSupport(nil, info, common.MustNewConfigFrom( map[string]interface{}{ - "enabled": true, - "name": "test-%{[agent.version]}", - "rollover_alias": "alias", - "pattern": "01", - "check_exists": false, - "overwrite": true, + "enabled": true, + "name": "test-%{[agent.version]}", + "check_exists": false, + "overwrite": true, }, )) require.NoError(t, err) @@ -63,17 +48,14 @@ func TestDefaultSupport_Init(t *testing.T) { assert.Equal(false, s.checkExists) assert.Equal(true, s.Enabled()) assert.Equal(DefaultPolicy, common.MapStr(s.Policy().Body)) - assert.Equal(Alias{Name: "alias", Pattern: "01"}, s.Alias()) }) t.Run("with custom alias config with fieldref", func(t *testing.T) { tmp, err := DefaultSupport(nil, info, common.MustNewConfigFrom( map[string]interface{}{ - "enabled": true, - "rollover_alias": "alias-%{[agent.version]}", - "pattern": "01", - "check_exists": false, - "overwrite": true, + "enabled": true, + "check_exists": false, + "overwrite": true, }, )) require.NoError(t, err) @@ -84,7 +66,6 @@ func TestDefaultSupport_Init(t *testing.T) { assert.Equal(false, s.checkExists) assert.Equal(true, s.Enabled()) assert.Equal(DefaultPolicy, common.MapStr(s.Policy().Body)) - assert.Equal(Alias{Name: "alias-9.9.9", Pattern: "01"}, s.Alias()) }) t.Run("with default alias", func(t *testing.T) { @@ -104,7 +85,6 @@ func TestDefaultSupport_Init(t *testing.T) { assert.Equal(false, s.checkExists) assert.Equal(true, s.Enabled()) assert.Equal(DefaultPolicy, common.MapStr(s.Policy().Body)) - assert.Equal(Alias{Name: "test-9.9.9", Pattern: "01"}, s.Alias()) }) t.Run("load external policy", func(t *testing.T) { @@ -146,13 +126,6 @@ func TestDefaultSupport_Manager_Enabled(t *testing.T) { cfg: map[string]interface{}{"enabled": true}, enabled: true, }, - "fail enabled": { - calls: []onCall{ - onCheckILMEnabled(true).Return(false, nil), - }, - cfg: map[string]interface{}{"enabled": true}, - fail: ErrESILMDisabled, - }, "io error": { calls: []onCall{ onCheckILMEnabled(true).Return(false, errors.New("ups")), @@ -189,80 +162,6 @@ func TestDefaultSupport_Manager_Enabled(t *testing.T) { } } -func TestDefaultSupport_Manager_EnsureAlias(t *testing.T) { - alias := Alias{ - Name: "test-9.9.9", - Pattern: ilmDefaultPattern, - } - - cases := map[string]struct { - calls []onCall - cfg map[string]interface{} - fail error - }{ - "create new alias": { - calls: []onCall{ - onHasAlias(alias.Name).Return(false, nil), - onCreateAlias(alias).Return(nil), - }, - }, - "alias already exists": { - calls: []onCall{ - onHasAlias(alias.Name).Return(true, nil), - }, - }, - "fail": { - calls: []onCall{ - onHasAlias(alias.Name).Return(false, nil), - onCreateAlias(alias).Return(errOf(ErrRequestFailed)), - }, - fail: ErrRequestFailed, - }, - "overwrite non-existent": { - calls: []onCall{ - onCreateAlias(alias).Return(nil), - }, - fail: nil, - cfg: map[string]interface{}{"check_exists": true, "overwrite": true}, - }, - "try overwrite existing": { - calls: []onCall{ - onCreateAlias(alias).Return(errOf(ErrAliasAlreadyExists)), - }, - fail: nil, // we detect that that the alias exists, and call it a day. - cfg: map[string]interface{}{"check_exists": true, "overwrite": true}, - }, - "fail to overwrite": { - calls: []onCall{ - onCreateAlias(alias).Return(errOf(ErrAliasCreateFailed)), - }, - fail: ErrAliasCreateFailed, - cfg: map[string]interface{}{"check_exists": true, "overwrite": true}, - }, - } - - for name, test := range cases { - t.Run(name, func(t *testing.T) { - cfg := test.cfg - if cfg == nil { - cfg = map[string]interface{}{"alias": "test"} - } - - h := newMockHandler(test.calls...) - m := createManager(t, h, test.cfg) - err := m.EnsureAlias() - - if test.fail == nil { - require.NoError(t, err) - } else { - require.Error(t, err) - assert.Equal(t, test.fail, ErrReason(err)) - } - h.AssertExpectations(t) - }) - } -} - func TestDefaultSupport_Manager_EnsurePolicy(t *testing.T) { testPolicy := Policy{ Name: "test", diff --git a/libbeat/idxmgmt/ilm/mockapihandler_test.go b/libbeat/idxmgmt/ilm/mockapihandler_test.go index 79148d83f1b2..b527ad118d72 100644 --- a/libbeat/idxmgmt/ilm/mockapihandler_test.go +++ b/libbeat/idxmgmt/ilm/mockapihandler_test.go @@ -50,18 +50,6 @@ func (h *mockHandler) CheckILMEnabled(enabled bool) (bool, error) { return args.Bool(0), args.Error(1) } -func onHasAlias(name string) onCall { return makeOnCall("HasAlias", name) } -func (h *mockHandler) HasAlias(name string) (bool, error) { - args := h.Called(name) - return args.Bool(0), args.Error(1) -} - -func onCreateAlias(alias Alias) onCall { return makeOnCall("CreateAlias", alias) } -func (h *mockHandler) CreateAlias(alias Alias) error { - args := h.Called(alias) - return args.Error(0) -} - func onHasILMPolicy(name string) onCall { return makeOnCall("HasILMPolicy", name) } func (h *mockHandler) HasILMPolicy(name string) (bool, error) { args := h.Called(name) diff --git a/libbeat/idxmgmt/ilm/noop.go b/libbeat/idxmgmt/ilm/noop.go index 20586a261d3c..a06c173d5670 100644 --- a/libbeat/idxmgmt/ilm/noop.go +++ b/libbeat/idxmgmt/ilm/noop.go @@ -26,17 +26,15 @@ type noopSupport struct{} type noopManager struct{} // NewNoopSupport creates a noop ILM implementation with ILM support being always -// disabled. Attempts to install a policy or create a write alias will fail. +// disabled. Attempts to install a policy will fail. func NewNoopSupport(info beat.Info, config *common.Config) (Supporter, error) { return (*noopSupport)(nil), nil } func (*noopSupport) Enabled() bool { return false } -func (*noopSupport) Alias() Alias { return Alias{} } func (*noopSupport) Policy() Policy { return Policy{} } func (*noopSupport) Overwrite() bool { return false } func (*noopSupport) Manager(_ ClientHandler) Manager { return (*noopManager)(nil) } func (*noopManager) CheckEnabled() (bool, error) { return false, nil } -func (*noopManager) EnsureAlias() error { return errOf(ErrOpNotAvailable) } func (*noopManager) EnsurePolicy(_ bool) (bool, error) { return false, errOf(ErrOpNotAvailable) } diff --git a/libbeat/idxmgmt/ilm/std.go b/libbeat/idxmgmt/ilm/std.go index 6363898a0a12..ef8a11f7f210 100644 --- a/libbeat/idxmgmt/ilm/std.go +++ b/libbeat/idxmgmt/ilm/std.go @@ -30,7 +30,6 @@ type stdSupport struct { overwrite bool checkExists bool - alias Alias policy Policy } @@ -53,7 +52,6 @@ var defaultCacheDuration = 5 * time.Minute func NewStdSupport( log *logp.Logger, enabled bool, - alias Alias, policy Policy, overwrite, checkExists bool, ) Supporter { @@ -62,13 +60,11 @@ func NewStdSupport( enabled: enabled, overwrite: overwrite, checkExists: checkExists, - alias: alias, policy: policy, } } func (s *stdSupport) Enabled() bool { return s.enabled } -func (s *stdSupport) Alias() Alias { return s.alias } func (s *stdSupport) Policy() Policy { return s.policy } func (s *stdSupport) Overwrite() bool { return s.overwrite } @@ -93,59 +89,11 @@ func (m *stdManager) CheckEnabled() (bool, error) { return ilmEnabled, err } - if !ilmEnabled && m.enabled { - return false, errOf(ErrESILMDisabled) - } - m.cache.Enabled = ilmEnabled m.cache.LastUpdate = time.Now() return ilmEnabled, nil } -func (m *stdManager) EnsureAlias() error { - log := m.log - if !m.checkExists { - log.Infof("Index alias is not checked as setup.ilm.check_exists is disabled") - return nil - } - - overwrite := m.Overwrite() - name := m.alias.Name - - var exists bool - if !overwrite { - var err error - exists, err = m.client.HasAlias(name) - if err != nil { - return err - } - } - - switch { - case exists && !overwrite: - log.Infof("Index Alias %v exists already.", name) - return nil - - case !exists || overwrite: - err := m.client.CreateAlias(m.alias) - if err != nil { - if ErrReason(err) != ErrAliasAlreadyExists { - log.Errorf("Index Alias %v setup failed: %v.", name, err) - return err - } - log.Infof("Index Alias %v exists already.", name) - return nil - } - - log.Infof("Index Alias %v successfully created.", name) - return nil - - default: - m.log.Infof("ILM index alias not created: exists=%v, overwrite=%v", exists, overwrite) - return nil - } -} - func (m *stdManager) EnsurePolicy(overwrite bool) (bool, error) { log := m.log if !m.checkExists { diff --git a/libbeat/idxmgmt/mockilm_test.go b/libbeat/idxmgmt/mockilm_test.go index d138b46e6a04..05ebbe873532 100644 --- a/libbeat/idxmgmt/mockilm_test.go +++ b/libbeat/idxmgmt/mockilm_test.go @@ -57,12 +57,6 @@ func (m *mockILMSupport) Enabled() bool { return args.Get(0).(bool) } -func onAlias() onCall { return makeOnCall("Alias") } -func (m *mockILMSupport) Alias() ilm.Alias { - args := m.Called() - return args.Get(0).(ilm.Alias) -} - func onPolicy() onCall { return makeOnCall("Policy") } func (m *mockILMSupport) Policy() ilm.Policy { args := m.Called() @@ -84,12 +78,6 @@ func (m *mockILMSupport) CheckEnabled() (bool, error) { return args.Bool(0), args.Error(1) } -func onEnsureAlias() onCall { return makeOnCall("EnsureAlias") } -func (m *mockILMSupport) EnsureAlias() error { - args := m.Called() - return args.Error(0) -} - func onEnsurePolicy() onCall { return makeOnCall("EnsurePolicy") } func (m *mockILMSupport) EnsurePolicy(overwrite bool) (bool, error) { args := m.Called() diff --git a/libbeat/idxmgmt/std.go b/libbeat/idxmgmt/std.go index 6cca4dad6833..e32fdfd647ca 100644 --- a/libbeat/idxmgmt/std.go +++ b/libbeat/idxmgmt/std.go @@ -63,7 +63,6 @@ type indexSelector struct { type ilmIndexSelector struct { index outil.Selector - alias outil.Selector st *indexState beatInfo beat.Info } @@ -112,7 +111,7 @@ func newIndexSupport( return nil, err } - tmplCfg, err := unpackTemplateConfig(tmplConfig) + tmplCfg, err := unpackTemplateConfig(info, tmplConfig) if err != nil { return nil, err } @@ -123,7 +122,7 @@ func newIndexSupport( info: info, templateCfg: tmplCfg, migration: migration, - defaultIndex: fmt.Sprintf("%v-%v-%%{+yyyy.MM.dd}", info.IndexPrefix, info.Version), + defaultIndex: fmt.Sprintf("%v-%v", info.IndexPrefix, info.Version), }, nil } @@ -155,8 +154,6 @@ func (s *indexSupport) Manager( func (s *indexSupport) BuildSelector(cfg *common.Config) (outputs.IndexSelector, error) { var err error - log := s.log - // we construct our own configuration object based on the available settings // in cfg and defaultIndex. The configuration object provided must not be // modified. @@ -177,12 +174,6 @@ func (s *indexSupport) BuildSelector(cfg *common.Config) (outputs.IndexSelector, } } - if s.ilm.Enabled() { - alias := s.ilm.Alias().Name - log.Infof("Set %v to '%s' as ILM is enabled.", cfg.PathOf("index"), alias) - indexName = alias - } - // no index name configuration found yet -> define default index name based on // beat.Info provided to the indexSupport on during setup. if indexName == "" { @@ -213,19 +204,18 @@ func (m *indexManager) VerifySetup(loadTemplate, loadILM LoadMode) (bool, string m.support.templateCfg.Overwrite, loadTemplate) if ilmComponent.load && !templateComponent.load { - return false, "Loading ILM policy and write alias without loading template " + - "is not recommended. Check your configuration." + return false, "Loading ILM policy without loading template is not recommended. Check your configuration." } if templateComponent.load && !ilmComponent.load && ilmComponent.enabled { return false, "Loading template with ILM settings whithout loading ILM " + - "policy and alias can lead to issues and is not recommended. " + + "policy can lead to issues and is not recommended. " + "Check your configuration." } var warn string if !ilmComponent.load { - warn += "ILM policy and write alias loading not enabled.\n" + warn += "ILM policy loading not enabled.\n" } else if !ilmComponent.overwrite { warn += "Overwriting ILM policy is disabled. Set `setup.ilm.overwrite: true` for enabling.\n" } @@ -243,7 +233,7 @@ func (m *indexManager) Setup(loadTemplate, loadILM LoadMode) error { if err != nil { return err } - if withILM && loadILM.Enabled() { + if withILM { log.Info("Auto ILM enable success.") } @@ -269,7 +259,7 @@ func (m *indexManager) Setup(loadTemplate, loadILM LoadMode) error { tmplCfg.Overwrite, tmplCfg.Enabled = templateComponent.overwrite, templateComponent.enabled if ilmComponent.enabled { - tmplCfg, err = applyILMSettings(log, tmplCfg, m.support.ilm.Policy(), m.support.ilm.Alias()) + tmplCfg, err = applyILMSettings(log, tmplCfg, m.support.ilm.Policy()) if err != nil { return err } @@ -283,13 +273,6 @@ func (m *indexManager) Setup(loadTemplate, loadILM LoadMode) error { log.Info("Loaded index template.") } - if ilmComponent.load { - err := m.ilm.EnsureAlias() - if err != nil { - return err - } - } - return nil } @@ -314,11 +297,6 @@ func (s *ilmIndexSelector) Select(evt *beat.Event) (string, error) { return idx, nil } - if s.st.withILM.Load() { - idx, err := s.alias.Select(evt) - return idx, err - } - idx, err := s.index.Select(evt) return idx, err } @@ -335,10 +313,6 @@ func getEventCustomIndex(evt *beat.Event, beatInfo beat.Info) string { return "" } - if alias, err := events.GetMetaStringValue(*evt, events.FieldMetaAlias); err == nil { - return strings.ToLower(alias) - } - if idx, err := events.GetMetaStringValue(*evt, events.FieldMetaIndex); err == nil { ts := evt.Timestamp.UTC() return fmt.Sprintf("%s-%d.%02d.%02d", @@ -356,8 +330,9 @@ func getEventCustomIndex(evt *beat.Event, beatInfo beat.Info) string { return "" } -func unpackTemplateConfig(cfg *common.Config) (config template.TemplateConfig, err error) { - config = template.DefaultConfig() +func unpackTemplateConfig(info beat.Info, cfg *common.Config) (config template.TemplateConfig, err error) { + config = template.DefaultConfig(info) + if cfg != nil { err = cfg.Unpack(&config) } @@ -368,32 +343,15 @@ func applyILMSettings( log *logp.Logger, tmpl template.TemplateConfig, policy ilm.Policy, - alias ilm.Alias, ) (template.TemplateConfig, error) { if !tmpl.Enabled { return tmpl, nil } - if alias.Name == "" { - return tmpl, errors.New("no ilm rollover alias configured") - } - if policy.Name == "" { return tmpl, errors.New("no ilm policy name configured") } - tmpl.Name = alias.Name - if log != nil { - log.Infof("Set setup.template.name to '%s' as ILM is enabled.", alias) - } - - tmpl.Pattern = fmt.Sprintf("%s-*", alias.Name) - if log != nil { - log.Infof("Set setup.template.pattern to '%s' as ILM is enabled.", tmpl.Pattern) - } - - // rollover_alias and lifecycle.name can't be configured and will be overwritten - // init/copy index settings idxSettings := tmpl.Settings.Index if idxSettings == nil { @@ -421,11 +379,6 @@ func applyILMSettings( } idxSettings["lifecycle"] = lifecycle - // add rollover_alias and name to index.lifecycle settings - if _, exists := lifecycle["rollover_alias"]; !exists { - log.Infof("Set settings.index.lifecycle.rollover_alias in template to %s as ILM is enabled.", alias) - lifecycle["rollover_alias"] = alias.Name - } if _, exists := lifecycle["name"]; !exists { log.Infof("Set settings.index.lifecycle.name in template to %s as ILM is enabled.", policy) lifecycle["name"] = policy.Name diff --git a/libbeat/idxmgmt/std_test.go b/libbeat/idxmgmt/std_test.go index 76b0ac9879ed..4a7a4c848cbe 100644 --- a/libbeat/idxmgmt/std_test.go +++ b/libbeat/idxmgmt/std_test.go @@ -33,7 +33,7 @@ import ( ) type mockClientHandler struct { - alias, policy string + policy string expectsPolicy bool tmplCfg *template.TemplateConfig @@ -47,7 +47,6 @@ type mockCreateOp uint8 const ( mockCreatePolicy mockCreateOp = iota mockCreateTemplate - mockCreateAlias ) func TestDefaultSupport_Enabled(t *testing.T) { @@ -99,10 +98,9 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { type nameFunc func(time.Time) string noILM := []onCall{onEnabled().Return(false)} - ilmTemplateSettings := func(alias, policy string) []onCall { + ilmTemplateSettings := func(policy string) []onCall { return []onCall{ onEnabled().Return(true), - onAlias().Return(ilm.Alias{Name: alias}), onPolicy().Return(ilm.Policy{Name: policy}), } } @@ -135,22 +133,6 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { cfg: map[string]interface{}{"index": "TeSt-%{[agent.version]}"}, want: stable("test-9.9.9"), }, - "event alias without ilm": { - ilmCalls: noILM, - cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: stable("test"), - meta: common.MapStr{ - "alias": "test", - }, - }, - "event alias without ilm must be lowercae": { - ilmCalls: noILM, - cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: stable("test"), - meta: common.MapStr{ - "alias": "Test", - }, - }, "event index without ilm": { ilmCalls: noILM, cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, @@ -168,33 +150,17 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { }, }, "with ilm": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), - cfg: map[string]interface{}{"index": "wrong-%{[agent.version]}"}, + ilmCalls: ilmTemplateSettings("test-9.9.9"), + cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, want: stable("test-9.9.9"), }, "with ilm must be lowercase": { - ilmCalls: ilmTemplateSettings("Test-9.9.9", "Test-9.9.9"), - cfg: map[string]interface{}{"index": "wrong-%{[agent.version]}"}, - want: stable("test-9.9.9"), - }, - "event alias wit ilm": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), + ilmCalls: ilmTemplateSettings("Test-9.9.9"), cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: stable("event-alias"), - meta: common.MapStr{ - "alias": "event-alias", - }, - }, - "event alias wit ilm must be lowercase": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), - cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: stable("event-alias"), - meta: common.MapStr{ - "alias": "Event-alias", - }, + want: stable("test-9.9.9"), }, "event index with ilm": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), + ilmCalls: ilmTemplateSettings("test-9.9.9"), cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, want: dateIdx("event-index"), meta: common.MapStr{ @@ -202,7 +168,7 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { }, }, "use indices": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), + ilmCalls: ilmTemplateSettings("test-9.9.9"), cfg: map[string]interface{}{ "index": "test-%{[agent.version]}", "indices": []map[string]interface{}{ @@ -212,7 +178,7 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { want: stable("myindex"), }, "use indices settings must be lowercase": { - ilmCalls: ilmTemplateSettings("test-9.9.9", "test-9.9.9"), + ilmCalls: ilmTemplateSettings("test-9.9.9"), cfg: map[string]interface{}{ "index": "test-%{[agent.version]}", "indices": []map[string]interface{}{ @@ -260,7 +226,7 @@ func TestIndexManager_VerifySetup(t *testing.T) { }{ "load template with ilm without loading ilm": { ilmEnabled: true, tmplEnabled: true, loadILM: LoadModeDisabled, - warn: "whithout loading ILM policy and alias", + warn: "whithout loading ILM policy", }, "load ilm without template": { ilmEnabled: true, loadILM: LoadModeUnset, @@ -346,40 +312,36 @@ func TestIndexManager_Setup(t *testing.T) { } return &s } - defaultCfg := template.DefaultConfig() + info := beat.Info{Beat: "test", Version: "9.9.9"} + defaultCfg := template.DefaultConfig(info) cases := map[string]struct { cfg common.MapStr loadTemplate, loadILM LoadMode - err bool - tmplCfg *template.TemplateConfig - alias, policy string + err bool + tmplCfg *template.TemplateConfig + policy string }{ "template default ilm default": { - tmplCfg: cfgWith(template.DefaultConfig(), map[string]interface{}{ + tmplCfg: cfgWith(template.DefaultConfig(info), map[string]interface{}{ "overwrite": "true", "name": "test-9.9.9", - "pattern": "test-9.9.9-*", + "pattern": "test-9.9.9", "settings.index.lifecycle.name": "test", - "settings.index.lifecycle.rollover_alias": "test-9.9.9", }), - alias: "test-9.9.9", policy: "test", }, - "template default ilm default with alias and policy changed": { + "template default ilm default with policy changed": { cfg: common.MapStr{ - "setup.ilm.rollover_alias": "mocktest", - "setup.ilm.policy_name": "policy-keep", + "setup.ilm.policy_name": "policy-keep", }, - tmplCfg: cfgWith(template.DefaultConfig(), map[string]interface{}{ + tmplCfg: cfgWith(template.DefaultConfig(info), map[string]interface{}{ "overwrite": "true", - "name": "mocktest", - "pattern": "mocktest-*", + "name": "test-9.9.9", + "pattern": "test-9.9.9", "settings.index.lifecycle.name": "policy-keep", - "settings.index.lifecycle.rollover_alias": "mocktest", }), - alias: "mocktest", policy: "policy-keep", }, "template default ilm disabled": { @@ -394,16 +356,20 @@ func TestIndexManager_Setup(t *testing.T) { "setup.ilm.enabled": false, }, loadTemplate: LoadModeOverwrite, - tmplCfg: cfgWith(template.DefaultConfig(), map[string]interface{}{ + tmplCfg: cfgWith(template.DefaultConfig(info), map[string]interface{}{ "overwrite": "true", + "name": "test-9.9.9", + "pattern": "test-9.9.9", }), }, "template default loadMode Force ilm disabled": { cfg: common.MapStr{ "setup.ilm.enabled": false, + "name": "test-9.9.9", + "pattern": "test-9.9.9", }, loadTemplate: LoadModeForce, - tmplCfg: cfgWith(template.DefaultConfig(), map[string]interface{}{ + tmplCfg: cfgWith(template.DefaultConfig(info), map[string]interface{}{ "overwrite": "true", }), }, @@ -417,7 +383,6 @@ func TestIndexManager_Setup(t *testing.T) { cfg: common.MapStr{ "setup.template.enabled": false, }, - alias: "test-9.9.9", policy: "test", }, "template disabled ilm disabled, loadMode Overwrite": { @@ -433,22 +398,19 @@ func TestIndexManager_Setup(t *testing.T) { "setup.ilm.enabled": false, }, loadILM: LoadModeForce, - alias: "test-9.9.9", policy: "test", }, "template loadmode disabled ilm loadMode enabled": { loadTemplate: LoadModeDisabled, loadILM: LoadModeEnabled, - alias: "test-9.9.9", policy: "test", }, "template default ilm loadMode disabled": { loadILM: LoadModeDisabled, - tmplCfg: cfgWith(template.DefaultConfig(), map[string]interface{}{ + tmplCfg: cfgWith(template.DefaultConfig(info), map[string]interface{}{ "name": "test-9.9.9", - "pattern": "test-9.9.9-*", + "pattern": "test-9.9.9", "settings.index.lifecycle.name": "test", - "settings.index.lifecycle.rollover_alias": "test-9.9.9", }), }, "template loadmode disabled ilm loadmode disabled": { @@ -458,7 +420,6 @@ func TestIndexManager_Setup(t *testing.T) { } for name, test := range cases { t.Run(name, func(t *testing.T) { - info := beat.Info{Beat: "test", Version: "9.9.9"} factory := MakeDefaultSupport(ilm.StdSupport) im, err := factory(nil, info, common.MustNewConfigFrom(test.cfg)) require.NoError(t, err) @@ -477,7 +438,6 @@ func TestIndexManager_Setup(t *testing.T) { } else { assert.Equal(t, test.tmplCfg, clientHandler.tmplCfg) } - assert.Equal(t, test.alias, clientHandler.alias) assert.Equal(t, test.policy, clientHandler.policy) } }) @@ -485,7 +445,7 @@ func TestIndexManager_Setup(t *testing.T) { } func (op mockCreateOp) String() string { - names := []string{"create-policy", "create-template", "create-alias"} + names := []string{"create-policy", "create-template"} if int(op) > len(names) { return "unknown" } @@ -507,16 +467,6 @@ func (h *mockClientHandler) CheckILMEnabled(enabled bool) (bool, error) { return enabled, nil } -func (h *mockClientHandler) HasAlias(name string) (bool, error) { - return h.alias == name, nil -} - -func (h *mockClientHandler) CreateAlias(alias ilm.Alias) error { - h.recordOp(mockCreateAlias) - h.alias = alias.Name - return nil -} - func (h *mockClientHandler) HasILMPolicy(name string) (bool, error) { return h.policy == name, nil } diff --git a/libbeat/publisher/processing/processors.go b/libbeat/publisher/processing/processors.go index 19111b6aff95..cac9d356153a 100644 --- a/libbeat/publisher/processing/processors.go +++ b/libbeat/publisher/processing/processors.go @@ -21,6 +21,7 @@ import ( "fmt" "strings" "sync" + "time" "github.com/joeshaw/multierror" @@ -51,6 +52,11 @@ func newGeneralizeProcessor(keepNull bool) *processorFn { return nil, nil } + // data streams require @timestamp field + if event.Timestamp.IsZero() { + event.Timestamp = time.Now() + } + fields := g.Convert(event.Fields) if fields == nil { logger.Error("fail to convert to generic event") diff --git a/libbeat/template/config.go b/libbeat/template/config.go index 7eb6ff522f46..4f9fe2348c7d 100644 --- a/libbeat/template/config.go +++ b/libbeat/template/config.go @@ -18,27 +18,10 @@ package template import ( - "fmt" - + "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/mapping" ) -const ( - IndexTemplateLegacy IndexTemplateType = iota - IndexTemplateComponent - IndexTemplateIndex -) - -var ( - templateTypes = map[string]IndexTemplateType{ - "legacy": IndexTemplateLegacy, - "component": IndexTemplateComponent, - "index": IndexTemplateIndex, - } -) - -type IndexTemplateType uint8 - // TemplateConfig holds config information about the Elasticsearch template type TemplateConfig struct { Enabled bool `config:"enabled"` @@ -50,12 +33,10 @@ type TemplateConfig struct { Path string `config:"path"` Name string `config:"name"` } `config:"json"` - AppendFields mapping.Fields `config:"append_fields"` - Overwrite bool `config:"overwrite"` - Settings TemplateSettings `config:"settings"` - Order int `config:"order"` - Priority int `config:"priority"` - Type IndexTemplateType `config:"type"` + AppendFields mapping.Fields `config:"append_fields"` + Overwrite bool `config:"overwrite"` + Settings TemplateSettings `config:"settings"` + Priority int `config:"priority"` } // TemplateSettings are part of the Elasticsearch template and hold index and source specific information. @@ -65,28 +46,12 @@ type TemplateSettings struct { } // DefaultConfig for index template -func DefaultConfig() TemplateConfig { +func DefaultConfig(info beat.Info) TemplateConfig { return TemplateConfig{ + Name: info.Beat + "-" + info.Version, + Pattern: info.Beat + "-" + info.Version, Enabled: true, Fields: "", - Type: IndexTemplateLegacy, - Order: 1, Priority: 150, } } - -func (t *IndexTemplateType) Unpack(v string) error { - if v == "" { - *t = IndexTemplateLegacy - return nil - } - - var tt IndexTemplateType - var ok bool - if tt, ok = templateTypes[v]; !ok { - return fmt.Errorf("unknown index template type: %s", v) - } - *t = tt - - return nil -} diff --git a/libbeat/template/load.go b/libbeat/template/load.go index 0ecbc291268e..1900d8f5a75a 100644 --- a/libbeat/template/load.go +++ b/libbeat/template/load.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "net/http" "os" - "strings" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" @@ -32,14 +31,6 @@ import ( "github.com/elastic/beats/v7/libbeat/paths" ) -var ( - templateLoaderPath = map[IndexTemplateType]string{ - IndexTemplateLegacy: "/_template/", - IndexTemplateComponent: "/_component_template/", - IndexTemplateIndex: "/_index_template/", - } -) - // Loader interface for loading templates. type Loader interface { Load(config TemplateConfig, info beat.Info, fields []byte, migration bool) error @@ -114,7 +105,7 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi templateName = config.JSON.Name } - exists, err := l.templateExists(templateName, config.Type) + exists, err := l.checkExistsTemplate(templateName) if err != nil { return fmt.Errorf("failure while checking if template exists: %w", err) } @@ -129,7 +120,7 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi if err != nil { return err } - if err := l.loadTemplate(templateName, config.Type, body); err != nil { + if err := l.loadTemplate(templateName, body); err != nil { return fmt.Errorf("failed to load template: %w", err) } l.log.Infof("Template with name %q loaded.", templateName) @@ -139,12 +130,10 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi // loadTemplate loads a template into Elasticsearch overwriting the existing // template if it exists. If you wish to not overwrite an existing template // then use CheckTemplate prior to calling this method. -func (l *ESLoader) loadTemplate(templateName string, templateType IndexTemplateType, template map[string]interface{}) error { +func (l *ESLoader) loadTemplate(templateName string, template map[string]interface{}) error { l.log.Infof("Try loading template %s to Elasticsearch", templateName) - clientVersion := l.client.GetVersion() - path := templateLoaderPath[templateType] + templateName - params := esVersionParams(clientVersion) - status, body, err := l.client.Request("PUT", path, "", params, template) + path := "/_index_template/" + templateName + status, body, err := l.client.Request("PUT", path, "", nil, template) if err != nil { return fmt.Errorf("couldn't load template: %v. Response body: %s", err, body) } @@ -154,52 +143,21 @@ func (l *ESLoader) loadTemplate(templateName string, templateType IndexTemplateT return nil } -func (l *ESLoader) templateExists(templateName string, templateType IndexTemplateType) (bool, error) { - if templateType == IndexTemplateComponent { - return l.checkExistsComponentTemplate(templateName) - } - return l.checkExistsTemplate(templateName) -} - // existsTemplate checks if a given template already exist, using the -// `_cat/templates/` API. +// `/_index_template/` API. // // An error is returned if the loader failed to execute the request, or a // status code indicating some problems is encountered. func (l *ESLoader) checkExistsTemplate(name string) (bool, error) { - status, body, err := l.client.Request("GET", "/_cat/templates/"+name, "", nil, nil) + status, _, err := l.client.Request("HEAD", "/_index_template/"+name, "", nil, nil) + if status == http.StatusNotFound { + return false, nil + } if err != nil { return false, err } - // Elasticsearch API returns 200, even if the template does not exists. We - // need to validate the body to be sure the template is actually known. Any - // status code other than 200 will be treated as error. - if status != http.StatusOK { - return false, &StatusError{status: status} - } - return strings.Contains(string(body), name), nil -} - -// existsComponentTemplate checks if a component template exists by querying -// the `_component_template/` API. -// -// The resource is assumed as present if a 200 OK status is returned and missing if a 404 is returned. -// Other status codes or IO errors during the request are reported as error. -func (l *ESLoader) checkExistsComponentTemplate(name string) (bool, error) { - status, _, err := l.client.Request("GET", "/_component_template/"+name, "", nil, nil) - - switch status { - case http.StatusNotFound: - return false, nil - case http.StatusOK: - return true, nil - default: - if err == nil { - err = &StatusError{status: status} - } - return false, err - } + return true, nil } // Load reads the template from the config, creates the template body and prints it to the configured file. @@ -247,7 +205,8 @@ func (b *templateBuilder) buildBody(tmpl *Template, config TemplateConfig, field return b.buildBodyFromFile(tmpl, config) } if fields == nil { - return b.buildMinimalTemplate(tmpl) + b.log.Debug("Load minimal template") + return tmpl.LoadMinimal(), nil } return b.buildBodyFromFields(tmpl, fields) } @@ -290,25 +249,6 @@ func (b *templateBuilder) buildBodyFromFields(tmpl *Template, fields []byte) (co return body, nil } -func (b *templateBuilder) buildMinimalTemplate(tmpl *Template) (common.MapStr, error) { - b.log.Debug("Load minimal template") - body, err := tmpl.LoadMinimal() - if err != nil { - return nil, fmt.Errorf("error creating mimimal template: %v", err) - } - return body, nil -} - func (e *StatusError) Error() string { return fmt.Sprintf("request failed with http status code %v", e.status) } - -func esVersionParams(ver common.Version) map[string]string { - if ver.Major == 6 && ver.Minor == 7 { - return map[string]string{ - "include_type_name": "true", - } - } - - return nil -} diff --git a/libbeat/template/load_integration_test.go b/libbeat/template/load_integration_test.go index 371991810e47..07caf39c3e75 100644 --- a/libbeat/template/load_integration_test.go +++ b/libbeat/template/load_integration_test.go @@ -67,13 +67,13 @@ func newTestSetup(t *testing.T, cfg TemplateConfig) *testSetup { t.Fatal(err) } s := testSetup{t: t, client: client, loader: NewESLoader(client), config: cfg} - client.Request("DELETE", templateLoaderPath[cfg.Type]+cfg.Name, "", nil, nil) + client.Request("DELETE", "/_index_template/"+cfg.Name, "", nil, nil) s.requireTemplateDoesNotExist("") return &s } func (ts *testSetup) mustLoadTemplate(body map[string]interface{}) { - err := ts.loader.loadTemplate(ts.config.Name, ts.config.Type, body) + err := ts.loader.loadTemplate(ts.config.Name, body) require.NoError(ts.t, err) ts.requireTemplateExists("") } @@ -103,16 +103,21 @@ func (ts *testSetup) requireTemplateExists(name string) { if name == "" { name = ts.config.Name } - exists, err := ts.loader.templateExists(name, ts.config.Type) + exists, err := ts.loader.checkExistsTemplate(name) require.NoError(ts.t, err, "failed to query template status") - require.True(ts.t, exists, "template must exist") + require.True(ts.t, exists, "template must exist: %s", name) +} + +func (ts *testSetup) cleanupTemplate(name string) { + ts.client.Request("DELETE", "/_index_template/"+name, "", nil, nil) + ts.requireTemplateDoesNotExist(name) } func (ts *testSetup) requireTemplateDoesNotExist(name string) { if name == "" { name = ts.config.Name } - exists, err := ts.loader.templateExists(name, ts.config.Type) + exists, err := ts.loader.checkExistsTemplate(name) require.NoError(ts.t, err, "failed to query template status") require.False(ts.t, exists, "template must not exist") } @@ -146,14 +151,14 @@ func TestESLoader_Load(t *testing.T) { t.Run("disabled", func(t *testing.T) { setup.load(nil) - tmpl := getTemplate(t, setup.client, setup.config.Name, setup.config.Type) + tmpl := getTemplate(t, setup.client, setup.config.Name) assert.Equal(t, true, tmpl.SourceEnabled()) }) t.Run("enabled", func(t *testing.T) { setup.config.Overwrite = true setup.load(nil) - tmpl := getTemplate(t, setup.client, setup.config.Name, setup.config.Type) + tmpl := getTemplate(t, setup.client, setup.config.Name) assert.Equal(t, false, tmpl.SourceEnabled()) }) }) @@ -172,6 +177,7 @@ func TestESLoader_Load(t *testing.T) { }{Enabled: true, Path: path(t, []string{"testdata", "fields.json"}), Name: nameJSON} setup.load(nil) setup.requireTemplateExists(nameJSON) + setup.cleanupTemplate(nameJSON) }) t.Run("load template successful", func(t *testing.T) { @@ -188,26 +194,17 @@ func TestESLoader_Load(t *testing.T) { fields: fields, properties: []string{"foo", "bar"}, }, - "default config with fields and component": { - cfg: TemplateConfig{Enabled: true, Type: IndexTemplateComponent}, - fields: fields, - properties: []string{"foo", "bar"}, - }, "minimal template": { cfg: TemplateConfig{Enabled: true}, fields: nil, }, - "minimal template component": { - cfg: TemplateConfig{Enabled: true, Type: IndexTemplateComponent}, - fields: nil, - }, "fields from file": { cfg: TemplateConfig{Enabled: true, Fields: path(t, []string{"testdata", "fields.yml"})}, fields: fields, - properties: []string{"object", "keyword", "alias", "migration_alias_false", "object_disabled"}, + properties: []string{"object", "keyword", "alias", "migration_alias_false", "object_disabled", "@timestamp"}, }, "fields from json": { - cfg: TemplateConfig{Enabled: true, Name: "json-template", JSON: struct { + cfg: TemplateConfig{Enabled: true, JSON: struct { Enabled bool `config:"enabled"` Path string `config:"path"` Name string `config:"name"` @@ -217,12 +214,15 @@ func TestESLoader_Load(t *testing.T) { }, } { t.Run(run, func(t *testing.T) { + if data.cfg.JSON.Enabled { + data.cfg.Name = data.cfg.JSON.Name + } setup := newTestSetup(t, data.cfg) setup.mustLoad(data.fields) // Fetch properties - tmpl := getTemplate(t, setup.client, setup.config.Name, setup.config.Type) - val, err := tmpl.GetValue("mappings.properties") + tmpl := getTemplate(t, setup.client, setup.config.Name) + val, err := tmpl.GetValue("template.mappings.properties") if data.properties == nil { assert.Error(t, err) } else { @@ -235,6 +235,7 @@ func TestESLoader_Load(t *testing.T) { } assert.ElementsMatch(t, properties, data.properties) } + setup.cleanupTemplate(setup.config.Name) }) } }) @@ -250,7 +251,7 @@ func TestLoadInvalidTemplate(t *testing.T) { // Try to load invalid template template := map[string]interface{}{"json": "invalid"} - err := setup.loader.loadTemplate(setup.config.Name, setup.config.Type, template) + err := setup.loader.loadTemplate(setup.config.Name, template) assert.Error(t, err) setup.requireTemplateDoesNotExist("") } @@ -276,7 +277,7 @@ func TestTemplateSettings(t *testing.T) { setup.mustLoadFromFile([]string{"..", "fields.yml"}) // Check that it contains the mapping - templateJSON := getTemplate(t, setup.client, setup.config.Name, setup.config.Type) + templateJSON := getTemplate(t, setup.client, setup.config.Name) assert.Equal(t, 1, templateJSON.NumberOfShards()) assert.Equal(t, false, templateJSON.SourceEnabled()) } @@ -287,8 +288,9 @@ var dataTests = []struct { }{ { data: common.MapStr{ - "keyword": "test keyword", - "array": [...]int{1, 2, 3}, + "@timestamp": time.Now(), + "keyword": "test keyword", + "array": [...]int{1, 2, 3}, "object": common.MapStr{ "hello": "world", }, @@ -314,6 +316,7 @@ var dataTests = []struct { { // tests enabled: false values data: common.MapStr{ + "@timestamp": time.Now(), "array_disabled": [...]int{1, 2, 3}, "object_disabled": common.MapStr{ "hello": "world", @@ -340,8 +343,8 @@ func TestTemplateWithData(t *testing.T) { } } -func getTemplate(t *testing.T, client ESClient, templateName string, templateType IndexTemplateType) testTemplate { - status, body, err := client.Request("GET", templateLoaderPath[templateType]+templateName, "", nil, nil) +func getTemplate(t *testing.T, client ESClient, templateName string) testTemplate { + status, body, err := client.Request("GET", "/_index_template/"+templateName, "", nil, nil) require.NoError(t, err) require.Equal(t, status, 200) @@ -350,29 +353,19 @@ func getTemplate(t *testing.T, client ESClient, templateName string, templateTyp require.NoError(t, err) require.NotNil(t, response) - if templateType == IndexTemplateComponent { - var tmpl map[string]interface{} - components := response["component_templates"].([]interface{}) - for _, ct := range components { - componentTemplate := ct.(map[string]interface{})["component_template"].(map[string]interface{}) - tmpl = componentTemplate["template"].(map[string]interface{}) - } - return testTemplate{ - t: t, - client: client, - MapStr: common.MapStr(tmpl), - } - } + templates, _ := response.GetValue("index_templates") + templatesList, _ := templates.([]interface{}) + templateElem := templatesList[0].(map[string]interface{}) return testTemplate{ t: t, client: client, - MapStr: common.MapStr(response[templateName].(map[string]interface{})), + MapStr: common.MapStr(templateElem["index_template"].(map[string]interface{})), } } func (tt *testTemplate) SourceEnabled() bool { - key := fmt.Sprintf("mappings._source.enabled") + key := fmt.Sprintf("template.mappings._source.enabled") // _source.enabled is true if it's missing (default) b, _ := tt.HasKey(key) @@ -390,7 +383,7 @@ func (tt *testTemplate) SourceEnabled() bool { } func (tt *testTemplate) NumberOfShards() int { - val, err := tt.GetValue("settings.index.number_of_shards") + val, err := tt.GetValue("template.settings.index.number_of_shards") require.NoError(tt.t, err) i, err := strconv.Atoi(val.(string)) diff --git a/libbeat/template/load_test.go b/libbeat/template/load_test.go index 017f53639fa4..429cf7382ab7 100644 --- a/libbeat/template/load_test.go +++ b/libbeat/template/load_test.go @@ -32,8 +32,7 @@ import ( func TestFileLoader_Load(t *testing.T) { ver := "7.0.0" prefix := "mock" - order := 1 - info := beat.Info{Version: ver, IndexPrefix: prefix} + info := beat.Info{Beat: "mock", Version: ver, IndexPrefix: prefix} tmplName := fmt.Sprintf("%s-%s", prefix, ver) for name, test := range map[string]struct { @@ -45,39 +44,47 @@ func TestFileLoader_Load(t *testing.T) { }{ "load minimal config info": { body: common.MapStr{ - "index_patterns": []string{"mock-7.0.0-*"}, - "order": order, - "settings": common.MapStr{"index": nil}, + "index_patterns": []string{"mock-7.0.0"}, + "data_stream": struct{}{}, + "priority": 150, + "template": common.MapStr{ + "settings": common.MapStr{"index": nil}}, }, }, "load minimal config with index settings": { settings: TemplateSettings{Index: common.MapStr{"code": "best_compression"}}, body: common.MapStr{ - "index_patterns": []string{"mock-7.0.0-*"}, - "order": order, - "settings": common.MapStr{"index": common.MapStr{"code": "best_compression"}}, + "index_patterns": []string{"mock-7.0.0"}, + "data_stream": struct{}{}, + "priority": 150, + "template": common.MapStr{ + "settings": common.MapStr{"index": common.MapStr{"code": "best_compression"}}}, }, }, "load minimal config with source settings": { settings: TemplateSettings{Source: common.MapStr{"enabled": false}}, body: common.MapStr{ - "index_patterns": []string{"mock-7.0.0-*"}, - "order": order, - "settings": common.MapStr{"index": nil}, - "mappings": common.MapStr{ - "_source": common.MapStr{"enabled": false}, - "_meta": common.MapStr{"beat": prefix, "version": ver}, - "date_detection": false, - "dynamic_templates": nil, - "properties": nil, - }, + "index_patterns": []string{"mock-7.0.0"}, + "data_stream": struct{}{}, + "priority": 150, + "template": common.MapStr{ + "settings": common.MapStr{"index": nil}, + "mappings": common.MapStr{ + "_source": common.MapStr{"enabled": false}, + "_meta": common.MapStr{"beat": prefix, "version": ver}, + "date_detection": false, + "dynamic_templates": nil, + "properties": nil, + }}, }, }, "load config and in-line analyzer fields": { body: common.MapStr{ - "index_patterns": []string{"mock-7.0.0-*"}, - "order": order, - "settings": common.MapStr{"index": nil}, + "index_patterns": []string{"mock-7.0.0"}, + "data_stream": struct{}{}, + "priority": 150, + "template": common.MapStr{ + "settings": common.MapStr{"index": nil}}, }, fields: []byte(`- key: test title: Test fields.yml with analyzer @@ -103,65 +110,66 @@ func TestFileLoader_Load(t *testing.T) { analyzer: simple `), want: common.MapStr{ - "index_patterns": []string{ - "mock-7.0.0-*", - }, - "order": 1, - "mappings": common.MapStr{ - "_meta": common.MapStr{ - "version": "7.0.0", - "beat": "mock", - }, - "date_detection": false, - "dynamic_templates": []common.MapStr{ - { - "strings_as_keyword": common.MapStr{ - "mapping": common.MapStr{ - "ignore_above": 1024, - "type": "keyword", + "index_patterns": []string{"mock-7.0.0"}, + "data_stream": struct{}{}, + "priority": 150, + "template": common.MapStr{ + "mappings": common.MapStr{ + "_meta": common.MapStr{ + "version": "7.0.0", + "beat": "mock", + }, + "date_detection": false, + "dynamic_templates": []common.MapStr{ + { + "strings_as_keyword": common.MapStr{ + "mapping": common.MapStr{ + "ignore_above": 1024, + "type": "keyword", + }, + "match_mapping_type": "string", }, - "match_mapping_type": "string", }, }, - }, - "properties": common.MapStr{ - "code_block_text": common.MapStr{ - "type": "text", - "norms": false, - "analyzer": "test_powershell", - }, - "script_block_text": common.MapStr{ - "type": "text", - "norms": false, - "analyzer": "test_powershell", - }, - "standard_text": common.MapStr{ - "type": "text", - "norms": false, - "analyzer": "simple", + "properties": common.MapStr{ + "code_block_text": common.MapStr{ + "type": "text", + "norms": false, + "analyzer": "test_powershell", + }, + "script_block_text": common.MapStr{ + "type": "text", + "norms": false, + "analyzer": "test_powershell", + }, + "standard_text": common.MapStr{ + "type": "text", + "norms": false, + "analyzer": "simple", + }, }, }, - }, - "settings": common.MapStr{ - "index": common.MapStr{ - "refresh_interval": "5s", - "mapping": common.MapStr{ - "total_fields": common.MapStr{ - "limit": 10000, + "settings": common.MapStr{ + "index": common.MapStr{ + "refresh_interval": "5s", + "mapping": common.MapStr{ + "total_fields": common.MapStr{ + "limit": 10000, + }, }, - }, - "query": common.MapStr{ - "default_field": []string{ - "fields.*", + "query": common.MapStr{ + "default_field": []string{ + "fields.*", + }, }, + "max_docvalue_fields_search": 200, }, - "max_docvalue_fields_search": 200, - }, - "analysis": common.MapStr{ - "analyzer": common.MapStr{ - "test_powershell": map[string]interface{}{ - "type": "pattern", - "pattern": "[\\W&&[^-]]+", + "analysis": common.MapStr{ + "analyzer": common.MapStr{ + "test_powershell": map[string]interface{}{ + "type": "pattern", + "pattern": "[\\W&&[^-]]+", + }, }, }, }, @@ -170,8 +178,7 @@ func TestFileLoader_Load(t *testing.T) { }, "load config and in-line analyzer fields with name collision": { body: common.MapStr{ - "index_patterns": []string{"mock-7.0.0-*"}, - "order": order, + "index_patterns": []string{"mock-7.0.0"}, "settings": common.MapStr{"index": nil}, }, fields: []byte(`- key: test @@ -205,7 +212,7 @@ func TestFileLoader_Load(t *testing.T) { require.NoError(t, err) fl := NewFileLoader(fc) - cfg := DefaultConfig() + cfg := DefaultConfig(info) cfg.Settings = test.settings err = fl.Load(cfg, info, test.fields, false) diff --git a/libbeat/template/processor.go b/libbeat/template/processor.go index a9489a35a11f..cb13a95aa2d1 100644 --- a/libbeat/template/processor.go +++ b/libbeat/template/processor.go @@ -31,7 +31,6 @@ import ( const DefaultField = false var ( - minVersionAlias = common.MustNewVersion("6.4.0") minVersionFieldMeta = common.MustNewVersion("7.6.0") minVersionHistogram = common.MustNewVersion("7.6.0") minVersionWildcard = common.MustNewVersion("7.9.0") @@ -204,11 +203,6 @@ func (p *Processor) scaledFloat(f *mapping.Field, params ...common.MapStr) commo property := p.getDefaultProperties(f) property["type"] = "scaled_float" - if p.EsVersion.IsMajor(2) { - property["type"] = "float" - return property - } - // Set scaling factor scalingFactor := defaultScalingFactor if f.ScalingFactor != 0 && len(f.ObjectTypeParams) == 0 { @@ -270,22 +264,12 @@ func (p *Processor) halfFloat(f *mapping.Field) common.MapStr { property := p.getDefaultProperties(f) property["type"] = "half_float" - if p.EsVersion.IsMajor(2) { - property["type"] = "float" - } return property } func (p *Processor) ip(f *mapping.Field) common.MapStr { property := p.getDefaultProperties(f) - property["type"] = "ip" - - if p.EsVersion.IsMajor(2) { - property["type"] = "string" - property["ignore_above"] = 1024 - property["index"] = "not_analyzed" - } return property } @@ -319,11 +303,6 @@ func (p *Processor) keyword(f *mapping.Field, analyzers common.MapStr) common.Ma property["ignore_above"] = f.IgnoreAbove } - if p.EsVersion.IsMajor(2) { - property["type"] = "string" - property["index"] = "not_analyzed" - } - if len(f.MultiFields) > 0 { fields := common.MapStr{} p.Process(f.MultiFields, stateFromField(f), fields, analyzers) @@ -360,18 +339,8 @@ func (p *Processor) text(f *mapping.Field, analyzers common.MapStr) (properties properties["type"] = "text" - if p.EsVersion.IsMajor(2) { - properties["type"] = "string" - properties["index"] = "analyzed" - if !f.Norms { - properties["norms"] = common.MapStr{ - "enabled": false, - } - } - } else { - if !f.Norms { - properties["norms"] = false - } + if !f.Norms { + properties["norms"] = false } if f.Analyzer.Name != "" { @@ -426,11 +395,6 @@ func (p *Processor) array(f *mapping.Field) common.MapStr { } func (p *Processor) alias(f *mapping.Field) common.MapStr { - // Aliases were introduced in Elasticsearch 6.4, ignore if unsupported - if p.EsVersion.LessThan(minVersionAlias) { - return nil - } - // In case migration is disabled and it's a migration alias, field is not created if !p.Migration && f.MigrationAlias { return nil @@ -483,11 +447,6 @@ func (p *Processor) object(f *mapping.Field) common.MapStr { matchingType = matchType("*", otp.ObjectTypeMappingType) case "text": dynProperties["type"] = "text" - - if p.EsVersion.IsMajor(2) { - dynProperties["type"] = "string" - dynProperties["index"] = "analyzed" - } matchingType = matchType("string", otp.ObjectTypeMappingType) case "keyword": dynProperties["type"] = otp.ObjectType diff --git a/libbeat/template/processor_test.go b/libbeat/template/processor_test.go index c686f2e47387..fefeb9b4313d 100644 --- a/libbeat/template/processor_test.go +++ b/libbeat/template/processor_test.go @@ -33,9 +33,6 @@ func TestProcessor(t *testing.T) { trueVar := true p := &Processor{EsVersion: *common.MustNewVersion("7.0.0")} migrationP := &Processor{EsVersion: *common.MustNewVersion("7.0.0"), Migration: true} - pEsVersion2 := &Processor{EsVersion: *common.MustNewVersion("2.0.0")} - pEsVersion64 := &Processor{EsVersion: *common.MustNewVersion("6.4.0")} - pEsVersion63 := &Processor{EsVersion: *common.MustNewVersion("6.3.6")} pEsVersion76 := &Processor{EsVersion: *common.MustNewVersion("7.6.0")} tests := []struct { @@ -81,10 +78,6 @@ func TestProcessor(t *testing.T) { "scaling_factor": 10, }, }, - { - output: pEsVersion2.scaledFloat(&mapping.Field{Type: "scaled_float"}), - expected: common.MapStr{"type": "float"}, - }, { output: p.object(&mapping.Field{Type: "object", Enabled: &falseVar}), expected: common.MapStr{ @@ -111,15 +104,6 @@ func TestProcessor(t *testing.T) { output: p.array(&mapping.Field{Type: "array", Index: &falseVar, ObjectType: "keyword"}), expected: common.MapStr{"index": false, "type": "keyword"}, }, - { - output: pEsVersion64.alias(&mapping.Field{Type: "alias", AliasPath: "a.b"}), - expected: common.MapStr{"path": "a.b", "type": "alias"}, - }, - { - // alias unsupported in ES < 6.4 - output: pEsVersion63.alias(&mapping.Field{Type: "alias", AliasPath: "a.b"}), - expected: nil, - }, { output: p.object(&mapping.Field{Type: "object", Enabled: &falseVar}), expected: common.MapStr{ diff --git a/libbeat/template/template.go b/libbeat/template/template.go index 291d128d0f48..af0324873037 100644 --- a/libbeat/template/template.go +++ b/libbeat/template/template.go @@ -51,7 +51,6 @@ type Template struct { esVersion common.Version config TemplateConfig migration bool - templateType IndexTemplateType order int priority int } @@ -71,13 +70,17 @@ func New( } name := config.Name + if config.JSON.Enabled { + name = config.JSON.Name + } + if name == "" { name = fmt.Sprintf("%s-%s", beatName, bV.String()) } pattern := config.Pattern if pattern == "" { - pattern = name + "-*" + pattern = name + "*" } event := &beat.Event{ @@ -132,8 +135,6 @@ func New( beatName: beatName, config: config, migration: migration, - templateType: config.Type, - order: config.Order, priority: config.Priority, }, nil } @@ -188,56 +189,25 @@ func (t *Template) LoadBytes(data []byte) (common.MapStr, error) { } // LoadMinimal loads the template only with the given configuration -func (t *Template) LoadMinimal() (common.MapStr, error) { - var m common.MapStr - switch t.templateType { - case IndexTemplateLegacy: - m = t.loadMinimalLegacy() - case IndexTemplateComponent: - m = t.loadMinimalComponent() - case IndexTemplateIndex: - m = t.loadMinimalIndex() - default: - return nil, fmt.Errorf("unknown template type %v", t.templateType) - } - +func (t *Template) LoadMinimal() common.MapStr { + templ := common.MapStr{} if t.config.Settings.Source != nil { - m["mappings"] = buildMappings( - t.beatVersion, t.esVersion, t.beatName, + templ["mappings"] = buildMappings( + t.beatVersion, t.beatName, nil, nil, common.MapStr(t.config.Settings.Source)) } - - return m, nil -} - -func (t *Template) loadMinimalLegacy() common.MapStr { - keyPattern, patterns := buildPatternSettings(t.esVersion, t.GetPattern()) - return common.MapStr{ - keyPattern: patterns, - "order": t.order, - "settings": common.MapStr{ - "index": t.config.Settings.Index, - }, + templ["settings"] = common.MapStr{ + "index": t.config.Settings.Index, } -} - -func (t *Template) loadMinimalComponent() common.MapStr { return common.MapStr{ - "template": common.MapStr{ - "settings": common.MapStr{ - "index": t.config.Settings.Index, - }, - }, + "template": templ, + "data_stream": struct{}{}, + "priority": t.priority, + "index_patterns": []string{t.GetPattern()}, } } -func (t *Template) loadMinimalIndex() common.MapStr { - m := t.loadMinimalComponent() - m["priority"] = t.priority - return m -} - // GetName returns the name of the template func (t *Template) GetName() string { return t.name @@ -251,45 +221,19 @@ func (t *Template) GetPattern() string { // Generate generates the full template // The default values are taken from the default variable. func (t *Template) Generate(properties, analyzers common.MapStr, dynamicTemplates []common.MapStr) common.MapStr { - switch t.templateType { - case IndexTemplateLegacy: - return t.generateLegacy(properties, analyzers, dynamicTemplates) - case IndexTemplateComponent: - return t.generateComponent(properties, analyzers, dynamicTemplates) - case IndexTemplateIndex: - return t.generateIndex(properties, analyzers, dynamicTemplates) - } - return nil -} + tmpl := t.generateComponent(properties, analyzers, dynamicTemplates) + tmpl["data_stream"] = struct{}{} + tmpl["priority"] = t.priority + tmpl["index_patterns"] = []string{t.GetPattern()} + return tmpl -func (t *Template) generateLegacy(properties, analyzers common.MapStr, dynamicTemplates []common.MapStr) common.MapStr { - keyPattern, patterns := buildPatternSettings(t.esVersion, t.GetPattern()) - m := common.MapStr{ - keyPattern: patterns, - "order": t.order, - "mappings": buildMappings( - t.beatVersion, t.esVersion, t.beatName, - properties, - append(dynamicTemplates, buildDynTmpl(t.esVersion)), - common.MapStr(t.config.Settings.Source)), - "settings": common.MapStr{ - "index": buildIdxSettings( - t.esVersion, - t.config.Settings.Index, - ), - }, - } - if len(analyzers) != 0 { - m.Put("settings.analysis.analyzer", analyzers) - } - return m } func (t *Template) generateComponent(properties, analyzers common.MapStr, dynamicTemplates []common.MapStr) common.MapStr { m := common.MapStr{ "template": common.MapStr{ "mappings": buildMappings( - t.beatVersion, t.esVersion, t.beatName, + t.beatVersion, t.beatName, properties, append(dynamicTemplates, buildDynTmpl(t.esVersion)), common.MapStr(t.config.Settings.Source)), @@ -302,28 +246,13 @@ func (t *Template) generateComponent(properties, analyzers common.MapStr, dynami }, } if len(analyzers) != 0 { - m.Put("settings.analysis.analyzer", analyzers) + m.Put("template.settings.analysis.analyzer", analyzers) } return m } -func (t *Template) generateIndex(properties, analyzers common.MapStr, dynamicTemplates []common.MapStr) common.MapStr { - tmpl := t.generateComponent(properties, analyzers, dynamicTemplates) - tmpl["priority"] = t.priority - keyPattern, patterns := buildPatternSettings(t.esVersion, t.GetPattern()) - tmpl[keyPattern] = patterns - return tmpl -} - -func buildPatternSettings(ver common.Version, pattern string) (string, interface{}) { - if ver.Major < 6 { - return "template", pattern - } - return "index_patterns", []string{pattern} -} - func buildMappings( - beatVersion, esVersion common.Version, + beatVersion common.Version, beatName string, properties common.MapStr, dynTmpls []common.MapStr, @@ -343,41 +272,16 @@ func buildMappings( mapping["_source"] = source } - major := esVersion.Major - switch { - case major == 2: - mapping.Put("_all.norms.enabled", false) - mapping = common.MapStr{ - "_default_": mapping, - } - case major < 6: - mapping = common.MapStr{ - "_default_": mapping, - } - case major == 6: - mapping = common.MapStr{ - "doc": mapping, - } - case major >= 7: - // keep typeless structure - } - return mapping } func buildDynTmpl(ver common.Version) common.MapStr { - strMapping := common.MapStr{ - "ignore_above": 1024, - "type": "keyword", - } - if ver.Major == 2 { - strMapping["type"] = "string" - strMapping["index"] = "not_analyzed" - } - return common.MapStr{ "strings_as_keyword": common.MapStr{ - "mapping": strMapping, + "mapping": common.MapStr{ + "ignore_above": 1024, + "type": "keyword", + }, "match_mapping_type": "string", }, } @@ -393,25 +297,14 @@ func buildIdxSettings(ver common.Version, userSettings common.MapStr) common.Map }, } - // number_of_routing shards is only supported for ES version >= 6.1 - // If ES >= 7.0 we can exclude this setting as well. - version61, _ := common.NewVersion("6.1.0") - if !ver.LessThan(version61) && ver.Major < 7 { - indexSettings.Put("number_of_routing_shards", defaultNumberOfRoutingShards) - } - - if ver.Major >= 7 { - // copy defaultFields, as defaultFields is shared global slice. - fields := make([]string, len(defaultFields)) - copy(fields, defaultFields) - fields = append(fields, "fields.*") + // copy defaultFields, as defaultFields is shared global slice. + fields := make([]string, len(defaultFields)) + copy(fields, defaultFields) + fields = append(fields, "fields.*") - indexSettings.Put("query.default_field", fields) - } + indexSettings.Put("query.default_field", fields) - if ver.Major >= 6 { - indexSettings.Put("max_docvalue_fields_search", defaultMaxDocvalueFieldsSearch) - } + indexSettings.Put("max_docvalue_fields_search", defaultMaxDocvalueFieldsSearch) indexSettings.DeepUpdate(userSettings) return indexSettings diff --git a/libbeat/template/template_test.go b/libbeat/template/template_test.go index 27223ecf6bdb..e2430e25edef 100644 --- a/libbeat/template/template_test.go +++ b/libbeat/template/template_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/version" ) @@ -39,30 +40,13 @@ type testTemplate struct { func TestNumberOfRoutingShards(t *testing.T) { const notPresent = 0 // setting missing indicator const settingKey = "number_of_routing_shards" - const fullKey = "settings.index." + settingKey + const fullKey = "template.settings.index." + settingKey cases := map[string]struct { esVersion string set int want int }{ - "Do not set default for older version than 6.1": { - esVersion: "6.0.0", - want: notPresent, - }, - "Default present if ES 6.1.0 is used": { - esVersion: "6.1.0", - want: 30, - }, - "Default present for newer ES 6.x version": { - esVersion: "6.8.2", - want: 30, - }, - "Can overwrite default for ES 6.x": { - esVersion: "6.1.0", - set: 1024, - want: 1024, - }, "Do not set by default for ES 7.x": { esVersion: "7.0.0", want: notPresent, @@ -108,29 +92,20 @@ func TestNumberOfRoutingShards(t *testing.T) { func TestTemplate(t *testing.T) { currentVersion := getVersion("") - - t.Run("for ES 6.x", func(t *testing.T) { - template := createTestTemplate(t, currentVersion, "6.4.0", DefaultConfig()) - template.Assert("index_patterns", []string{"testbeat-" + currentVersion + "-*"}) - template.Assert("order", 1) - template.Assert("mappings.doc._meta", common.MapStr{"beat": "testbeat", "version": currentVersion}) - template.Assert("settings.index.max_docvalue_fields_search", 200) - }) + info := beat.Info{Beat: "testbeat", Version: currentVersion} t.Run("for ES 7.x", func(t *testing.T) { - template := createTestTemplate(t, currentVersion, "7.2.0", DefaultConfig()) - template.Assert("index_patterns", []string{"testbeat-" + currentVersion + "-*"}) - template.Assert("order", 1) - template.Assert("mappings._meta", common.MapStr{"beat": "testbeat", "version": currentVersion}) - template.Assert("settings.index.max_docvalue_fields_search", 200) + template := createTestTemplate(t, currentVersion, "7.10.0", DefaultConfig(info)) + template.Assert("index_patterns", []string{"testbeat-" + currentVersion}) + template.Assert("template.mappings._meta", common.MapStr{"beat": "testbeat", "version": currentVersion}) + template.Assert("template.settings.index.max_docvalue_fields_search", 200) }) t.Run("for ES 8.x", func(t *testing.T) { - template := createTestTemplate(t, currentVersion, "8.0.0", DefaultConfig()) - template.Assert("index_patterns", []string{"testbeat-" + currentVersion + "-*"}) - template.Assert("order", 1) - template.Assert("mappings._meta", common.MapStr{"beat": "testbeat", "version": currentVersion}) - template.Assert("settings.index.max_docvalue_fields_search", 200) + template := createTestTemplate(t, currentVersion, "8.0.0", DefaultConfig(info)) + template.Assert("index_patterns", []string{"testbeat-" + currentVersion}) + template.Assert("template.mappings._meta", common.MapStr{"beat": "testbeat", "version": currentVersion}) + template.Assert("template.settings.index.max_docvalue_fields_search", 200) }) } diff --git a/libbeat/template/testdata/fields.json b/libbeat/template/testdata/fields.json index d95b7a7dabe0..01894247b8e7 100644 --- a/libbeat/template/testdata/fields.json +++ b/libbeat/template/testdata/fields.json @@ -1,15 +1,17 @@ { "index_patterns": ["foo"], - "settings": { - "number_of_shards": 1 - }, - "mappings": { - "_source": { - "enabled": false + "template": { + "settings": { + "number_of_shards": 1 }, - "properties": { - "host_name": { - "type": "keyword" + "mappings": { + "_source": { + "enabled": false + }, + "properties": { + "host_name": { + "type": "keyword" + } } } } diff --git a/libbeat/template/testdata/fields.yml b/libbeat/template/testdata/fields.yml index afceaeaae694..fcfe105b5e5f 100644 --- a/libbeat/template/testdata/fields.yml +++ b/libbeat/template/testdata/fields.yml @@ -3,6 +3,8 @@ description: > Contains all types for testing fields: + - name: '@timestamp' + type: date - name: object type: object diff --git a/libbeat/tests/files/template.json b/libbeat/tests/files/template.json index 655613e32d0a..6ebbcfe211dd 100644 --- a/libbeat/tests/files/template.json +++ b/libbeat/tests/files/template.json @@ -1,19 +1,21 @@ { "index_patterns": ["bla"], - "settings": { - "number_of_shards": 1 - }, - "mappings": { - "_source": { - "enabled": false + "template": { + "settings": { + "number_of_shards": 1 }, - "properties": { - "host_name": { - "type": "keyword" + "mappings": { + "_source": { + "enabled": false }, - "created_at": { - "type": "date", - "format": "EEE MMM dd HH:mm:ss Z YYYY" + "properties": { + "host_name": { + "type": "keyword" + }, + "created_at": { + "type": "date", + "format": "EEE MMM dd HH:mm:ss Z YYYY" + } } } } diff --git a/libbeat/tests/system/beat/common_tests.py b/libbeat/tests/system/beat/common_tests.py index f5bccf2968dc..a5caff92c9a4 100644 --- a/libbeat/tests/system/beat/common_tests.py +++ b/libbeat/tests/system/beat/common_tests.py @@ -58,7 +58,12 @@ def test_export_template(self): """ output = self.run_export_cmd("template") js = json.loads(output) - assert "index_patterns" in js and "mappings" in js + assert "index_patterns" in js + assert "template" in js + assert "priority" in js + assert "order" not in js + assert "mappings" in js["template"] + assert "settings" in js["template"] def test_export_index_pattern(self): """ diff --git a/libbeat/tests/system/config/libbeat.yml.j2 b/libbeat/tests/system/config/libbeat.yml.j2 index edfc178eea86..e6d62a5eae6b 100644 --- a/libbeat/tests/system/config/libbeat.yml.j2 +++ b/libbeat/tests/system/config/libbeat.yml.j2 @@ -31,9 +31,6 @@ setup.ilm: {% if ilm.pattern %} pattern: {{ ilm.pattern }} {% endif %} - {% if ilm.rollover_alias %} - rollover_alias: {{ ilm.rollover_alias }} - {% endif %} {% endif %} #================================ Processors ===================================== diff --git a/libbeat/tests/system/idxmgmt.py b/libbeat/tests/system/idxmgmt.py index f789b919bc26..6da6a077c71b 100644 --- a/libbeat/tests/system/idxmgmt.py +++ b/libbeat/tests/system/idxmgmt.py @@ -9,35 +9,45 @@ class IdxMgmt(unittest.TestCase): def __init__(self, client, index): self._client = client self._index = index if index != '' and index != '*' else 'mockbeat' + self.patterns = [self.default_pattern(), "1", datetime.datetime.now().strftime("%Y.%m.%d")] def needs_init(self, s): return s == '' or s == '*' - def delete(self, indices=[], policies=[]): - indices = list([x for x in indices if x != '']) - if not indices: - indices == [self._index] + def delete(self, indices=[], policies=[], data_streams=[]): + for ds in data_streams: + self.delete_data_stream(ds) + self.delete_template(template=ds) for i in indices: self.delete_index_and_alias(i) self.delete_template(template=i) for i in [x for x in policies if x != '']: self.delete_policy(i) + def delete_data_stream(self, data_stream): + try: + resp = self._client.transport.perform_request('DELETE', '/_data_stream/' + data_stream) + except NotFoundError: + pass + def delete_index_and_alias(self, index=""): if self.needs_init(index): index = self._index - try: - self._client.transport.perform_request('DELETE', "/" + index + "*") - except NotFoundError: - pass + for pattern in self.patterns: + index_with_pattern = index+"-"+pattern + try: + self._client.indices.delete(index_with_pattern) + self._client.indices.delete_alias(index, index_with_pattern) + except NotFoundError: + continue def delete_template(self, template=""): if self.needs_init(template): template = self._index try: - self._client.transport.perform_request('DELETE', "/_template/" + template + "*") + self._client.transport.perform_request('DELETE', "/_index_template/" + template) except NotFoundError: pass @@ -54,12 +64,7 @@ def delete_policy(self, policy): def assert_index_template_not_loaded(self, template): with pytest.raises(NotFoundError): - self._client.transport.perform_request('GET', '/_template/' + template) - - def assert_legacy_index_template_loaded(self, template): - resp = self._client.transport.perform_request('GET', '/_template/' + template) - assert template in resp - assert "lifecycle" not in resp[template]["settings"]["index"] + self._client.transport.perform_request('GET', '/_index_template/' + template) def assert_index_template_loaded(self, template): resp = self._client.transport.perform_request('GET', '/_index_template/' + template) @@ -69,40 +74,20 @@ def assert_index_template_loaded(self, template): found = True assert found - def assert_component_template_loaded(self, template): - resp = self._client.transport.perform_request('GET', '/_component_template/' + template) - found = False - print(resp) - for index_template in resp['component_templates']: + def assert_data_stream_created(self, data_stream): + try: + resp = self._client.transport.perform_request('GET', '/_data_stream/' + data_stream) + except NotFoundError: + assert False + + def assert_index_template_index_pattern(self, template, index_pattern): + resp = self._client.transport.perform_request('GET', '/_index_template/' + template) + for index_template in resp['index_templates']: if index_template['name'] == template: + assert index_pattern == index_template['index_template']['index_patterns'] found = True assert found - def assert_ilm_template_loaded(self, template, policy, alias): - resp = self._client.transport.perform_request('GET', '/_template/' + template) - assert resp[template]["settings"]["index"]["lifecycle"]["name"] == policy - assert resp[template]["settings"]["index"]["lifecycle"]["rollover_alias"] == alias - - def assert_index_template_index_pattern(self, template, index_pattern): - resp = self._client.transport.perform_request('GET', '/_template/' + template) - assert template in resp - assert resp[template]["index_patterns"] == index_pattern - - def assert_alias_not_created(self, alias): - resp = self._client.transport.perform_request('GET', '/_alias') - for name, entry in resp.items(): - if alias not in name: - continue - assert entry["aliases"] == {}, entry["aliases"] - - def assert_alias_created(self, alias, pattern=None): - if pattern is None: - pattern = self.default_pattern() - name = alias + "-" + pattern - resp = self._client.transport.perform_request('GET', '/_alias/' + alias) - assert name in resp - assert resp[name]["aliases"][alias]["is_write_index"] == True - def assert_policy_not_created(self, policy): with pytest.raises(NotFoundError): self._client.transport.perform_request('GET', '/_ilm/policy/' + policy) @@ -113,22 +98,14 @@ def assert_policy_created(self, policy): assert resp[policy]["policy"]["phases"]["hot"]["actions"]["rollover"]["max_size"] == "50gb" assert resp[policy]["policy"]["phases"]["hot"]["actions"]["rollover"]["max_age"] == "30d" - def assert_docs_written_to_alias(self, alias, pattern=None): + def assert_docs_written_to_data_stream(self, data_stream): # Refresh the indices to guarantee all documents are available # through the _search API. self._client.transport.perform_request('POST', '/_refresh') - if pattern is None: - pattern = self.default_pattern() - name = alias + "-" + pattern - data = self._client.transport.perform_request('GET', '/' + name + '/_search') + data = self._client.transport.perform_request('GET', '/' + data_stream + '/_search') self.assertGreater(data["hits"]["total"]["value"], 0) def default_pattern(self): d = datetime.datetime.now().strftime("%Y.%m.%d") return d + "-000001" - - def index_for(self, alias, pattern=None): - if pattern is None: - pattern = self.default_pattern() - return "{}-{}".format(alias, pattern) diff --git a/libbeat/tests/system/template/template.go b/libbeat/tests/system/template/template.go index ed284a6ff79e..7467f5b60fbc 100644 --- a/libbeat/tests/system/template/template.go +++ b/libbeat/tests/system/template/template.go @@ -65,10 +65,10 @@ func testTemplateDefaultFieldLength(beatName string, elasticLicensed bool) func( templateMap := tmpl.Generate(fields, nil, nil) - v, _ := templateMap.GetValue("settings.index.query.default_field") + v, _ := templateMap.GetValue("template.settings.index.query.default_field") defaultValue, ok := v.([]string) if !ok { - t.Fatalf("settings.index.query.default_field value has an unexpected type: %T", v) + t.Fatalf("template.settings.index.query.default_field value has an unexpected type: %T", v) } if len(defaultValue) > MaxDefaultFieldLength { diff --git a/libbeat/tests/system/test_cmd_setup_index_management.py b/libbeat/tests/system/test_cmd_setup_index_management.py index cd6d19eefbe4..2abe88281758 100644 --- a/libbeat/tests/system/test_cmd_setup_index_management.py +++ b/libbeat/tests/system/test_cmd_setup_index_management.py @@ -21,28 +21,29 @@ def setUp(self): self.cmd = "--index-management" # auto-derived default settings, if nothing else is set self.policy_name = self.beat_name - self.index_name = self.alias_name = self.beat_name + "-9.9.9" + self.data_stream = self.beat_name + "-9.9.9" - self.custom_alias = self.beat_name + "_foo" self.custom_policy = self.beat_name + "_bar" self.custom_template = self.beat_name + "_foobar" self.es = self.es_client() - self.idxmgmt = IdxMgmt(self.es, self.index_name) - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt = IdxMgmt(self.es, self.data_stream) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) logging.getLogger("urllib3").setLevel(logging.WARNING) logging.getLogger("elasticsearch").setLevel(logging.ERROR) def tearDown(self): - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) def render_config(self, **kwargs): self.render_config_template( elasticsearch={"hosts": self.get_elasticsearch_url()}, - es_template_name=self.index_name, + es_template_name=self.data_stream, **kwargs ) @@ -57,45 +58,24 @@ def test_setup_default(self): extra_args=["setup", self.cmd]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_index_template_index_pattern(self.index_name, [self.index_name + "-*"]) - self.idxmgmt.assert_docs_written_to_alias(self.alias_name) - self.idxmgmt.assert_alias_created(self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) + self.idxmgmt.assert_index_template_index_pattern(self.data_stream, [self.data_stream]) self.idxmgmt.assert_policy_created(self.policy_name) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_default(self): - """ - Test setup --index-management with default config - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.cmd]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_index_template_index_pattern(self.index_name, [self.index_name + "-*"]) - self.idxmgmt.assert_alias_created(self.alias_name) - self.idxmgmt.assert_policy_created(self.policy_name) - # try deleting policy needs to raise an error as it is in use - with pytest.raises(RequestError): - self.idxmgmt.delete_policy(self.policy_name) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') def test_setup_template_disabled(self): """ Test setup --index-management when ilm disabled """ + self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], + exit_code = self.run_beat(logging_args=["-v", "-e", "-d", "*"], extra_args=["setup", self.cmd, "-E", "setup.template.enabled=false"]) assert exit_code == 0 - self.idxmgmt.assert_index_template_not_loaded(self.index_name) - self.idxmgmt.assert_alias_created(self.index_name) + self.idxmgmt.assert_index_template_not_loaded(self.data_stream+"ba") self.idxmgmt.assert_policy_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -110,8 +90,7 @@ def test_setup_ilm_disabled(self): "-E", "setup.ilm.enabled=false"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.index_name) - self.idxmgmt.assert_alias_not_created(self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_not_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -126,7 +105,7 @@ def test_setup_policy_name(self): "-E", "setup.ilm.policy_name=" + self.custom_policy]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.custom_policy, self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_created(self.custom_policy) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -176,58 +155,6 @@ def test_setup_ilm_policy_no_overwrite(self): assert "delete" not in resp[policy_name]["policy"]["phases"] assert "hot" in resp[policy_name]["policy"]["phases"] - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_rollover_alias(self): - """ - Test setup --index-management when ilm.rollover_alias is configured - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.cmd, - "-E", "setup.ilm.rollover_alias=" + self.custom_alias]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) - self.idxmgmt.assert_index_template_index_pattern(self.custom_alias, [self.custom_alias + "-*"]) - self.idxmgmt.assert_alias_created(self.custom_alias) - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_rollover_alias_with_fieldref(self): - """ - Test setup --index-management when ilm.rollover_alias is configured and using field reference. - """ - aliasFieldRef = "%{[agent.name]}-myalias" - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.cmd, - "-E", "setup.ilm.rollover_alias=" + aliasFieldRef]) - - self.custom_alias = self.beat_name + "-myalias" - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) - self.idxmgmt.assert_index_template_index_pattern(self.custom_alias, [self.custom_alias + "-*"]) - self.idxmgmt.assert_alias_created(self.custom_alias) - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_template_name_and_pattern(self): - """ - Test setup --index-management ignores template.name and template.pattern when ilm is enabled - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.cmd, - "-E", "setup.template.name=" + self.custom_template, - "-E", "setup.template.pattern=" + self.custom_template + "*"]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_index_template_index_pattern(self.alias_name, [self.alias_name + "-*"]) - self.idxmgmt.assert_alias_created(self.alias_name) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') def test_setup_template_name_and_pattern_on_ilm_disabled(self): @@ -242,9 +169,8 @@ def test_setup_template_name_and_pattern_on_ilm_disabled(self): "-E", "setup.template.pattern=" + self.custom_template + "*"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.custom_template) + self.idxmgmt.assert_index_template_loaded(self.custom_template) self.idxmgmt.assert_index_template_index_pattern(self.custom_template, [self.custom_template + "*"]) - self.idxmgmt.assert_alias_not_created(self.alias_name) self.idxmgmt.assert_policy_not_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -261,13 +187,17 @@ def test_setup_template_with_opts(self): "-E", "setup.template.settings.index.number_of_shards=2"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.index_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) # check that settings are overwritten - resp = self.es.transport.perform_request('GET', '/_template/' + self.index_name) - assert self.index_name in resp - index = resp[self.index_name]["settings"]["index"] - assert index["number_of_shards"] == "2", index["number_of_shards"] + resp = self.es.transport.perform_request('GET', '/_index_template/' + self.data_stream) + found = False + for index_template in resp["index_templates"]: + if self.data_stream == index_template["name"]: + found = True + index = index_template["index_template"]["template"]["settings"]["index"] + assert index["number_of_shards"] == "2", index["number_of_shards"] + assert found @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') @@ -281,22 +211,29 @@ def test_setup_overwrite_template_on_ilm_policy_created(self): exit_code = self.run_beat(logging_args=["-v", "-d", "*"], extra_args=["setup", self.cmd, "-E", "setup.ilm.enabled=false", - "-E", "setup.template.name=" + self.custom_alias, - "-E", "setup.template.pattern=" + self.custom_alias + "*"]) + "-E", "setup.template.priority=160", + "-E", "setup.template.name=" + self.custom_template, + "-E", "setup.template.pattern=" + self.custom_template + "*"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.custom_alias) + self.idxmgmt.assert_index_template_loaded(self.custom_template) self.idxmgmt.assert_policy_not_created(self.policy_name) # ensure ilm policy is created, triggering overwriting existing template - exit_code = self.run_beat(extra_args=["setup", self.cmd, - "-E", "setup.template.overwrite=false", - "-E", "setup.template.settings.index.number_of_shards=2", - "-E", "setup.ilm.rollover_alias=" + self.custom_alias]) + exit_code = self.run_beat(extra_args=["setup", "-d", "*", self.cmd, + "-E", "setup.template.overwrite=true", + "-E", "setup.template.name=" + self.custom_template, + "-E", "setup.template.pattern=" + self.custom_template + "*", + "-E", "setup.template.settings.index.number_of_shards=2"]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) + self.idxmgmt.assert_index_template_loaded(self.custom_template) self.idxmgmt.assert_policy_created(self.policy_name) # check that template was overwritten - resp = self.es.transport.perform_request('GET', '/_template/' + self.custom_alias) - assert self.custom_alias in resp - index = resp[self.custom_alias]["settings"]["index"] - assert index["number_of_shards"] == "2", index["number_of_shards"] + resp = self.es.transport.perform_request('GET', '/_index_template/' + self.custom_template) + + found = False + for index_template in resp["index_templates"]: + if index_template["name"] == self.custom_template: + found = True + index = index_template["index_template"]["template"]["settings"]["index"] + assert index["number_of_shards"] == "2", index["number_of_shards"] + assert found diff --git a/libbeat/tests/system/test_ilm.py b/libbeat/tests/system/test_ilm.py index 672f51327f64..461fc0212f0d 100644 --- a/libbeat/tests/system/test_ilm.py +++ b/libbeat/tests/system/test_ilm.py @@ -21,23 +21,24 @@ class TestRunILM(BaseTest): def setUp(self): super(TestRunILM, self).setUp() - self.alias_name = self.index_name = self.beat_name + "-9.9.9" + self.data_stream = self.beat_name + "-9.9.9" self.policy_name = self.beat_name - self.custom_alias = self.beat_name + "_foo" self.custom_policy = self.beat_name + "_bar" self.es = self.es_client() - self.idxmgmt = IdxMgmt(self.es, self.index_name) - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt = IdxMgmt(self.es, self.data_stream) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) def tearDown(self): - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) def render_config(self, **kwargs): self.render_config_template( elasticsearch={"hosts": self.get_elasticsearch_url()}, - es_template_name=self.index_name, + es_template_name=self.data_stream, **kwargs ) @@ -45,7 +46,7 @@ def render_config(self, **kwargs): @pytest.mark.tag('integration') def test_ilm_default(self): """ - Test ilm default settings to load ilm policy, write alias and ilm template + Test ilm default settings to load ilm policy, data stream template """ self.render_config() proc = self.start_beat() @@ -54,10 +55,9 @@ def test_ilm_default(self): self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) proc.check_kill_and_wait() - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_alias_created(self.alias_name) + self.idxmgmt.assert_data_stream_created(self.data_stream) self.idxmgmt.assert_policy_created(self.policy_name) - self.idxmgmt.assert_docs_written_to_alias(self.alias_name) + self.idxmgmt.assert_docs_written_to_data_stream(self.data_stream) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') @@ -72,9 +72,9 @@ def test_ilm_disabled(self): self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) proc.check_kill_and_wait() - self.idxmgmt.assert_legacy_index_template_loaded(self.index_name) - self.idxmgmt.assert_alias_not_created(self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_not_created(self.policy_name) + self.idxmgmt.assert_docs_written_to_data_stream(self.data_stream) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') @@ -92,71 +92,10 @@ def test_policy_name(self): self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) proc.check_kill_and_wait() - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, policy_name, self.alias_name) - self.idxmgmt.assert_docs_written_to_alias(self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) + self.idxmgmt.assert_docs_written_to_data_stream(self.data_stream) self.idxmgmt.assert_policy_created(policy_name) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_rollover_alias(self): - """ - Test settings ilm rollover alias - """ - - self.render_config(ilm={"enabled": True, "rollover_alias": self.custom_alias}) - - proc = self.start_beat() - self.wait_until(lambda: self.log_contains("mockbeat start running.")) - self.wait_until(lambda: self.log_contains(MSG_ILM_POLICY_LOADED)) - self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) - proc.check_kill_and_wait() - - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) - self.idxmgmt.assert_docs_written_to_alias(self.custom_alias) - self.idxmgmt.assert_alias_created(self.custom_alias) - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_pattern(self): - """ - Test setting ilm pattern - """ - - pattern = "1" - self.render_config(ilm={"enabled": True, "pattern": pattern}) - - proc = self.start_beat() - self.wait_until(lambda: self.log_contains("mockbeat start running.")) - self.wait_until(lambda: self.log_contains(MSG_ILM_POLICY_LOADED)) - self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) - proc.check_kill_and_wait() - - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_alias_created(self.alias_name, pattern=pattern) - self.idxmgmt.assert_docs_written_to_alias(self.alias_name, pattern=pattern) - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_pattern_date(self): - """ - Test setting ilm pattern with date - """ - - pattern = "'{now/d}'" - self.render_config(ilm={"enabled": True, "pattern": pattern}) - - proc = self.start_beat() - self.wait_until(lambda: self.log_contains("mockbeat start running.")) - self.wait_until(lambda: self.log_contains(MSG_ILM_POLICY_LOADED)) - self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) - proc.check_kill_and_wait() - - resolved_pattern = datetime.datetime.now().strftime("%Y.%m.%d") - - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_alias_created(self.alias_name, pattern=resolved_pattern) - self.idxmgmt.assert_docs_written_to_alias(self.alias_name, pattern=resolved_pattern) - class TestCommandSetupILMPolicy(BaseTest): """ @@ -168,26 +107,27 @@ def setUp(self): self.setupCmd = "--index-management" - self.alias_name = self.index_name = self.beat_name + "-9.9.9" + self.data_stream = self.beat_name + "-9.9.9" self.policy_name = self.beat_name - self.custom_alias = self.beat_name + "_foo" self.custom_policy = self.beat_name + "_bar" self.es = self.es_client() - self.idxmgmt = IdxMgmt(self.es, self.index_name) - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt = IdxMgmt(self.es, self.data_stream) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) logging.getLogger("urllib3").setLevel(logging.WARNING) logging.getLogger("elasticsearch").setLevel(logging.ERROR) def tearDown(self): - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name, self.custom_policy], - policies=[self.policy_name, self.custom_policy]) + self.idxmgmt.delete(indices=[], + policies=[self.policy_name, self.custom_policy], + data_streams=[self.data_stream]) def render_config(self, **kwargs): self.render_config_template( elasticsearch={"hosts": self.get_elasticsearch_url()}, - es_template_name=self.index_name, + es_template_name=self.data_stream, **kwargs ) @@ -203,9 +143,7 @@ def test_setup_ilm_default(self): extra_args=["setup", self.setupCmd]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.policy_name, self.alias_name) - self.idxmgmt.assert_index_template_index_pattern(self.alias_name, [self.alias_name + "-*"]) - self.idxmgmt.assert_alias_created(self.alias_name) + self.idxmgmt.assert_index_template_index_pattern(self.data_stream, [self.data_stream]) self.idxmgmt.assert_policy_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -221,8 +159,7 @@ def test_setup_ilm_disabled(self): "-E", "setup.ilm.enabled=false"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.index_name) - self.idxmgmt.assert_alias_not_created(self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_not_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -238,25 +175,9 @@ def test_policy_name(self): "-E", "setup.ilm.policy_name=" + self.custom_policy]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.alias_name, self.custom_policy, self.alias_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_created(self.custom_policy) - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_rollover_alias(self): - """ - Test ilm policy setup when rollover_alias is configured - """ - self.render_config() - - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, - "-E", "setup.ilm.rollover_alias=" + self.custom_alias]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) - self.idxmgmt.assert_alias_created(self.custom_alias) - class TestCommandExportILMPolicy(BaseTest): """ @@ -277,9 +198,6 @@ def assert_log_contains_policy(self): assert self.log_contains('"max_age": "30d"') assert self.log_contains('"max_size": "50gb"') - def assert_log_contains_write_alias(self): - assert self.log_contains(re.compile('Index Alias .* successfully created.')) - def test_default(self): """ Test ilm-policy export with default config @@ -290,7 +208,6 @@ def test_default(self): assert exit_code == 0 self.assert_log_contains_policy() - self.assert_log_contains_write_alias() def test_load_disabled(self): """ @@ -302,7 +219,6 @@ def test_load_disabled(self): assert exit_code == 0 self.assert_log_contains_policy() - self.assert_log_contains_write_alias() def test_changed_policy_name(self): """ @@ -315,7 +231,6 @@ def test_changed_policy_name(self): assert exit_code == 0 self.assert_log_contains_policy() - self.assert_log_contains_write_alias() def test_export_to_file_absolute_path(self): """ diff --git a/libbeat/tests/system/test_template.py b/libbeat/tests/system/test_template.py index 6a81a6bd036c..abed68332a89 100644 --- a/libbeat/tests/system/test_template.py +++ b/libbeat/tests/system/test_template.py @@ -110,7 +110,7 @@ def test_json_template(self): self.wait_until(lambda: self.log_contains('Template with name \\\"bla\\\" loaded.')) proc.check_kill_and_wait() - result = es.transport.perform_request('GET', '/_template/' + template_name) + result = es.transport.perform_request('GET', '/_index_template/' + template_name) assert len(result) == 1 def get_host(self): @@ -125,14 +125,14 @@ class TestRunTemplate(BaseTest): def setUp(self): super(TestRunTemplate, self).setUp() # auto-derived default settings, if nothing else is set - self.index_name = self.beat_name + "-9.9.9" + self.data_stream = self.beat_name + "-9.9.9" self.es = self.es_client() - self.idxmgmt = IdxMgmt(self.es, self.index_name) - self.idxmgmt.delete(indices=[self.index_name]) + self.idxmgmt = IdxMgmt(self.es, self.data_stream) + self.idxmgmt.delete(data_streams=[self.data_stream]) def tearDown(self): - self.idxmgmt.delete(indices=[self.index_name]) + self.idxmgmt.delete(data_streams=[self.data_stream]) def render_config(self, **kwargs): self.render_config_template( @@ -153,9 +153,8 @@ def test_template_default(self): self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) proc.check_kill_and_wait() - self.idxmgmt.assert_ilm_template_loaded(self.index_name, self.beat_name, self.index_name) - self.idxmgmt.assert_alias_created(self.index_name) - self.idxmgmt.assert_docs_written_to_alias(self.index_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) + self.idxmgmt.assert_docs_written_to_data_stream(self.data_stream) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') @@ -169,7 +168,7 @@ def test_template_disabled(self): self.wait_until(lambda: self.log_contains("PublishEvents: 1 events have been published")) proc.check_kill_and_wait() - self.idxmgmt.assert_index_template_not_loaded(self.index_name) + self.idxmgmt.assert_index_template_not_loaded(self.data_stream) class TestCommandSetupTemplate(BaseTest): @@ -182,18 +181,17 @@ def setUp(self): # auto-derived default settings, if nothing else is set self.setupCmd = "--index-management" - self.index_name = self.beat_name + "-9.9.9" - self.custom_alias = self.beat_name + "_foo" + self.data_stream = self.beat_name + "-9.9.9" self.policy_name = self.beat_name self.es = self.es_client() - self.idxmgmt = IdxMgmt(self.es, self.index_name) - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name], policies=[self.policy_name]) + self.idxmgmt = IdxMgmt(self.es, self.data_stream) + self.idxmgmt.delete(indices=[self.data_stream], policies=[self.policy_name]) logging.getLogger("urllib3").setLevel(logging.WARNING) logging.getLogger("elasticsearch").setLevel(logging.ERROR) def tearDown(self): - self.idxmgmt.delete(indices=[self.custom_alias, self.index_name], policies=[self.policy_name]) + self.idxmgmt.delete(indices=[self.data_stream], policies=[self.policy_name]) def render_config(self, **kwargs): self.render_config_template( @@ -212,8 +210,7 @@ def test_setup(self): extra_args=["setup", self.setupCmd]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.index_name, self.policy_name, self.index_name) - self.idxmgmt.assert_alias_created(self.index_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -227,10 +224,9 @@ def test_setup_template_default(self): extra_args=["setup", self.setupCmd]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.index_name, self.policy_name, self.index_name) - self.idxmgmt.assert_index_template_index_pattern(self.index_name, [self.index_name + "-*"]) + self.idxmgmt.assert_index_template_loaded(self.data_stream) + self.idxmgmt.assert_index_template_index_pattern(self.data_stream, [self.data_stream]) - self.idxmgmt.assert_alias_created(self.index_name) self.idxmgmt.assert_policy_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -245,9 +241,8 @@ def test_setup_template_disabled(self): "-E", "setup.template.enabled=false"]) assert exit_code == 0 - self.idxmgmt.assert_index_template_not_loaded(self.index_name) + self.idxmgmt.assert_index_template_not_loaded(self.data_stream) - self.idxmgmt.assert_alias_created(self.index_name) self.idxmgmt.assert_policy_created(self.policy_name) @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @@ -263,28 +258,17 @@ def test_setup_template_with_opts(self): "-E", "setup.template.settings.index.number_of_shards=2"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.index_name) + self.idxmgmt.assert_index_template_loaded(self.data_stream) # check that settings are overwritten - resp = self.es.transport.perform_request('GET', '/_template/' + self.index_name) - assert self.index_name in resp - index = resp[self.index_name]["settings"]["index"] - assert index["number_of_shards"] == "2", index["number_of_shards"] - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_template_with_ilm_changed_pattern(self): - """ - Test template setup with changed ilm.rollover_alias config - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, - "-E", "setup.ilm.rollover_alias=" + self.custom_alias]) - - assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) - self.idxmgmt.assert_index_template_index_pattern(self.custom_alias, [self.custom_alias + "-*"]) + resp = self.es.transport.perform_request('GET', '/_index_template/' + self.data_stream) + found = False + for index_template in resp["index_templates"]: + if self.data_stream == index_template["name"]: + found = True + index = index_template["index_template"]["template"]["settings"]["index"] + assert index["number_of_shards"] == "2", index["number_of_shards"] + assert found @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') @@ -293,58 +277,20 @@ def test_template_created_on_ilm_policy_created(self): Test template setup overwrites template when new ilm policy is created """ - # ensure template with ilm rollover_alias name is created, but ilm policy not yet self.render_config() exit_code = self.run_beat(logging_args=["-v", "-d", "*"], extra_args=["setup", self.setupCmd, - "-E", "setup.ilm.enabled=false", - "-E", "setup.template.name=" + self.custom_alias, - "-E", "setup.template.pattern=" + self.custom_alias + "*"]) + "-E", "setup.ilm.enabled=false"]) assert exit_code == 0 - self.idxmgmt.assert_legacy_index_template_loaded(self.custom_alias) + self.idxmgmt.assert_index_template_loaded(self.data_stream) self.idxmgmt.assert_policy_not_created(self.policy_name) # ensure ilm policy is created, triggering overwriting existing template exit_code = self.run_beat(extra_args=["setup", self.setupCmd, "-E", "setup.template.overwrite=false", - "-E", "setup.template.settings.index.number_of_shards=2", - "-E", "setup.ilm.rollover_alias=" + self.custom_alias]) + "-E", "setup.template.settings.index.number_of_shards=2"]) assert exit_code == 0 - self.idxmgmt.assert_ilm_template_loaded(self.custom_alias, self.policy_name, self.custom_alias) self.idxmgmt.assert_policy_created(self.policy_name) - # check that template was overwritten - resp = self.es.transport.perform_request('GET', '/_template/' + self.custom_alias) - assert self.custom_alias in resp - index = resp[self.custom_alias]["settings"]["index"] - assert index["number_of_shards"] == "2", index["number_of_shards"] - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_template_index(self): - """ - Test template setup of new index templates - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, - "-E", "setup.template.type=index"]) - - assert exit_code == 0 - self.idxmgmt.assert_index_template_loaded(self.index_name) - - @unittest.skipUnless(INTEGRATION_TESTS, "integration test") - @pytest.mark.tag('integration') - def test_setup_template_component(self): - """ - Test template setup of component index templates - """ - self.render_config() - exit_code = self.run_beat(logging_args=["-v", "-d", "*"], - extra_args=["setup", self.setupCmd, - "-E", "setup.template.type=component"]) - - assert exit_code == 0 - self.idxmgmt.assert_component_template_loaded(self.index_name) class TestCommandExportTemplate(BaseTest): @@ -375,23 +321,7 @@ def test_default(self): config=self.config) assert exit_code == 0 - self.assert_log_contains_template(self.template_name + "-*") - - def test_changed_index_pattern(self): - """ - Test export template with changed index pattern - """ - self.render_config_template(self.beat_name, self.output, - fields=self.output) - alias_name = "mockbeat-ilm-index-pattern" - - exit_code = self.run_beat( - extra_args=["export", "template", - "-E", "setup.ilm.rollover_alias=" + alias_name], - config=self.config) - - assert exit_code == 0 - self.assert_log_contains_template(alias_name + "-*") + self.assert_log_contains_template(self.template_name) def test_load_disabled(self): """ @@ -404,7 +334,7 @@ def test_load_disabled(self): config=self.config) assert exit_code == 0 - self.assert_log_contains_template(self.template_name + "-*") + self.assert_log_contains_template(self.template_name) def test_export_to_file_absolute_path(self): """ @@ -424,7 +354,7 @@ def test_export_to_file_absolute_path(self): with open(file) as f: template = json.load(f) assert 'index_patterns' in template - assert template['index_patterns'] == [self.template_name + '-*'], template + assert template['index_patterns'] == [self.template_name], template os.remove(file) @@ -447,6 +377,6 @@ def test_export_to_file_relative_path(self): with open(file) as f: template = json.load(f) assert 'index_patterns' in template - assert template['index_patterns'] == [self.template_name + '-*'], template + assert template['index_patterns'] == [self.template_name], template os.remove(file) diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index c036073f011a..0826671a80ef 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -1988,19 +1988,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default metricbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "metricbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "metricbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "metricbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "metricbeat-%{[agent.version]}-*" +#setup.template.pattern: "metricbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -2047,17 +2041,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'metricbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'metricbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/metricbeat/tests/system/test_template.py b/metricbeat/tests/system/test_template.py index 75b366ab15d3..17df56cf552f 100644 --- a/metricbeat/tests/system/test_template.py +++ b/metricbeat/tests/system/test_template.py @@ -41,7 +41,7 @@ def test_export_template(self): break t = json.loads(template_content) - properties = t["mappings"]["properties"] + properties = t["template"]["mappings"]["properties"] # Check libbeat fields assert properties["@timestamp"] == {"type": "date"} diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 5f931ddde706..1a51aeb6b4d8 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1640,19 +1640,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default packetbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "packetbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "packetbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "packetbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "packetbeat-%{[agent.version]}-*" +#setup.template.pattern: "packetbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1699,17 +1693,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'packetbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'packetbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 305d1b5acce5..17901a0b179e 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -1074,19 +1074,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default winlogbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "winlogbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "winlogbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "winlogbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "winlogbeat-%{[agent.version]}-*" +#setup.template.pattern: "winlogbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1133,17 +1127,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'winlogbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'winlogbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index f52cc6feab15..a83cc1742e2c 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -1201,19 +1201,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default auditbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "auditbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "auditbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "auditbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "auditbeat-%{[agent.version]}-*" +#setup.template.pattern: "auditbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1260,17 +1254,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'auditbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'auditbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index fae9d78fb5da..d6694e9e700e 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -4231,19 +4231,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default filebeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "filebeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "filebeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "filebeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "filebeat-%{[agent.version]}-*" +#setup.template.pattern: "filebeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -4290,17 +4284,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'filebeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'filebeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml b/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml index 87c3deacb97c..7b30ee7d38a0 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml +++ b/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml @@ -18,9 +18,9 @@ processors: replacement: ' ' - trim: field: message -- rename: - field: '@timestamp' - target_field: event.created +- set: + copy_from: '@timestamp' + field: event.created - grok: field: message patterns: diff --git a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json index 45a57fffd05a..78b92a4d5fdc 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json +++ b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -32,6 +33,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -64,6 +66,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -96,6 +99,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -128,6 +132,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -160,6 +165,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -192,6 +198,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -224,6 +231,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -256,6 +264,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -288,6 +297,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -320,6 +330,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -352,6 +363,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -384,6 +396,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.788Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -416,6 +429,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -448,6 +462,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -480,6 +495,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -512,6 +528,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -544,6 +561,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -576,6 +594,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -608,6 +627,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -640,6 +660,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -672,6 +693,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -704,6 +726,7 @@ "user.name": "felix" }, { + "@timestamp": "2021-12-03T15:44:37.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", diff --git a/x-pack/filebeat/module/snyk/audit/config/config.yml b/x-pack/filebeat/module/snyk/audit/config/config.yml index 7476d4dd1cf9..4932c7133a13 100644 --- a/x-pack/filebeat/module/snyk/audit/config/config.yml +++ b/x-pack/filebeat/module/snyk/audit/config/config.yml @@ -67,13 +67,6 @@ processors: - fingerprint: fields: ["json.orgId", "json.created", "json.event"] target_field: "@metadata._id" - - script: - lang: javascript - id: my_filter - source: > - function process(event) { - event.Put("@metadata.op_type", "index"); - } - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/snyk/vulnerabilities/config/config.yml b/x-pack/filebeat/module/snyk/vulnerabilities/config/config.yml index a78cc297493d..318196897168 100644 --- a/x-pack/filebeat/module/snyk/vulnerabilities/config/config.yml +++ b/x-pack/filebeat/module/snyk/vulnerabilities/config/config.yml @@ -90,13 +90,6 @@ processors: - fingerprint: fields: ["json.issue.id"] target_field: "@metadata._id" - - script: - lang: javascript - id: my_filter - source: > - function process(event) { - event.Put("@metadata.op_type", "index"); - } - add_fields: target: '' fields: diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index 5ea23a3b0dbf..e41673206408 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -939,19 +939,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default functionbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "functionbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "functionbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "functionbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "functionbeat-%{[agent.version]}-*" +#setup.template.pattern: "functionbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -998,17 +992,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'functionbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'functionbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index 8f0f019626bd..c3ae5c012145 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -1291,19 +1291,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default heartbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "heartbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "heartbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "heartbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "heartbeat-%{[agent.version]}-*" +#setup.template.pattern: "heartbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1350,17 +1344,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'heartbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'heartbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 4d1d41aa0d52..e75eb46dda3b 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -2509,19 +2509,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default metricbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "metricbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "metricbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "metricbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "metricbeat-%{[agent.version]}-*" +#setup.template.pattern: "metricbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -2568,17 +2562,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'metricbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'metricbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/osquerybeat/osquerybeat.reference.yml b/x-pack/osquerybeat/osquerybeat.reference.yml index edb3adcfb1d4..a0c021361e91 100644 --- a/x-pack/osquerybeat/osquerybeat.reference.yml +++ b/x-pack/osquerybeat/osquerybeat.reference.yml @@ -658,19 +658,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default osquerybeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "osquerybeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "osquerybeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "osquerybeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "osquerybeat-%{[agent.version]}-*" +#setup.template.pattern: "osquerybeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -717,17 +711,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'osquerybeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'osquerybeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index 5f931ddde706..1a51aeb6b4d8 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -1640,19 +1640,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default packetbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "packetbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "packetbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "packetbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "packetbeat-%{[agent.version]}-*" +#setup.template.pattern: "packetbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1699,17 +1693,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'packetbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'packetbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index d6e9d30c50da..cff71187ffb7 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -1117,19 +1117,13 @@ output.elasticsearch: # Set to false to disable template loading. #setup.template.enabled: true -# Select the kind of index template. From Elasticsearch 7.8, it is possible to -# use component templates. Available options: legacy, component, index. -# By default winlogbeat uses the legacy index templates. -#setup.template.type: legacy - # Template name. By default the template name is "winlogbeat-%{[agent.version]}" # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. #setup.template.name: "winlogbeat-%{[agent.version]}" -# Template pattern. By default the template pattern is "-%{[agent.version]}-*" to apply to the default index settings. -# The first part is the version of the beat and then -* is used to match all daily indices. +# Template pattern. By default the template pattern is "winlogbeat-%{[agent.version]}" to apply to the default index settings. # The template name and pattern has to be set in case the Elasticsearch index pattern is modified. -#setup.template.pattern: "winlogbeat-%{[agent.version]}-*" +#setup.template.pattern: "winlogbeat-%{[agent.version]}" # Path to fields.yml file to generate the template #setup.template.fields: "${path.config}/fields.yml" @@ -1176,17 +1170,8 @@ setup.template.settings: # output.elasticsearch.index is ignored, and the write alias is used to set the # index name. -# Enable ILM support. Valid values are true, false, and auto. When set to auto -# (the default), the Beat uses index lifecycle management when it connects to a -# cluster that supports ILM; otherwise, it creates daily indices. -#setup.ilm.enabled: auto - -# Set the prefix used in the index lifecycle write alias name. The default alias -# name is 'winlogbeat-%{[agent.version]}'. -#setup.ilm.rollover_alias: 'winlogbeat' - -# Set the rollover index pattern. The default is "%{now/d}-000001". -#setup.ilm.pattern: "{now/d}-000001" +# Enable ILM support. Valid values are true, false. +#setup.ilm.enabled: true # Set the lifecycle policy name. The default policy name is # 'beatname'. From 27d1a6e3e7b1ae6eb75ed4a2f699c9a02bdab88d Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Mon, 6 Dec 2021 09:19:27 -0500 Subject: [PATCH 058/172] Osquerybeat: Add missing osquery top-level configuration properties for auto_table_construction, yara, prometheus_targets (#29270) --- x-pack/osquerybeat/internal/config/osquery.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/x-pack/osquerybeat/internal/config/osquery.go b/x-pack/osquerybeat/internal/config/osquery.go index 6db2ac0ca134..3bc100672c65 100644 --- a/x-pack/osquerybeat/internal/config/osquery.go +++ b/x-pack/osquerybeat/internal/config/osquery.go @@ -59,12 +59,15 @@ type Events struct { } type OsqueryConfig struct { - Options map[string]interface{} `config:"options" json:"options,omitempty"` - Schedule map[string]Query `config:"schedule" json:"schedule,omitempty"` - Packs map[string]Pack `config:"packs" json:"packs,omitempty"` - Filepaths map[string][]string `config:"file_paths" json:"file_paths,omitempty"` - Views map[string]string `config:"views" json:"views,omitempty"` - Events *Events `config:"events" json:"events,omitempty"` + Options map[string]interface{} `config:"options" json:"options,omitempty"` + Schedule map[string]Query `config:"schedule" json:"schedule,omitempty"` + Packs map[string]Pack `config:"packs" json:"packs,omitempty"` + Filepaths map[string][]string `config:"file_paths" json:"file_paths,omitempty"` + Views map[string]string `config:"views" json:"views,omitempty"` + Events *Events `config:"events" json:"events,omitempty"` + Yara map[string]interface{} `config:"yara" json:"yara,omitempty"` + PrometheusTargets map[string]interface{} `config:"prometheus_targets" json:"prometheus_targets,omitempty"` + AutoTableConstruction map[string]interface{} `config:"auto_table_construction" json:"auto_table_construction,omitempty"` } func (c OsqueryConfig) Render() ([]byte, error) { From 191a0752b5ceddc7b7657a517b90ca76c1350f30 Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Mon, 6 Dec 2021 19:15:06 +0000 Subject: [PATCH 059/172] Support self-signed certificate on outputs (#29229) Adds ssl.ca_trusted_fingerprint option, if set to the HEX fingerprint of a root CA certificate, this certificate is added to the trusted CAs (as if it was defined on ssl.certificate_authorities), then the SSL validation continues as normal. This happens during the SSL handshake. --- CHANGELOG.next.asciidoc | 1 + auditbeat/auditbeat.reference.yml | 42 ++++++++++++++++ filebeat/filebeat.reference.yml | 42 ++++++++++++++++ heartbeat/heartbeat.reference.yml | 42 ++++++++++++++++ libbeat/_meta/config/ssl.reference.yml.tmpl | 7 +++ libbeat/common/transport/tlscommon/config.go | 36 ++++++------- .../common/transport/tlscommon/tls_config.go | 50 ++++++++++++++++++- libbeat/docs/shared-ssl-config.asciidoc | 9 ++++ metricbeat/metricbeat.reference.yml | 42 ++++++++++++++++ packetbeat/packetbeat.reference.yml | 42 ++++++++++++++++ winlogbeat/winlogbeat.reference.yml | 42 ++++++++++++++++ x-pack/auditbeat/auditbeat.reference.yml | 42 ++++++++++++++++ x-pack/filebeat/filebeat.reference.yml | 42 ++++++++++++++++ .../functionbeat/functionbeat.reference.yml | 28 +++++++++++ x-pack/heartbeat/heartbeat.reference.yml | 42 ++++++++++++++++ x-pack/metricbeat/metricbeat.reference.yml | 42 ++++++++++++++++ x-pack/osquerybeat/osquerybeat.reference.yml | 28 +++++++++++ x-pack/packetbeat/packetbeat.reference.yml | 42 ++++++++++++++++ x-pack/winlogbeat/winlogbeat.reference.yml | 42 ++++++++++++++++ 19 files changed, 645 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 0ad71e056376..3e59467780b5 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -295,6 +295,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add http.pprof.enabled option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] - Support custom analyzers in fields.yml. {issue}28540[28540] {pull}28926[28926] - SASL/SCRAM in the Kafka output is no longer beta. {pull}29126[29126] +- Support self signed certificates on outputs {pull}29229[29229] *Auditbeat* diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index fc685b6c231a..544cd80ade25 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -513,6 +513,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -645,6 +652,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -846,6 +860,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1010,6 +1031,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1297,6 +1325,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1495,6 +1530,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index a8217924d4dd..b63760c63dd4 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -1446,6 +1446,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1578,6 +1585,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -1779,6 +1793,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1943,6 +1964,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -2230,6 +2258,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -2428,6 +2463,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index c3ae5c012145..76dcc7758b9e 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -659,6 +659,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -791,6 +798,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -992,6 +1006,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1156,6 +1177,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1443,6 +1471,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1641,6 +1676,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/libbeat/_meta/config/ssl.reference.yml.tmpl b/libbeat/_meta/config/ssl.reference.yml.tmpl index 65920fb646f0..e6928c894fad 100644 --- a/libbeat/_meta/config/ssl.reference.yml.tmpl +++ b/libbeat/_meta/config/ssl.reference.yml.tmpl @@ -50,3 +50,10 @@ # # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + +# A root CA HEX encoded fingerprint. During the SSL handshake if the +# fingerprint matches the root CA certificate, it will be added to +# the provided list of root CAs (`certificate_authorities`), if the +# list is empty or not defined, the matching certificate will be the +# only one in the list. Then the normal SSL validation happens. +#ssl.ca_trusted_fingerprint: "" diff --git a/libbeat/common/transport/tlscommon/config.go b/libbeat/common/transport/tlscommon/config.go index 41d1ad6532ce..0bb2e35c20c1 100644 --- a/libbeat/common/transport/tlscommon/config.go +++ b/libbeat/common/transport/tlscommon/config.go @@ -30,15 +30,16 @@ var warnOnce sync.Once // Config defines the user configurable options in the yaml file. type Config struct { - Enabled *bool `config:"enabled" yaml:"enabled,omitempty"` - VerificationMode TLSVerificationMode `config:"verification_mode" yaml:"verification_mode"` // one of 'none', 'full' - Versions []TLSVersion `config:"supported_protocols" yaml:"supported_protocols,omitempty"` - CipherSuites []CipherSuite `config:"cipher_suites" yaml:"cipher_suites,omitempty"` - CAs []string `config:"certificate_authorities" yaml:"certificate_authorities,omitempty"` - Certificate CertificateConfig `config:",inline" yaml:",inline"` - CurveTypes []tlsCurveType `config:"curve_types" yaml:"curve_types,omitempty"` - Renegotiation TlsRenegotiationSupport `config:"renegotiation" yaml:"renegotiation"` - CASha256 []string `config:"ca_sha256" yaml:"ca_sha256,omitempty"` + Enabled *bool `config:"enabled" yaml:"enabled,omitempty"` + VerificationMode TLSVerificationMode `config:"verification_mode" yaml:"verification_mode"` // one of 'none', 'full' + Versions []TLSVersion `config:"supported_protocols" yaml:"supported_protocols,omitempty"` + CipherSuites []CipherSuite `config:"cipher_suites" yaml:"cipher_suites,omitempty"` + CAs []string `config:"certificate_authorities" yaml:"certificate_authorities,omitempty"` + Certificate CertificateConfig `config:",inline" yaml:",inline"` + CurveTypes []tlsCurveType `config:"curve_types" yaml:"curve_types,omitempty"` + Renegotiation TlsRenegotiationSupport `config:"renegotiation" yaml:"renegotiation"` + CASha256 []string `config:"ca_sha256" yaml:"ca_sha256,omitempty"` + CATrustedFingerprint string `config:"ca_trusted_fingerprint" yaml:"ca_trusted_fingerprint,omitempty"` } // LoadTLSConfig will load a certificate from config with all TLS based keys @@ -82,14 +83,15 @@ func LoadTLSConfig(config *Config) (*TLSConfig, error) { // return config if no error occurred return &TLSConfig{ - Versions: config.Versions, - Verification: config.VerificationMode, - Certificates: certs, - RootCAs: cas, - CipherSuites: config.CipherSuites, - CurvePreferences: curves, - Renegotiation: tls.RenegotiationSupport(config.Renegotiation), - CASha256: config.CASha256, + Versions: config.Versions, + Verification: config.VerificationMode, + Certificates: certs, + RootCAs: cas, + CipherSuites: config.CipherSuites, + CurvePreferences: curves, + Renegotiation: tls.RenegotiationSupport(config.Renegotiation), + CASha256: config.CASha256, + CATrustedFingerprint: config.CATrustedFingerprint, }, nil } diff --git a/libbeat/common/transport/tlscommon/tls_config.go b/libbeat/common/transport/tlscommon/tls_config.go index 77c60f951f84..6f097876ec7e 100644 --- a/libbeat/common/transport/tlscommon/tls_config.go +++ b/libbeat/common/transport/tlscommon/tls_config.go @@ -18,8 +18,11 @@ package tlscommon import ( + "bytes" + "crypto/sha256" "crypto/tls" "crypto/x509" + "encoding/hex" "fmt" "net" "time" @@ -74,6 +77,10 @@ type TLSConfig struct { // the server certificate. CASha256 []string + // CATrustedFingerprint is the HEX encoded fingerprint of a CA certificate. If present in the chain + // this certificate will be added to the list of trusted CAs (RootCAs) during the handshake. + CATrustedFingerprint string `config:"ca_trusted_fingerprint" yaml:"ca_trusted_fingerprint,omitempty"` + // time returns the current time as the number of seconds since the epoch. // If time is nil, TLS uses time.Now. time func() time.Time @@ -151,10 +158,42 @@ func (c *TLSConfig) BuildServerConfig(host string) *tls.Config { return config } +func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error { + fingerprint, err := hex.DecodeString(cfg.CATrustedFingerprint) + if err != nil { + return fmt.Errorf("decode fingerprint: %w", err) + } + + for _, cert := range peerCerts { + // Compute digest for each certificate. + digest := sha256.Sum256(cert.Raw) + + if bytes.Equal(digest[0:], fingerprint) { + // Make sure the fingerprint matches a CA certificate + if cert.IsCA { + if cfg.RootCAs == nil { + cfg.RootCAs = x509.NewCertPool() + } + + cfg.RootCAs.AddCert(cert) + return nil + } + } + } + + logp.NewLogger("tls").Warn("no CA certificate matching the fingerprint") + return nil +} + func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error { switch cfg.Verification { case VerifyFull: return func(cs tls.ConnectionState) error { + if cfg.CATrustedFingerprint != "" { + if err := trustRootCA(cfg, cs.PeerCertificates); err != nil { + return err + } + } // On the client side, PeerCertificates can't be empty. if len(cs.PeerCertificates) == 0 { return MissingPeerCertificate @@ -172,6 +211,11 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error { } case VerifyCertificate: return func(cs tls.ConnectionState) error { + if cfg.CATrustedFingerprint != "" { + if err := trustRootCA(cfg, cs.PeerCertificates); err != nil { + return err + } + } // On the client side, PeerCertificates can't be empty. if len(cs.PeerCertificates) == 0 { return MissingPeerCertificate @@ -186,6 +230,11 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error { case VerifyStrict: if len(cfg.CASha256) > 0 { return func(cs tls.ConnectionState) error { + if cfg.CATrustedFingerprint != "" { + if err := trustRootCA(cfg, cs.PeerCertificates); err != nil { + return err + } + } return verifyCAPin(cfg.CASha256, cs.VerifiedChains) } } @@ -193,7 +242,6 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error { } return nil - } func makeVerifyServerConnection(cfg *TLSConfig) func(tls.ConnectionState) error { diff --git a/libbeat/docs/shared-ssl-config.asciidoc b/libbeat/docs/shared-ssl-config.asciidoc index 1c20e6b85658..97a2605ef4ba 100644 --- a/libbeat/docs/shared-ssl-config.asciidoc +++ b/libbeat/docs/shared-ssl-config.asciidoc @@ -377,6 +377,15 @@ production environments is strongly discouraged. + The default value is `full`. +[float] +[[ca_trusted_fingerprint]] +==== `ca_trusted_fingerprint` +A HEX encoded SHA-256 of a CA certificate. If this certificate is +present in the chain during the handshake, it will be added to the +`certificate_authorities` list and the handshake will continue +normaly. + + [discrete] [[ssl-server-config]] === Server configuration options diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 0826671a80ef..d25c61ab5f07 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -1356,6 +1356,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1488,6 +1495,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -1689,6 +1703,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1853,6 +1874,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -2140,6 +2168,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -2338,6 +2373,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 1a51aeb6b4d8..3d9d0f604bf7 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1008,6 +1008,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1140,6 +1147,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -1341,6 +1355,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1505,6 +1526,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1792,6 +1820,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1990,6 +2025,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 17901a0b179e..afa6ec97eb39 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -442,6 +442,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -574,6 +581,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -775,6 +789,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -939,6 +960,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1226,6 +1254,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1424,6 +1459,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index a83cc1742e2c..5219627ac63c 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -569,6 +569,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -701,6 +708,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -902,6 +916,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1066,6 +1087,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1353,6 +1381,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1551,6 +1586,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index d6694e9e700e..8a8fdeb360fe 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -3599,6 +3599,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -3731,6 +3738,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -3932,6 +3946,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -4096,6 +4117,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -4383,6 +4411,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -4581,6 +4616,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index e41673206408..090ab1cc8779 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -691,6 +691,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -823,6 +830,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -1091,6 +1105,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1289,6 +1310,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index c3ae5c012145..76dcc7758b9e 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -659,6 +659,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -791,6 +798,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -992,6 +1006,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1156,6 +1177,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1443,6 +1471,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1641,6 +1676,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index e75eb46dda3b..f219b056d099 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -1877,6 +1877,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -2009,6 +2016,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -2210,6 +2224,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -2374,6 +2395,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -2661,6 +2689,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -2859,6 +2894,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/osquerybeat/osquerybeat.reference.yml b/x-pack/osquerybeat/osquerybeat.reference.yml index a0c021361e91..53f7f52f9225 100644 --- a/x-pack/osquerybeat/osquerybeat.reference.yml +++ b/x-pack/osquerybeat/osquerybeat.reference.yml @@ -410,6 +410,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -542,6 +549,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -810,6 +824,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1008,6 +1029,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index 1a51aeb6b4d8..3d9d0f604bf7 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -1008,6 +1008,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1140,6 +1147,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -1341,6 +1355,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -1505,6 +1526,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1792,6 +1820,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1990,6 +2025,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index cff71187ffb7..8d9d4ef25669 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -485,6 +485,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -617,6 +624,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # The number of times to retry publishing an event after a publishing failure. # After the specified number of retries, the events are typically dropped. # Some Beats, such as Filebeat and Winlogbeat, ignore the max_retries setting @@ -818,6 +832,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true @@ -982,6 +1003,13 @@ output.elasticsearch: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # -------------------------------- File Output --------------------------------- #output.file: @@ -1269,6 +1297,13 @@ setup.kibana: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # ================================== Logging =================================== @@ -1467,6 +1502,13 @@ logging.files: # The pin is a base64 encoded string of the SHA-256 fingerprint. #ssl.ca_sha256: "" + # A root CA HEX encoded fingerprint. During the SSL handshake if the + # fingerprint matches the root CA certificate, it will be added to + # the provided list of root CAs (`certificate_authorities`), if the + # list is empty or not defined, the matching certificate will be the + # only one in the list. Then the normal SSL validation happens. + #ssl.ca_trusted_fingerprint: "" + # Enable Kerberos support. Kerberos is automatically enabled if any Kerberos setting is set. #kerberos.enabled: true From b233ea59b3e327f6c23a5cdfb6ebc3d44a0bc274 Mon Sep 17 00:00:00 2001 From: stuart nelson Date: Tue, 7 Dec 2021 11:55:59 +0100 Subject: [PATCH 060/172] [elastic-agent] stop syncing apm ingest folder (#29311) in 8.0 the apm tarball no longer includes an ingest folder --- x-pack/elastic-agent/pkg/agent/cmd/container.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index e7a64cec1932..e0f9f3dcfb70 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -670,12 +670,6 @@ func runLegacyAPMServer(streams *cli.IOStreams, path string) (*process.Info, err return nil, errors.New("expected one directory") } apmDir := filepath.Join(path, files[0].Name()) - // Extract the ingest pipeline definition to the HOME_DIR - if home := os.Getenv("HOME_PATH"); home != "" { - if err := syncDir(filepath.Join(apmDir, "ingest"), filepath.Join(home, "ingest")); err != nil { - return nil, fmt.Errorf("syncing APM ingest directory to HOME_PATH(%s) failed: %s", home, err) - } - } // Start apm-server process respecting path ENVs apmBinary := filepath.Join(apmDir, spec.Cmd) log, err := logger.New("apm-server", false) From db9b4104d8399a7e2fc7a92093d61efb413e159b Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Tue, 7 Dec 2021 13:53:10 +0000 Subject: [PATCH 061/172] Add logs for ca_trusted_fingerprint workflow (#29312) This commit adds logs to clearly show when Beats is trusting a self-signed certificate through the fingerprint provided by `ssl.ca_trusted_fingerprint`. It also cleans up some struct tags on `tlscommon.TLSConfig`. --- libbeat/common/transport/tlscommon/tls_config.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libbeat/common/transport/tlscommon/tls_config.go b/libbeat/common/transport/tlscommon/tls_config.go index 6f097876ec7e..64fcf62e47dc 100644 --- a/libbeat/common/transport/tlscommon/tls_config.go +++ b/libbeat/common/transport/tlscommon/tls_config.go @@ -79,7 +79,7 @@ type TLSConfig struct { // CATrustedFingerprint is the HEX encoded fingerprint of a CA certificate. If present in the chain // this certificate will be added to the list of trusted CAs (RootCAs) during the handshake. - CATrustedFingerprint string `config:"ca_trusted_fingerprint" yaml:"ca_trusted_fingerprint,omitempty"` + CATrustedFingerprint string // time returns the current time as the number of seconds since the epoch. // If time is nil, TLS uses time.Now. @@ -159,9 +159,11 @@ func (c *TLSConfig) BuildServerConfig(host string) *tls.Config { } func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error { + logger := logp.NewLogger("tls") + logger.Info("'ca_trusted_fingerprint' set, looking for matching fingerprints") fingerprint, err := hex.DecodeString(cfg.CATrustedFingerprint) if err != nil { - return fmt.Errorf("decode fingerprint: %w", err) + return fmt.Errorf("decode 'ca_trusted_fingerprint': %w", err) } for _, cert := range peerCerts { @@ -169,6 +171,7 @@ func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error { digest := sha256.Sum256(cert.Raw) if bytes.Equal(digest[0:], fingerprint) { + logger.Info("CA certificate matching 'ca_trusted_fingerprint' found, adding it to 'certificate_authorities'") // Make sure the fingerprint matches a CA certificate if cert.IsCA { if cfg.RootCAs == nil { @@ -181,7 +184,7 @@ func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error { } } - logp.NewLogger("tls").Warn("no CA certificate matching the fingerprint") + logger.Warn("no CA certificate matching the fingerprint") return nil } From 16d587b7338b5d37bf5ad81cb58c2311d7996182 Mon Sep 17 00:00:00 2001 From: Fae Charlton Date: Tue, 7 Dec 2021 10:27:19 -0500 Subject: [PATCH 062/172] libbeat publisher pipeline cleanups (#28206) --- libbeat/outputs/outest/batch.go | 5 - libbeat/publisher/event.go | 14 +- libbeat/publisher/pipeline/client.go | 1 - .../pipeline/{output.go => client_worker.go} | 10 +- .../{output_test.go => client_worker_test.go} | 30 +- libbeat/publisher/pipeline/consumer.go | 303 +++++++++--------- libbeat/publisher/pipeline/controller.go | 75 ++--- libbeat/publisher/pipeline/monitoring.go | 25 -- libbeat/publisher/pipeline/pipeline.go | 4 - libbeat/publisher/pipeline/queue_reader.go | 63 ++++ libbeat/publisher/pipeline/retry.go | 231 ------------- libbeat/publisher/pipeline/testing.go | 95 +++--- .../pipeline/{batch.go => ttl_batch.go} | 78 ++--- libbeat/publisher/pipeline/util.go | 55 ---- 14 files changed, 363 insertions(+), 626 deletions(-) rename libbeat/publisher/pipeline/{output.go => client_worker.go} (93%) rename libbeat/publisher/pipeline/{output_test.go => client_worker_test.go} (91%) create mode 100644 libbeat/publisher/pipeline/queue_reader.go delete mode 100644 libbeat/publisher/pipeline/retry.go rename libbeat/publisher/pipeline/{batch.go => ttl_batch.go} (63%) delete mode 100644 libbeat/publisher/pipeline/util.go diff --git a/libbeat/outputs/outest/batch.go b/libbeat/outputs/outest/batch.go index 11d4bf1a2667..4aeab9cbb5f3 100644 --- a/libbeat/outputs/outest/batch.go +++ b/libbeat/outputs/outest/batch.go @@ -41,7 +41,6 @@ const ( BatchRetry BatchRetryEvents BatchCancelled - BatchCancelledEvents ) func NewBatch(in ...beat.Event) *Batch { @@ -76,10 +75,6 @@ func (b *Batch) Cancelled() { b.doSignal(BatchSignal{Tag: BatchCancelled}) } -func (b *Batch) CancelledEvents(events []publisher.Event) { - b.doSignal(BatchSignal{Tag: BatchCancelledEvents, Events: events}) -} - func (b *Batch) doSignal(sig BatchSignal) { b.Signals = append(b.Signals, sig) if b.OnSignal != nil { diff --git a/libbeat/publisher/event.go b/libbeat/publisher/event.go index 29625319e7c1..e127d012d87d 100644 --- a/libbeat/publisher/event.go +++ b/libbeat/publisher/event.go @@ -24,17 +24,25 @@ import ( // Batch is used to pass a batch of events to the outputs and asynchronously listening // for signals from these outpts. After a batch is processed (completed or -// errors), one of the signal methods must be called. +// errors), one of the signal methods must be called. In normal operation +// every batch will eventually receive an ACK() or a Drop(). type Batch interface { Events() []Event - // signals + // All events have been acknowledged by the output. ACK() + + // Give up on these events permanently without sending. Drop() + + // Try sending this batch again Retry() + + // Try sending the events in this list again; all others are acknowledged. RetryEvents(events []Event) + + // Send was aborted, try again but don't decrease the batch's TTL counter. Cancelled() - CancelledEvents(events []Event) } // Event is used by the publisher pipeline and broker to pass additional diff --git a/libbeat/publisher/pipeline/client.go b/libbeat/publisher/pipeline/client.go index edb5a3f1eb35..29d243257d1c 100644 --- a/libbeat/publisher/pipeline/client.go +++ b/libbeat/publisher/pipeline/client.go @@ -201,7 +201,6 @@ func (c *client) logger() *logp.Logger { } func (c *client) onClosing() { - c.pipeline.observer.clientClosing() if c.eventer != nil { c.eventer.Closing() } diff --git a/libbeat/publisher/pipeline/output.go b/libbeat/publisher/pipeline/client_worker.go similarity index 93% rename from libbeat/publisher/pipeline/output.go rename to libbeat/publisher/pipeline/client_worker.go index 00c3fc542819..008d774303d5 100644 --- a/libbeat/publisher/pipeline/output.go +++ b/libbeat/publisher/pipeline/client_worker.go @@ -29,9 +29,8 @@ import ( ) type worker struct { - id uint observer outputObserver - qu workQueue + qu chan publisher.Batch done chan struct{} } @@ -46,14 +45,12 @@ type netClientWorker struct { worker client outputs.NetworkClient - batchSize int - batchSizer func() int - logger logger + logger logger tracer *apm.Tracer } -func makeClientWorker(observer outputObserver, qu workQueue, client outputs.Client, logger logger, tracer *apm.Tracer) outputWorker { +func makeClientWorker(observer outputObserver, qu chan publisher.Batch, client outputs.Client, logger logger, tracer *apm.Tracer) outputWorker { w := worker{ observer: observer, qu: qu, @@ -102,7 +99,6 @@ func (w *clientWorker) run() { if batch == nil { continue } - w.observer.outBatchSend(len(batch.Events())) if err := w.client.Publish(context.TODO(), batch); err != nil { return } diff --git a/libbeat/publisher/pipeline/output_test.go b/libbeat/publisher/pipeline/client_worker_test.go similarity index 91% rename from libbeat/publisher/pipeline/output_test.go rename to libbeat/publisher/pipeline/client_worker_test.go index 7bde6e137ab8..921847ab0be8 100644 --- a/libbeat/publisher/pipeline/output_test.go +++ b/libbeat/publisher/pipeline/client_worker_test.go @@ -52,8 +52,8 @@ func TestMakeClientWorker(t *testing.T) { logger := makeBufLogger(t) - wqu := makeWorkQueue() - retryer := newRetryer(logger, nilObserver, wqu, nil) + workQueue := make(chan publisher.Batch) + retryer := newStandaloneRetryer(workQueue) defer retryer.close() var published atomic.Uint @@ -64,13 +64,13 @@ func TestMakeClientWorker(t *testing.T) { client := ctor(publishFn) - worker := makeClientWorker(nilObserver, wqu, client, logger, nil) + worker := makeClientWorker(nilObserver, workQueue, client, logger, nil) defer worker.Close() for i := uint(0); i < numBatches; i++ { batch := randomBatch(50, 150).withRetryer(retryer) numEvents += uint(len(batch.Events())) - wqu <- batch + workQueue <- batch } // Give some time for events to be published @@ -114,14 +114,16 @@ func TestReplaceClientWorker(t *testing.T) { logger := makeBufLogger(t) - wqu := makeWorkQueue() - retryer := newRetryer(logger, nilObserver, wqu, nil) + workQueue := make(chan publisher.Batch) + retryer := newStandaloneRetryer(workQueue) defer retryer.close() var batches []publisher.Batch var numEvents int for i := uint(0); i < numBatches; i++ { - batch := randomBatch(minEventsInBatch, maxEventsInBatch).withRetryer(retryer) + batch := randomBatch( + minEventsInBatch, maxEventsInBatch, + ).withRetryer(retryer) batch.events[0].Content.Private = i numEvents += batch.Len() batches = append(batches, batch) @@ -133,7 +135,7 @@ func TestReplaceClientWorker(t *testing.T) { defer wg.Done() for _, batch := range batches { t.Logf("publish batch: %v", batch.(*mockBatch).events[0].Content.Private) - wqu <- batch + workQueue <- batch } }() @@ -156,7 +158,7 @@ func TestReplaceClientWorker(t *testing.T) { } client := ctor(blockingPublishFn) - worker := makeClientWorker(nilObserver, wqu, client, logger, nil) + worker := makeClientWorker(nilObserver, workQueue, client, logger, nil) // Allow the worker to make *some* progress before we close it timeout := 10 * time.Second @@ -183,7 +185,7 @@ func TestReplaceClientWorker(t *testing.T) { } client = ctor(countingPublishFn) - makeClientWorker(nilObserver, wqu, client, logger, nil) + makeClientWorker(nilObserver, workQueue, client, logger, nil) wg.Wait() // Make sure that all events have eventually been published @@ -214,8 +216,8 @@ func TestMakeClientTracer(t *testing.T) { logger := makeBufLogger(t) - wqu := makeWorkQueue() - retryer := newRetryer(logger, nilObserver, wqu, nil) + workQueue := make(chan publisher.Batch) + retryer := newStandaloneRetryer(workQueue) defer retryer.close() var published atomic.Uint @@ -229,13 +231,13 @@ func TestMakeClientTracer(t *testing.T) { recorder := apmtest.NewRecordingTracer() defer recorder.Close() - worker := makeClientWorker(nilObserver, wqu, client, logger, recorder.Tracer) + worker := makeClientWorker(nilObserver, workQueue, client, logger, recorder.Tracer) defer worker.Close() for i := 0; i < numBatches; i++ { batch := randomBatch(10, 15).withRetryer(retryer) numEvents += uint(len(batch.Events())) - wqu <- batch + workQueue <- batch } // Give some time for events to be published diff --git a/libbeat/publisher/pipeline/consumer.go b/libbeat/publisher/pipeline/consumer.go index d8f4288b011f..242cb62409bd 100644 --- a/libbeat/publisher/pipeline/consumer.go +++ b/libbeat/publisher/pipeline/consumer.go @@ -18,206 +18,221 @@ package pipeline import ( - "errors" "sync" - "github.com/elastic/beats/v7/libbeat/common/atomic" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/publisher" "github.com/elastic/beats/v7/libbeat/publisher/queue" ) // eventConsumer collects and forwards events from the queue to the outputs work queue. -// The eventConsumer is managed by the controller and receives additional pause signals -// from the retryer in case of too many events failing to be send or if retryer -// is receiving cancelled batches from outputs to be closed on output reloading. +// It accepts retry requests from batches it vends, which will resend them +// to the next available output. type eventConsumer struct { logger *logp.Logger - ctx *batchContext - pause atomic.Bool - wait atomic.Bool - sig chan consumerSignal - wg sync.WaitGroup + // eventConsumer calls the observer methods eventsRetry and eventsDropped. + observer outputObserver - queue queue.Queue - consumer queue.Consumer + // When the output changes, the new target is sent to the worker routine + // on this channel. Clients should call eventConsumer.setTarget(). + targetChan chan consumerTarget - out *outputGroup -} + // Failed batches are sent to this channel to retry. Clients should call + // eventConsumer.retry(). + retryChan chan retryRequest -type consumerSignal struct { - tag consumerEventTag - consumer queue.Consumer - out *outputGroup -} + // Closing this channel signals consumer shutdown. Clients should call + // eventConsumer.close(). + done chan struct{} -type consumerEventTag uint8 + // This waitgroup is released when this eventConsumer's worker + // goroutines return. + wg sync.WaitGroup -const ( - sigConsumerCheck consumerEventTag = iota - sigConsumerUpdateOutput - sigConsumerUpdateInput - sigStop -) + // The queue the eventConsumer will retrieve batches from. + queue queue.Queue +} -var errStopped = errors.New("stopped") +// consumerTarget specifies the output channel and parameters needed for +// eventConsumer to generate a batch. +type consumerTarget struct { + ch chan publisher.Batch + timeToLive int + batchSize int +} + +// retryRequest is used by ttlBatch to add itself back to the eventConsumer +// queue for distribution to an output. +type retryRequest struct { + batch *ttlBatch + decreaseTTL bool +} func newEventConsumer( log *logp.Logger, queue queue.Queue, - ctx *batchContext, + observer outputObserver, ) *eventConsumer { - consumer := queue.Consumer() c := &eventConsumer{ - logger: log, - sig: make(chan consumerSignal, 3), - out: nil, - + logger: log, + observer: observer, queue: queue, - consumer: consumer, - ctx: ctx, - } - c.pause.Store(true) + targetChan: make(chan consumerTarget), + retryChan: make(chan retryRequest), + done: make(chan struct{}), + } c.wg.Add(1) go func() { defer c.wg.Done() - c.loop(consumer) + c.run() }() return c } -func (c *eventConsumer) close() { - c.consumer.Close() - c.sig <- consumerSignal{tag: sigStop} - c.wg.Wait() -} +func (c *eventConsumer) run() { + log := c.logger -func (c *eventConsumer) sigWait() { - c.wait.Store(true) - c.sigHint() -} + log.Debug("start pipeline event consumer") -func (c *eventConsumer) sigUnWait() { - c.wait.Store(false) - c.sigHint() -} + // Create a queueReader to run our queue fetches in the background + c.wg.Add(1) + queueReader := makeQueueReader() + go func() { + defer c.wg.Done() + queueReader.run(log) + }() -func (c *eventConsumer) sigPause() { - c.pause.Store(true) - c.sigHint() -} + var ( + // Whether there's an outstanding request to queueReader + pendingRead bool -func (c *eventConsumer) sigContinue() { - c.pause.Store(false) - c.sigHint() -} + // The batches waiting to be retried. + retryBatches []*ttlBatch -func (c *eventConsumer) sigHint() { - // send signal to unblock a consumer trying to publish events. - // With flags being set atomically, multiple signals can be compressed into one - // signal -> drop if queue is not empty - select { - case c.sig <- consumerSignal{tag: sigConsumerCheck}: - default: - } -} + // The batch read from the queue and waiting to be sent, if any + queueBatch *ttlBatch -func (c *eventConsumer) updOutput(grp *outputGroup) { - // close consumer to break consumer worker from pipeline - c.consumer.Close() + // The output channel (and associated parameters) that will receive + // the batches we're loading. + target consumerTarget - // update output - c.sig <- consumerSignal{ - tag: sigConsumerUpdateOutput, - out: grp, - } + // The queue.Consumer we get the raw batches from. Reset whenever + // the target changes. + consumer queue.Consumer = c.queue.Consumer() + ) - // update eventConsumer with new queue connection - c.consumer = c.queue.Consumer() - c.sig <- consumerSignal{ - tag: sigConsumerUpdateInput, - consumer: c.consumer, - } -} +outerLoop: + for { + // If possible, start reading the next batch in the background. + if queueBatch == nil && !pendingRead { + pendingRead = true + queueReader.req <- queueReaderRequest{ + consumer: consumer, + retryer: c, + batchSize: target.batchSize, + timeToLive: target.timeToLive, + } + } -func (c *eventConsumer) loop(consumer queue.Consumer) { - log := c.logger + var active *ttlBatch + // Choose the active batch: if we have batches to retry, use the first + // one. Otherwise, use a new batch if we have one. + if len(retryBatches) > 0 { + active = retryBatches[0] + } else if queueBatch != nil { + active = queueBatch + } - log.Debug("start pipeline event consumer") + // If we have a batch, we'll point the output channel at the target + // and try to send to it. Otherwise, it will remain nil, and sends + // to it will always block, so the output case of the select below + // will be ignored. + var outputChan chan publisher.Batch + if active != nil { + outputChan = target.ch + } - var ( - out workQueue - batch Batch - paused = true - ) + // Now we can block until the next state change. + select { + case outputChan <- active: + // Successfully sent a batch to the output workers + if len(retryBatches) > 0 { + // This was a retry, report it to the observer + c.observer.eventsRetry(len(active.Events())) + retryBatches = retryBatches[1:] + } else { + // This was directly from the queue, clear the value so we can + // fetch a new one + queueBatch = nil + } - handleSignal := func(sig consumerSignal) error { - switch sig.tag { - case sigStop: - return errStopped + case target = <-c.targetChan: - case sigConsumerCheck: + case queueBatch = <-queueReader.resp: + pendingRead = false - case sigConsumerUpdateOutput: - c.out = sig.out + case req := <-c.retryChan: + alive := true + if req.decreaseTTL { + countFailed := len(req.batch.Events()) - case sigConsumerUpdateInput: - consumer = sig.consumer - } + alive = req.batch.reduceTTL() - paused = c.paused() - if c.out != nil && batch != nil { - out = c.out.workQueue - } else { - out = nil - } - return nil - } + countDropped := countFailed - len(req.batch.Events()) + c.observer.eventsDropped(countDropped) - for { - if !paused && c.out != nil && consumer != nil && batch == nil { - out = c.out.workQueue - queueBatch, err := consumer.Get(c.out.batchSize) - if err != nil { - out = nil - consumer = nil - continue - } - if queueBatch != nil { - batch = newBatch(c.ctx, queueBatch, c.out.timeToLive) + if !alive { + log.Info("Drop batch") + req.batch.Drop() + continue + } } + retryBatches = append(retryBatches, req.batch) - paused = c.paused() - if paused || batch == nil { - out = nil - } + case <-c.done: + break outerLoop } + } - select { - case sig := <-c.sig: - if err := handleSignal(sig); err != nil { - return - } - continue - default: - } + // Close the queue.Consumer, otherwise queueReader can get blocked + // waiting on a read. + consumer.Close() - select { - case sig := <-c.sig: - if err := handleSignal(sig); err != nil { - return - } - case out <- batch: - batch = nil - if paused { - out = nil - } + // Close the queueReader request channel so it knows to shutdown. + close(queueReader.req) + + // If there's an outstanding request, we need to read the response + // to unblock it, but we won't pass on the value. + if pendingRead { + batch := <-queueReader.resp + if batch != nil { + // Inform any listeners that we couldn't deliver this batch. + batch.Drop() } } } -func (c *eventConsumer) paused() bool { - return c.pause.Load() || c.wait.Load() +func (c *eventConsumer) setTarget(target consumerTarget) { + select { + case c.targetChan <- target: + case <-c.done: + } +} + +func (c *eventConsumer) retry(batch *ttlBatch, decreaseTTL bool) { + select { + case c.retryChan <- retryRequest{batch: batch, decreaseTTL: decreaseTTL}: + // The batch is back in eventConsumer's retry queue + case <-c.done: + // The consumer has already shut down, drop the batch + batch.Drop() + } +} + +func (c *eventConsumer) close() { + close(c.done) + c.wg.Wait() } diff --git a/libbeat/publisher/pipeline/controller.go b/libbeat/publisher/pipeline/controller.go index 2a15ea86e166..3a7089e0f819 100644 --- a/libbeat/publisher/pipeline/controller.go +++ b/libbeat/publisher/pipeline/controller.go @@ -36,25 +36,24 @@ type outputController struct { monitors Monitors observer outputObserver - queue queue.Queue - workQueue workQueue + workQueue chan publisher.Batch - retryer *retryer consumer *eventConsumer out *outputGroup } // outputGroup configures a group of load balanced outputs with shared work queue. type outputGroup struct { - workQueue workQueue + // workQueue is a channel that receives event batches that + // are ready to send. Each output worker in outputs reads from + // workQueue for events to send. + workQueue chan publisher.Batch outputs []outputWorker batchSize int timeToLive int // event lifetime } -type workQueue chan publisher.Batch - // outputWorker instances pass events from the shared workQueue to the outputs.Client // instances. type outputWorker interface { @@ -67,29 +66,17 @@ func newOutputController( observer outputObserver, queue queue.Queue, ) *outputController { - c := &outputController{ + return &outputController{ beat: beat, monitors: monitors, observer: observer, - queue: queue, - workQueue: makeWorkQueue(), + workQueue: make(chan publisher.Batch), + consumer: newEventConsumer(monitors.Logger, queue, observer), } - - ctx := &batchContext{} - c.consumer = newEventConsumer(monitors.Logger, queue, ctx) - c.retryer = newRetryer(monitors.Logger, observer, c.workQueue, c.consumer) - ctx.observer = observer - ctx.retryer = c.retryer - - c.consumer.sigContinue() - - return c } func (c *outputController) Close() error { - c.consumer.sigPause() c.consumer.close() - c.retryer.close() close(c.workQueue) if c.out != nil { @@ -97,11 +84,21 @@ func (c *outputController) Close() error { out.Close() } } - return nil } func (c *outputController) Set(outGrp outputs.Group) { + // Set consumer to empty target to pause it while we reload + c.consumer.setTarget(consumerTarget{}) + + // Close old outputWorkers, so they send their remaining events + // back to eventConsumer's retry channel + if c.out != nil { + for _, w := range c.out.outputs { + w.Close() + } + } + // create new output group with the shared work queue clients := outGrp.Clients worker := make([]outputWorker, len(clients)) @@ -116,35 +113,15 @@ func (c *outputController) Set(outGrp outputs.Group) { batchSize: outGrp.BatchSize, } - // update consumer and retryer - c.consumer.sigPause() - if c.out != nil { - for range c.out.outputs { - c.retryer.sigOutputRemoved() - } - } - for range clients { - c.retryer.sigOutputAdded() - } - c.consumer.updOutput(grp) - - // close old group, so events are send to new workQueue via retryer - if c.out != nil { - for _, w := range c.out.outputs { - w.Close() - } - } - c.out = grp - // restart consumer (potentially blocked by retryer) - c.consumer.sigContinue() - - c.observer.updateOutputGroup() -} - -func makeWorkQueue() workQueue { - return workQueue(make(chan publisher.Batch, 0)) + // Resume consumer targeting the new work queue + c.consumer.setTarget( + consumerTarget{ + ch: c.workQueue, + batchSize: grp.batchSize, + timeToLive: grp.timeToLive, + }) } // Reload the output diff --git a/libbeat/publisher/pipeline/monitoring.go b/libbeat/publisher/pipeline/monitoring.go index edcfb75a5359..754ea030855c 100644 --- a/libbeat/publisher/pipeline/monitoring.go +++ b/libbeat/publisher/pipeline/monitoring.go @@ -30,7 +30,6 @@ type observer interface { type pipelineObserver interface { clientConnected() - clientClosing() clientClosed() } @@ -47,12 +46,8 @@ type queueObserver interface { } type outputObserver interface { - updateOutputGroup() - eventsFailed(int) eventsDropped(int) eventsRetry(int) - outBatchSend(int) - outBatchACKed(int) } // metricsObserver is used by many component in the publisher pipeline, to report @@ -119,9 +114,6 @@ func (o *metricsObserver) cleanup() { // (pipeline) pipeline did finish creating a new client instance func (o *metricsObserver) clientConnected() { o.vars.clients.Inc() } -// (client) close being called on client -func (o *metricsObserver) clientClosing() {} - // (client) client finished processing close func (o *metricsObserver) clientClosed() { o.vars.clients.Dec() } @@ -171,12 +163,6 @@ func (o *metricsObserver) queueMaxEvents(n int) { // pipeline output events // -// (controller) new output group is about to be loaded -func (o *metricsObserver) updateOutputGroup() {} - -// (retryer) new failed batch has been received -func (o *metricsObserver) eventsFailed(int) {} - // (retryer) number of events dropped by retryer func (o *metricsObserver) eventsDropped(n int) { o.vars.dropped.Add(uint64(n)) @@ -187,19 +173,12 @@ func (o *metricsObserver) eventsRetry(n int) { o.vars.retry.Add(uint64(n)) } -// (output) number of events to be forwarded to the output client -func (o *metricsObserver) outBatchSend(int) {} - -// (output) number of events acked by the output batch -func (o *metricsObserver) outBatchACKed(int) {} - type emptyObserver struct{} var nilObserver observer = (*emptyObserver)(nil) func (*emptyObserver) cleanup() {} func (*emptyObserver) clientConnected() {} -func (*emptyObserver) clientClosing() {} func (*emptyObserver) clientClosed() {} func (*emptyObserver) newEvent() {} func (*emptyObserver) filteredEvent() {} @@ -207,9 +186,5 @@ func (*emptyObserver) publishedEvent() {} func (*emptyObserver) failedPublishEvent() {} func (*emptyObserver) queueACKed(n int) {} func (*emptyObserver) queueMaxEvents(int) {} -func (*emptyObserver) updateOutputGroup() {} -func (*emptyObserver) eventsFailed(int) {} func (*emptyObserver) eventsDropped(int) {} func (*emptyObserver) eventsRetry(int) {} -func (*emptyObserver) outBatchSend(int) {} -func (*emptyObserver) outBatchACKed(int) {} diff --git a/libbeat/publisher/pipeline/pipeline.go b/libbeat/publisher/pipeline/pipeline.go index be3a5e663621..c7e7f0b47fb1 100644 --- a/libbeat/publisher/pipeline/pipeline.go +++ b/libbeat/publisher/pipeline/pipeline.go @@ -70,9 +70,6 @@ type Pipeline struct { waitCloseTimeout time.Duration waitCloser *waitCloser - // pipeline ack - eventSema *sema - // closeRef signal propagation support guardStartSigPropagation sync.Once sigNewClient chan *client @@ -185,7 +182,6 @@ func New( maxEvents = 64000 } p.observer.queueMaxEvents(maxEvents) - p.eventSema = newSema(maxEvents) p.output = newOutputController(beat, monitors, p.observer, p.queue) p.output.Set(out) diff --git a/libbeat/publisher/pipeline/queue_reader.go b/libbeat/publisher/pipeline/queue_reader.go new file mode 100644 index 000000000000..10f724ce5b5f --- /dev/null +++ b/libbeat/publisher/pipeline/queue_reader.go @@ -0,0 +1,63 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package pipeline + +import ( + "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/publisher/queue" +) + +// queueReader is a standalone stateless helper goroutine to dispatch +// reads of the queue without blocking eventConsumer's main loop. +type queueReader struct { + req chan queueReaderRequest // "give me a batch for this target" + resp chan *ttlBatch // "here is your batch, or nil" +} + +type queueReaderRequest struct { + consumer queue.Consumer + retryer retryer + batchSize int + timeToLive int +} + +func makeQueueReader() queueReader { + qr := queueReader{ + req: make(chan queueReaderRequest, 1), + resp: make(chan *ttlBatch), + } + return qr +} + +func (qr *queueReader) run(logger *logp.Logger) { + logger.Debug("pipeline event consumer queue reader: start") + for { + req, ok := <-qr.req + if !ok { + // The request channel is closed, we're shutting down + logger.Debug("pipeline event consumer queue reader: stop") + return + } + queueBatch, _ := req.consumer.Get(req.batchSize) + var batch *ttlBatch + if queueBatch != nil { + batch = newBatch(req.retryer, queueBatch, req.timeToLive) + } + qr.resp <- batch + } +} diff --git a/libbeat/publisher/pipeline/retry.go b/libbeat/publisher/pipeline/retry.go deleted file mode 100644 index 77f439f2fad5..000000000000 --- a/libbeat/publisher/pipeline/retry.go +++ /dev/null @@ -1,231 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package pipeline - -import ( - "sync" -) - -// retryer is responsible for accepting and managing failed send attempts. It -// will also accept not yet published events from outputs being dynamically closed -// by the controller. Cancelled batches will be forwarded to the new workQueue, -// without updating the events retry counters. -// If too many batches (number of outputs/3) are stored in the retry buffer, -// will the consumer be paused, until some batches have been processed by some -// outputs. -type retryer struct { - logger logger - observer outputObserver - - done chan struct{} - - consumer interruptor - - sig chan retryerSignal - out workQueue - in retryQueue - doneWaiter sync.WaitGroup -} - -type interruptor interface { - sigWait() - sigUnWait() -} - -type retryQueue chan batchEvent - -type retryerSignal struct { - tag retryerEventTag - channel workQueue -} - -type batchEvent struct { - tag retryerBatchTag - batch Batch -} - -type retryerEventTag uint8 - -const ( - sigRetryerOutputAdded retryerEventTag = iota - sigRetryerOutputRemoved - sigRetryerUpdateOutput -) - -type retryerBatchTag uint8 - -const ( - retryBatch retryerBatchTag = iota - cancelledBatch -) - -func newRetryer( - log logger, - observer outputObserver, - out workQueue, - c interruptor, -) *retryer { - r := &retryer{ - logger: log, - observer: observer, - done: make(chan struct{}), - sig: make(chan retryerSignal, 3), - in: retryQueue(make(chan batchEvent, 3)), - out: out, - consumer: c, - doneWaiter: sync.WaitGroup{}, - } - r.doneWaiter.Add(1) - go r.loop() - return r -} - -func (r *retryer) close() { - close(r.done) - //Block until loop() is properly closed - r.doneWaiter.Wait() -} - -func (r *retryer) sigOutputAdded() { - r.sig <- retryerSignal{tag: sigRetryerOutputAdded} -} - -func (r *retryer) sigOutputRemoved() { - r.sig <- retryerSignal{tag: sigRetryerOutputRemoved} -} - -func (r *retryer) retry(b Batch) { - r.in <- batchEvent{tag: retryBatch, batch: b} -} - -func (r *retryer) cancelled(b Batch) { - r.in <- batchEvent{tag: cancelledBatch, batch: b} -} - -func (r *retryer) loop() { - defer r.doneWaiter.Done() - var ( - out workQueue - consumerBlocked bool - - active Batch - activeSize int - buffer []Batch - numOutputs int - - log = r.logger - ) - - for { - select { - case <-r.done: - return - case evt := <-r.in: - var ( - countFailed int - countDropped int - batch = evt.batch - countRetry = len(batch.Events()) - alive = true - ) - - if evt.tag == retryBatch { - countFailed = len(batch.Events()) - r.observer.eventsFailed(countFailed) - - alive = batch.reduceTTL() - - countRetry = len(batch.Events()) - countDropped = countFailed - countRetry - r.observer.eventsDropped(countDropped) - } - - if !alive { - log.Info("Drop batch") - batch.Drop() - } else { - out = r.out - buffer = append(buffer, batch) - out = r.out - active = buffer[0] - activeSize = len(active.Events()) - if !consumerBlocked { - consumerBlocked = r.checkConsumerBlock(numOutputs, len(buffer)) - } - } - - case out <- active: - r.observer.eventsRetry(activeSize) - - buffer = buffer[1:] - active, activeSize = nil, 0 - - if len(buffer) == 0 { - out = nil - } else { - active = buffer[0] - activeSize = len(active.Events()) - } - - if consumerBlocked { - consumerBlocked = r.checkConsumerBlock(numOutputs, len(buffer)) - } - - case sig := <-r.sig: - switch sig.tag { - case sigRetryerOutputAdded: - numOutputs++ - if consumerBlocked { - consumerBlocked = r.checkConsumerBlock(numOutputs, len(buffer)) - } - case sigRetryerOutputRemoved: - numOutputs-- - if !consumerBlocked { - consumerBlocked = r.checkConsumerBlock(numOutputs, len(buffer)) - } - } - } - } -} - -func (r *retryer) checkConsumerBlock(numOutputs, numBatches int) bool { - consumerBlocked := blockConsumer(numOutputs, numBatches) - if r.consumer == nil { - return consumerBlocked - } - - if consumerBlocked { - r.logger.Info("retryer: send wait signal to consumer") - if r.consumer != nil { - r.consumer.sigWait() - } - r.logger.Info(" done") - } else { - r.logger.Info("retryer: send unwait signal to consumer") - if r.consumer != nil { - r.consumer.sigUnWait() - } - r.logger.Info(" done") - } - - return consumerBlocked -} - -func blockConsumer(numOutputs, numBatches int) bool { - return numBatches/3 >= numOutputs -} diff --git a/libbeat/publisher/pipeline/testing.go b/libbeat/publisher/pipeline/testing.go index 431b2a6e39e2..75250ece0f17 100644 --- a/libbeat/publisher/pipeline/testing.go +++ b/libbeat/publisher/pipeline/testing.go @@ -25,7 +25,6 @@ import ( "github.com/elastic/beats/v7/libbeat/outputs" "github.com/elastic/beats/v7/libbeat/publisher" - "github.com/elastic/beats/v7/libbeat/publisher/queue" ) type mockPublishFn func(publisher.Batch) error @@ -54,24 +53,6 @@ type mockNetworkClient struct { func (c *mockNetworkClient) Connect() error { return nil } -type mockQueue struct{} - -func (q mockQueue) Close() error { return nil } -func (q mockQueue) BufferConfig() queue.BufferConfig { return queue.BufferConfig{} } -func (q mockQueue) Producer(cfg queue.ProducerConfig) queue.Producer { return mockProducer{} } -func (q mockQueue) Consumer() queue.Consumer { return mockConsumer{} } - -type mockProducer struct{} - -func (p mockProducer) Publish(event publisher.Event) bool { return true } -func (p mockProducer) TryPublish(event publisher.Event) bool { return true } -func (p mockProducer) Cancel() int { return 0 } - -type mockConsumer struct{} - -func (c mockConsumer) Get(eventCount int) (queue.Batch, error) { return &batch{}, nil } -func (c mockConsumer) Close() error { return nil } - type mockBatch struct { mu sync.Mutex events []publisher.Event @@ -81,7 +62,6 @@ type mockBatch struct { onDrop func() onRetry func() onCancelled func() - onReduceTTL func() bool } func (b *mockBatch) Events() []publisher.Event { @@ -95,23 +75,12 @@ func (b *mockBatch) ACK() { signalFn(b.onACK) } func (b *mockBatch) Drop() { signalFn(b.onDrop) } func (b *mockBatch) Retry() { signalFn(b.onRetry) } func (b *mockBatch) Cancelled() { signalFn(b.onCancelled) } + func (b *mockBatch) RetryEvents(events []publisher.Event) { b.updateEvents(events) signalFn(b.onRetry) } -func (b *mockBatch) reduceTTL() bool { - if b.onReduceTTL != nil { - return b.onReduceTTL() - } - return true -} - -func (b *mockBatch) CancelledEvents(events []publisher.Event) { - b.updateEvents(events) - signalFn(b.onCancelled) -} - func (b *mockBatch) updateEvents(events []publisher.Event) { b.mu.Lock() defer b.mu.Unlock() @@ -124,17 +93,63 @@ func (b *mockBatch) Len() int { return len(b.events) } -func (b *mockBatch) withRetryer(r *retryer) *mockBatch { - return &mockBatch{ - events: b.events, - onACK: b.onACK, - onDrop: b.onDrop, - onRetry: func() { r.retry(b) }, - onCancelled: func() { r.cancelled(b) }, - onReduceTTL: b.onReduceTTL, +func (b *mockBatch) withRetryer(r standaloneRetryer) *mockBatch { + wrapper := &mockBatch{ + events: b.events, + onACK: b.onACK, + onDrop: b.onDrop, + } + wrapper.onRetry = func() { r.retryChan <- wrapper } + wrapper.onCancelled = func() { r.retryChan <- wrapper } + return wrapper +} + +// standaloneRetryer is a helper that can be used to simulate retry +// behavior when unit testing outputWorker without a full pipeline. (In +// a live pipeline the retry calls are handled by the eventConsumer). +type standaloneRetryer struct { + workQueue chan publisher.Batch + retryChan chan publisher.Batch + done chan struct{} +} + +func newStandaloneRetryer(workQueue chan publisher.Batch) standaloneRetryer { + sr := standaloneRetryer{ + workQueue: workQueue, + retryChan: make(chan publisher.Batch), + done: make(chan struct{}), + } + go sr.run() + return sr +} + +func (sr standaloneRetryer) run() { + var batches []publisher.Batch + for { + var active publisher.Batch + var outChan chan publisher.Batch + // If we have a batch to send, set the batch and output channel. + // Otherwise they'll be nil, and the select statement below will + // ignore them. + if len(batches) > 0 { + active = batches[0] + outChan = sr.workQueue + } + select { + case batch := <-sr.retryChan: + batches = append(batches, batch) + case outChan <- active: + batches = batches[1:] + case <-sr.done: + return + } } } +func (sr standaloneRetryer) close() { + close(sr.done) +} + func signalFn(fn func()) { if fn != nil { fn() diff --git a/libbeat/publisher/pipeline/batch.go b/libbeat/publisher/pipeline/ttl_batch.go similarity index 63% rename from libbeat/publisher/pipeline/batch.go rename to libbeat/publisher/pipeline/ttl_batch.go index 54ba2058d746..4b3bdb6489b2 100644 --- a/libbeat/publisher/pipeline/batch.go +++ b/libbeat/publisher/pipeline/ttl_batch.go @@ -24,99 +24,81 @@ import ( "github.com/elastic/beats/v7/libbeat/publisher/queue" ) -type Batch interface { - publisher.Batch - - reduceTTL() bool +type retryer interface { + retry(batch *ttlBatch, decreaseTTL bool) } -type batch struct { +type ttlBatch struct { original queue.Batch - ctx *batchContext - ttl int - events []publisher.Event -} -type batchContext struct { - observer outputObserver - retryer *retryer + // The internal hook back to the eventConsumer, used to implement the + // publisher.Batch retry interface. + retryer retryer + + // How many retries until we drop this batch. -1 means it can't be dropped. + ttl int + + // The cached events returned from original.Events(). If some but not + // all of the events are ACKed, those ones are removed from the list. + events []publisher.Event } var batchPool = sync.Pool{ New: func() interface{} { - return &batch{} + return &ttlBatch{} }, } -func newBatch(ctx *batchContext, original queue.Batch, ttl int) *batch { +func newBatch(retryer retryer, original queue.Batch, ttl int) *ttlBatch { if original == nil { panic("empty batch") } - b := batchPool.Get().(*batch) - *b = batch{ + b := batchPool.Get().(*ttlBatch) + *b = ttlBatch{ original: original, - ctx: ctx, + retryer: retryer, ttl: ttl, events: original.Events(), } return b } -func releaseBatch(b *batch) { - *b = batch{} // clear batch +func releaseBatch(b *ttlBatch) { + *b = ttlBatch{} // clear batch batchPool.Put(b) } -func (b *batch) Events() []publisher.Event { +func (b *ttlBatch) Events() []publisher.Event { return b.events } -func (b *batch) ACK() { - if b.ctx != nil { - b.ctx.observer.outBatchACKed(len(b.events)) - } +func (b *ttlBatch) ACK() { b.original.ACK() releaseBatch(b) } -func (b *batch) Drop() { +func (b *ttlBatch) Drop() { b.original.ACK() releaseBatch(b) } -func (b *batch) Retry() { - b.ctx.retryer.retry(b) +func (b *ttlBatch) Retry() { + b.retryer.retry(b, true) } -func (b *batch) Cancelled() { - b.ctx.retryer.cancelled(b) +func (b *ttlBatch) Cancelled() { + b.retryer.retry(b, false) } -func (b *batch) RetryEvents(events []publisher.Event) { - b.updEvents(events) - b.Retry() -} - -func (b *batch) CancelledEvents(events []publisher.Event) { - b.updEvents(events) - b.Cancelled() -} - -func (b *batch) updEvents(events []publisher.Event) { - l1 := len(b.events) - l2 := len(events) - if l1 > l2 { - // report subset of events not to be retried as ACKed - b.ctx.observer.outBatchACKed(l1 - l2) - } - +func (b *ttlBatch) RetryEvents(events []publisher.Event) { b.events = events + b.Retry() } // reduceTTL reduces the time to live for all events that have no 'guaranteed' // sending requirements. reduceTTL returns true if the batch is still alive. -func (b *batch) reduceTTL() bool { +func (b *ttlBatch) reduceTTL() bool { if b.ttl <= 0 { return true } diff --git a/libbeat/publisher/pipeline/util.go b/libbeat/publisher/pipeline/util.go deleted file mode 100644 index db656f4ae9e0..000000000000 --- a/libbeat/publisher/pipeline/util.go +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package pipeline - -import "sync" - -type sema struct { - // simulate cancellable counting semaphore using counter + mutex + cond - mutex sync.Mutex - cond sync.Cond - count, max int -} - -func newSema(max int) *sema { - s := &sema{max: max} - s.cond.L = &s.mutex - return s -} - -func (s *sema) inc() { - s.mutex.Lock() - for s.count == s.max { - s.cond.Wait() - } - s.mutex.Unlock() -} - -func (s *sema) release(n int) { - s.mutex.Lock() - old := s.count - s.count -= n - if old == s.max { - if n == 1 { - s.cond.Signal() - } else { - s.cond.Broadcast() - } - } - s.mutex.Unlock() -} From 07383bbd07435e539c2e040cfe33214923ba0fcb Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 7 Dec 2021 21:48:16 -0800 Subject: [PATCH 063/172] Add 7.16 breaking changes (#29300) * Add 7.16 breaking changes * Resolve feedback from kvch * Add BC about Beats generator code --- .../breaking/breaking-7.16.asciidoc | 42 +++++++++++++++++++ .../release-notes/breaking/breaking.asciidoc | 4 ++ 2 files changed, 46 insertions(+) create mode 100644 libbeat/docs/release-notes/breaking/breaking-7.16.asciidoc diff --git a/libbeat/docs/release-notes/breaking/breaking-7.16.asciidoc b/libbeat/docs/release-notes/breaking/breaking-7.16.asciidoc new file mode 100644 index 000000000000..29e82e73337e --- /dev/null +++ b/libbeat/docs/release-notes/breaking/breaking-7.16.asciidoc @@ -0,0 +1,42 @@ +[[breaking-changes-7.16]] + +=== Breaking changes in 7.16 +++++ +7.16 +++++ + +See the <> for a complete list of changes, +including changes to beta or experimental functionality. + +//NOTE: The notable-breaking-changes tagged regions are re-used in the +//Installation and Upgrade Guide + +// tag::notable-breaking-changes[] + +[discrete] +==== {journalbeat} is removed in 7.16 + +{journalbeat}, a lightweight shipper for collecting logs written by the Journald +system service, is removed in 7.16. This functionality is instead provided as +a {filebeat} input. If you're currently using {journalbeat}, you should +use the `journald` input in {filebeat} instead. For more information, refer to +the +{filebeat-ref}/filebeat-input-journald.html[Journald input] documentation. + +If you're using {agent} instead of {beats}, you can collect Journald logs by +adding the *Custom Journald logs* integration to your agent policy. For more +information, refer to +{fleet-guide}/add-integration-to-policy.html[Add an {agent} integration to a policy]. + +//TODO: Add pointer to the integrations docs for custom journald logs when +//available. + +[discrete] +==== Custom {beats} generator is deprecated in 7.16 + +The generator code for creating custom {beats} is deprecated in 7.16.0 and will +be removed in 8.0.0. You can continue to build custom {beats} using the +generators available in 7.16, or refer to existing {beats} as working examples. + +// end::notable-breaking-changes[] + diff --git a/libbeat/docs/release-notes/breaking/breaking.asciidoc b/libbeat/docs/release-notes/breaking/breaking.asciidoc index f2f71da0579d..6fb7e8934607 100644 --- a/libbeat/docs/release-notes/breaking/breaking.asciidoc +++ b/libbeat/docs/release-notes/breaking/breaking.asciidoc @@ -11,6 +11,8 @@ changes, but there are breaking changes between major versions (e.g. 6.x to See the following topics for a description of breaking changes: +* <> + * <> * <> @@ -43,6 +45,8 @@ See the following topics for a description of breaking changes: * <> +include::breaking-7.16.asciidoc[] + include::breaking-7.15.asciidoc[] include::breaking-7.14.asciidoc[] From 810ae71defc0fb5015b13daa10eb60acd8cc7470 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Wed, 8 Dec 2021 08:16:02 -0500 Subject: [PATCH 064/172] Add info to aws-s3 log messages (#29328) This adds elapsed_time_ns into S3 object read errors and SQS processing warning log messages. This gives context about how long it took to fail. Extended times could be an indicator of a blocked output. It also adds the number of S3 records contained in the SQS notification to error messages. This gives context about how many S3 objects were being processed when a failure occurs. --- CHANGELOG.next.asciidoc | 3 ++- x-pack/filebeat/input/awss3/s3_objects.go | 28 ++++++++++----------- x-pack/filebeat/input/awss3/sqs.go | 5 +++- x-pack/filebeat/input/awss3/sqs_s3_event.go | 6 ++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 3e59467780b5..a9e40591fa21 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -27,7 +27,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - add_docker_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] - Use data streams instead of indices for storing events from Beats. {pull}28450[28450] - Remove option `setup.template.type` and always load composable template with data streams. {pull}28450[28450] -- Remove several ILM options (`rollover_alias` and `pattern`) as data streams does not require index aliases. {pull}28450[28450] +- Remove several ILM options (`rollover_alias` and `pattern`) as data streams does not require index aliases. {pull}28450[28450] - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] @@ -355,6 +355,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support in aws-s3 input for custom script parsing of s3 notifications. {pull}28946[28946] - Improve error handling in aws-s3 input for malformed s3 notifications. {issue}28828[28828] {pull}28946[28946] - Add support for parsers on journald input {pull}29070[29070] +- Add elapsed time information to `aws-s3` input errors and log messages. {pull}29328[29328] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] *Heartbeat* diff --git a/x-pack/filebeat/input/awss3/s3_objects.go b/x-pack/filebeat/input/awss3/s3_objects.go index 2839c31e2253..7fe6b193fa45 100644 --- a/x-pack/filebeat/input/awss3/s3_objects.go +++ b/x-pack/filebeat/input/awss3/s3_objects.go @@ -120,23 +120,22 @@ func (p *s3ObjectProcessor) ProcessS3Object() error { } // Metrics and Logging - { - p.log.Debug("Begin S3 object processing.") - p.metrics.s3ObjectsRequestedTotal.Inc() - p.metrics.s3ObjectsInflight.Inc() - start := time.Now() - defer func() { - elapsed := time.Since(start) - p.metrics.s3ObjectsInflight.Dec() - p.metrics.s3ObjectProcessingTime.Update(elapsed.Nanoseconds()) - p.log.Debugw("End S3 object processing.", "elapsed_time_ns", elapsed) - }() - } + p.log.Debug("Begin S3 object processing.") + p.metrics.s3ObjectsRequestedTotal.Inc() + p.metrics.s3ObjectsInflight.Inc() + start := time.Now() + defer func() { + elapsed := time.Since(start) + p.metrics.s3ObjectsInflight.Dec() + p.metrics.s3ObjectProcessingTime.Update(elapsed.Nanoseconds()) + p.log.Debugw("End S3 object processing.", "elapsed_time_ns", elapsed) + }() // Request object (download). contentType, meta, body, err := p.download() if err != nil { - return errors.Wrap(err, "failed to get s3 object") + return errors.Wrapf(err, "failed to get s3 object (elasped_time_ns=%d)", + time.Since(start).Nanoseconds()) } defer body.Close() p.s3Metadata = meta @@ -159,7 +158,8 @@ func (p *s3ObjectProcessor) ProcessS3Object() error { err = p.readFile(reader) } if err != nil { - return err + return errors.Wrapf(err, "failed reading s3 object (elasped_time_ns=%d)", + time.Since(start).Nanoseconds()) } return nil diff --git a/x-pack/filebeat/input/awss3/sqs.go b/x-pack/filebeat/input/awss3/sqs.go index 56f35e473ce4..1f13ec010cf7 100644 --- a/x-pack/filebeat/input/awss3/sqs.go +++ b/x-pack/filebeat/input/awss3/sqs.go @@ -88,7 +88,10 @@ func (r *sqsReader) Receive(ctx context.Context) error { }() if err := r.msgHandler.ProcessSQS(ctx, &msg); err != nil { - r.log.Warnw("Failed processing SQS message.", "error", err, "message_id", *msg.MessageId) + r.log.Warnw("Failed processing SQS message.", + "error", err, + "message_id", *msg.MessageId, + "elapsed_time_ns", time.Since(start)) } }(msg, time.Now()) } diff --git a/x-pack/filebeat/input/awss3/sqs_s3_event.go b/x-pack/filebeat/input/awss3/sqs_s3_event.go index c906c74fa9e0..b6641a36c81c 100644 --- a/x-pack/filebeat/input/awss3/sqs_s3_event.go +++ b/x-pack/filebeat/input/awss3/sqs_s3_event.go @@ -265,7 +265,7 @@ func (p *sqsS3EventProcessor) processS3Events(ctx context.Context, log *logp.Log defer acker.Wait() var errs []error - for _, event := range s3Events { + for i, event := range s3Events { s3Processor := p.s3ObjectHandler.Create(ctx, log, acker, event) if s3Processor == nil { continue @@ -274,8 +274,8 @@ func (p *sqsS3EventProcessor) processS3Events(ctx context.Context, log *logp.Log // Process S3 object (download, parse, create events). if err := s3Processor.ProcessS3Object(); err != nil { errs = append(errs, errors.Wrapf(err, - "failed processing S3 event for object key %q in bucket %q", - event.S3.Object.Key, event.S3.Bucket.Name)) + "failed processing S3 event for object key %q in bucket %q (object record %d of %d in SQS notification)", + event.S3.Object.Key, event.S3.Bucket.Name, i+1, len(s3Events))) } } From 8796caa9af2a272e779b4dbd947052410a122770 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 8 Dec 2021 17:01:44 +0200 Subject: [PATCH 065/172] Fix k8s metadata regression (#29329) --- libbeat/autodiscover/providers/kubernetes/config.go | 11 ++++++----- libbeat/processors/add_kubernetes_metadata/config.go | 11 ++++++----- .../pkg/composable/providers/kubernetes/config.go | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libbeat/autodiscover/providers/kubernetes/config.go b/libbeat/autodiscover/providers/kubernetes/config.go index 173a5208c99e..46f73930141e 100644 --- a/libbeat/autodiscover/providers/kubernetes/config.go +++ b/libbeat/autodiscover/providers/kubernetes/config.go @@ -66,11 +66,12 @@ var DefaultCleanupTimeout time.Duration = 0 func defaultConfig() *Config { return &Config{ - SyncPeriod: 10 * time.Minute, - Resource: "pod", - CleanupTimeout: DefaultCleanupTimeout, - Prefix: "co.elastic", - Unique: false, + SyncPeriod: 10 * time.Minute, + Resource: "pod", + CleanupTimeout: DefaultCleanupTimeout, + Prefix: "co.elastic", + Unique: false, + AddResourceMetadata: metadata.GetDefaultResourceMetadataConfig(), } } diff --git a/libbeat/processors/add_kubernetes_metadata/config.go b/libbeat/processors/add_kubernetes_metadata/config.go index ecc9b5919feb..9365627f59fd 100644 --- a/libbeat/processors/add_kubernetes_metadata/config.go +++ b/libbeat/processors/add_kubernetes_metadata/config.go @@ -52,11 +52,12 @@ type PluginConfig []map[string]common.Config func defaultKubernetesAnnotatorConfig() kubeAnnotatorConfig { return kubeAnnotatorConfig{ - SyncPeriod: 10 * time.Minute, - CleanupTimeout: 60 * time.Second, - DefaultMatchers: Enabled{true}, - DefaultIndexers: Enabled{true}, - Scope: "node", + SyncPeriod: 10 * time.Minute, + CleanupTimeout: 60 * time.Second, + DefaultMatchers: Enabled{true}, + DefaultIndexers: Enabled{true}, + Scope: "node", + AddResourceMetadata: metadata.GetDefaultResourceMetadataConfig(), } } diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/config.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/config.go index ec99bca287d9..cdb50d6d816c 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/config.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/config.go @@ -55,6 +55,7 @@ func (c *Config) InitDefaults() { c.Scope = "node" c.LabelsDedot = true c.AnnotationsDedot = true + c.AddResourceMetadata = metadata.GetDefaultResourceMetadataConfig() } // Validate ensures correctness of config From e5a6631b6a00eaa899b460ec543fd5c121df75b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Wed, 8 Dec 2021 16:36:52 +0100 Subject: [PATCH 066/172] Overwrite index name in index template correctly (#29299) --- CHANGELOG.next.asciidoc | 1 + libbeat/dashboards/modify_json.go | 44 ++--------- libbeat/dashboards/modify_json_test.go | 104 +++++++------------------ 3 files changed, 34 insertions(+), 115 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index a9e40591fa21..e04793eb0898 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -147,6 +147,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] - Fix `decode_json_processor` to always respect `add_error_key` {pull}29107[29107] - Fix `add_labels` flattening of array values. {pull}29211[29211] +- Overwrite index name in index template correctly. {issue}28571[28571] {pull}29299[29299] *Auditbeat* diff --git a/libbeat/dashboards/modify_json.go b/libbeat/dashboards/modify_json.go index 204413280bb7..2545e1fe02ee 100644 --- a/libbeat/dashboards/modify_json.go +++ b/libbeat/dashboards/modify_json.go @@ -23,8 +23,6 @@ import ( "fmt" "regexp" - "github.com/pkg/errors" - "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" ) @@ -53,44 +51,14 @@ func ReplaceIndexInIndexPattern(index string, content common.MapStr) (err error) return nil } - list, ok := content["objects"] - if !ok { - return errors.New("empty index pattern") - } - - updateObject := func(obj common.MapStr) { - // This uses Put instead of DeepUpdate to avoid modifying types for - // inner objects. (DeepUpdate will replace maps with MapStr). - obj.Put("id", index) - // Only overwrite title if it exists. - if _, err := obj.GetValue("attributes.title"); err == nil { - obj.Put("attributes.title", index) - } + // This uses Put instead of DeepUpdate to avoid modifying types for + // inner objects. (DeepUpdate will replace maps with MapStr). + content.Put("id", index) + // Only overwrite title if it exists. + if _, err := content.GetValue("attributes.title"); err == nil { + content.Put("attributes.title", index) } - switch v := list.(type) { - case []interface{}: - for _, objIf := range v { - switch obj := objIf.(type) { - case common.MapStr: - updateObject(obj) - case map[string]interface{}: - updateObject(obj) - default: - return errors.Errorf("index pattern object has unexpected type %T", v) - } - } - case []map[string]interface{}: - for _, obj := range v { - updateObject(obj) - } - case []common.MapStr: - for _, obj := range v { - updateObject(obj) - } - default: - return errors.Errorf("index pattern objects have unexpected type %T", v) - } return nil } diff --git a/libbeat/dashboards/modify_json_test.go b/libbeat/dashboards/modify_json_test.go index 389e8b416a72..7981dac8c57e 100644 --- a/libbeat/dashboards/modify_json_test.go +++ b/libbeat/dashboards/modify_json_test.go @@ -124,118 +124,68 @@ func TestReplaceIndexInIndexPattern(t *testing.T) { index string expected common.MapStr }{ - { - title: "Replace in []interface(map).map", - input: common.MapStr{"objects": []interface{}{map[string]interface{}{ - "id": "phonybeat-*", - "type": "index-pattern", - "attributes": map[string]interface{}{ - "title": "phonybeat-*", - "timeFieldName": "@timestamp", - }}}}, - index: "otherindex-*", - expected: common.MapStr{"objects": []interface{}{map[string]interface{}{ - "id": "otherindex-*", - "type": "index-pattern", - "attributes": map[string]interface{}{ - "title": "otherindex-*", - "timeFieldName": "@timestamp", - }}}}, - }, - { - title: "Replace in []interface(map).mapstr", - input: common.MapStr{"objects": []interface{}{map[string]interface{}{ - "id": "phonybeat-*", - "type": "index-pattern", - "attributes": common.MapStr{ - "title": "phonybeat-*", - "timeFieldName": "@timestamp", - }}}}, - index: "otherindex-*", - expected: common.MapStr{"objects": []interface{}{map[string]interface{}{ - "id": "otherindex-*", - "type": "index-pattern", - "attributes": common.MapStr{ - "title": "otherindex-*", - "timeFieldName": "@timestamp", - }}}}, - }, - { - title: "Replace in []map.mapstr", - input: common.MapStr{"objects": []map[string]interface{}{{ - "id": "phonybeat-*", - "type": "index-pattern", - "attributes": common.MapStr{ - "title": "phonybeat-*", - "timeFieldName": "@timestamp", - }}}}, - index: "otherindex-*", - expected: common.MapStr{"objects": []map[string]interface{}{{ - "id": "otherindex-*", - "type": "index-pattern", - "attributes": common.MapStr{ - "title": "otherindex-*", - "timeFieldName": "@timestamp", - }}}}, - }, { title: "Replace in []mapstr.mapstr", - input: common.MapStr{"objects": []common.MapStr{{ + input: common.MapStr{ "id": "phonybeat-*", "type": "index-pattern", "attributes": common.MapStr{ "title": "phonybeat-*", "timeFieldName": "@timestamp", - }}}}, + }}, index: "otherindex-*", - expected: common.MapStr{"objects": []common.MapStr{{ + expected: common.MapStr{ "id": "otherindex-*", "type": "index-pattern", "attributes": common.MapStr{ "title": "otherindex-*", "timeFieldName": "@timestamp", - }}}}, + }}, }, { title: "Replace in []mapstr.interface(mapstr)", - input: common.MapStr{"objects": []common.MapStr{{ + input: common.MapStr{ "id": "phonybeat-*", "type": "index-pattern", "attributes": interface{}(common.MapStr{ "title": "phonybeat-*", "timeFieldName": "@timestamp", - })}}}, + })}, index: "otherindex-*", - expected: common.MapStr{"objects": []common.MapStr{{ + expected: common.MapStr{ "id": "otherindex-*", "type": "index-pattern", "attributes": interface{}(common.MapStr{ "title": "otherindex-*", "timeFieldName": "@timestamp", - })}}}, + })}, }, { title: "Do not create missing attributes", - input: common.MapStr{"objects": []common.MapStr{{ - "id": "phonybeat-*", - "type": "index-pattern", - }}}, + input: common.MapStr{ + "attributes": common.MapStr{}, + "id": "phonybeat-*", + "type": "index-pattern", + }, index: "otherindex-*", - expected: common.MapStr{"objects": []common.MapStr{{ - "id": "otherindex-*", - "type": "index-pattern", - }}}, + expected: common.MapStr{ + "attributes": common.MapStr{}, + "id": "otherindex-*", + "type": "index-pattern", + }, }, { title: "Create missing id", - input: common.MapStr{"objects": []common.MapStr{{ - "type": "index-pattern", - }}}, + input: common.MapStr{ + "attributes": common.MapStr{}, + "type": "index-pattern", + }, index: "otherindex-*", - expected: common.MapStr{"objects": []common.MapStr{{ - "id": "otherindex-*", - "type": "index-pattern", - }}}, + expected: common.MapStr{ + "attributes": common.MapStr{}, + "id": "otherindex-*", + "type": "index-pattern", + }, }, } From 28d00c76735850e80920bb913d6730138de75c34 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Wed, 8 Dec 2021 23:22:53 -0500 Subject: [PATCH 067/172] Fix decode_cef handling of escaped LF and CR (#29268) * Fix decode_cef handling of escaped LF and CR Escaped LF and CR were not handled inside of CEF extension value. Those characters are now accepted and replaced with their unescaped equivalents. Replace fgoto with fnext to fix generated Go code that had duplicate 'goto' statements. Fixes #16995 --- CHANGELOG.next.asciidoc | 1 + .../filebeat/processors/decode_cef/cef/cef.go | 58 +- .../filebeat/processors/decode_cef/cef/cef.rl | 44 +- .../processors/decode_cef/cef/cef_test.go | 15 + .../processors/decode_cef/cef/parser.go | 1045 +++++++++++------ 5 files changed, 751 insertions(+), 412 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e04793eb0898..93d6c7cd1bed 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -196,6 +196,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] - Fix `threatintel.misp` filters configuration. {issue}27970[27970] - Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] +- Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] - Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] *Heartbeat* diff --git a/x-pack/filebeat/processors/decode_cef/cef/cef.go b/x-pack/filebeat/processors/decode_cef/cef/cef.go index 4c0f983aa96f..73808171aceb 100644 --- a/x-pack/filebeat/processors/decode_cef/cef/cef.go +++ b/x-pack/filebeat/processors/decode_cef/cef/cef.go @@ -152,32 +152,42 @@ func (e *Event) Unpack(data string, opts ...Option) error { return multierr.Combine(errs...) } -const ( - backslash = `\` - escapedBackslash = `\\` - - pipe = `|` - escapedPipe = `\|` - - equalsSign = `=` - escapedEqualsSign = `\=` -) - -var ( - headerEscapes = strings.NewReplacer(escapedBackslash, backslash, escapedPipe, pipe) - extensionEscapes = strings.NewReplacer(escapedBackslash, backslash, escapedEqualsSign, equalsSign) -) +// replaceEscapes replaces the escaped characters contained in v with their +// unescaped value. +func replaceEscapes(v string, startOffset int, escapes []int) string { + if len(escapes) == 0 { + return v + } -func replaceHeaderEscapes(b string) string { - if strings.Index(b, escapedBackslash) != -1 || strings.Index(b, escapedPipe) != -1 { - return headerEscapes.Replace(b) + // Adjust escape offsets relative to the start offset of v. + for i := 0; i < len(escapes); i++ { + escapes[i] = escapes[i] - startOffset } - return b -} -func replaceExtensionEscapes(b string) string { - if strings.Index(b, escapedBackslash) != -1 || strings.Index(b, escapedEqualsSign) != -1 { - return extensionEscapes.Replace(b) + var buf strings.Builder + var end int + + // Iterate over escapes and replace them. + for i := 0; i < len(escapes); i += 2 { + start := escapes[i] + buf.WriteString(v[end:start]) + + end = escapes[i+1] + value := v[start:end] + + switch value { + case `\n`: + buf.WriteByte('\n') + case `\r`: + buf.WriteByte('\r') + default: + // Remove leading slash. + if len(value) > 0 && value[0] == '\\' { + buf.WriteString(value[1:]) + } + } } - return b + buf.WriteString(v[end:]) + + return buf.String() } diff --git a/x-pack/filebeat/processors/decode_cef/cef/cef.rl b/x-pack/filebeat/processors/decode_cef/cef/cef.rl index a34ced7d87f1..09b7fd6e962e 100644 --- a/x-pack/filebeat/processors/decode_cef/cef/cef.rl +++ b/x-pack/filebeat/processors/decode_cef/cef/cef.rl @@ -18,7 +18,8 @@ import ( // unpack unpacks a CEF message. func (e *Event) unpack(data string) error { cs, p, pe, eof := 0, 0, len(data), len(data) - mark := 0 + mark, mark_slash := 0, 0 + var escapes []int // Extension key. var extKey string @@ -37,23 +38,34 @@ func (e *Event) unpack(data string) error { action mark { mark = p } + action mark_slash { + mark_slash = p + } + action mark_escape { + escapes = append(escapes, mark_slash, p) + } action version { e.Version, _ = strconv.Atoi(data[mark:p]) } action device_vendor { - e.DeviceVendor = replaceHeaderEscapes(data[mark:p]) + e.DeviceVendor = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] } action device_product { - e.DeviceProduct = replaceHeaderEscapes(data[mark:p]) + e.DeviceProduct = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] } action device_version { - e.DeviceVersion = replaceHeaderEscapes(data[mark:p]) + e.DeviceVersion = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] } action device_event_class_id { - e.DeviceEventClassID = replaceHeaderEscapes(data[mark:p]) + e.DeviceEventClassID = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] } action name { - e.Name = replaceHeaderEscapes(data[mark:p]) + e.Name = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] } action severity { e.Severity = data[mark:p] @@ -61,8 +73,8 @@ func (e *Event) unpack(data string) error { action extension_key { // A new extension key marks the end of the last extension value. if len(extKey) > 0 && extValueStart <= mark - 1 { - e.pushExtension(extKey, replaceExtensionEscapes(data[extValueStart:mark-1])) - extKey, extValueStart, extValueEnd = "", 0, 0 + e.pushExtension(extKey, replaceEscapes(data[extValueStart:mark-1], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] } extKey = data[mark:p] } @@ -76,19 +88,19 @@ func (e *Event) unpack(data string) error { action extension_eof { // Reaching the EOF marks the end of the final extension value. if len(extKey) > 0 && extValueStart <= extValueEnd { - e.pushExtension(extKey, replaceExtensionEscapes(data[extValueStart:extValueEnd])) - extKey, extValueStart, extValueEnd = "", 0, 0 + e.pushExtension(extKey, replaceEscapes(data[extValueStart:extValueEnd], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] } } action extension_err { recoveredErrs = append(recoveredErrs, fmt.Errorf("malformed value for %s at pos %d", extKey, p+1)) - fhold; fgoto gobble_extension; + fhold; fnext gobble_extension; } action recover_next_extension { extKey, extValueStart, extValueEnd = "", 0, 0 // Resume processing at p, the start of the next extension key. p = mark; - fgoto extensions; + fnext extensions; } # Define what header characters are allowed. @@ -96,7 +108,8 @@ func (e *Event) unpack(data string) error { escape = "\\"; escape_pipe = escape pipe; backslash = "\\\\"; - device_chars = backslash | escape_pipe | (any -- pipe -- escape); + header_escapes = (backslash | escape_pipe) >mark_slash %mark_escape; + device_chars = header_escapes | (any -- pipe -- escape); severity_chars = ( alpha | digit | "-" ); # Header fields. @@ -119,12 +132,15 @@ func (e *Event) unpack(data string) error { # Define what extension characters are allowed. equal = "="; escape_equal = escape equal; + escape_newline = escape 'n'; + escape_carriage_return = escape 'r'; + extension_value_escapes = (escape_equal | backslash | escape_newline | escape_carriage_return) >mark_slash %mark_escape; # Only alnum is defined in the CEF spec. The other characters allow # non-conforming extension keys to be parsed. extension_key_start_chars = alnum | '_'; extension_key_chars = extension_key_start_chars | '.' | ',' | '[' | ']'; extension_key_pattern = extension_key_start_chars extension_key_chars*; - extension_value_chars_nospace = backslash | escape_equal | (any -- equal -- escape -- space); + extension_value_chars_nospace = extension_value_escapes | (any -- equal -- escape -- space); # Extension fields. extension_key = extension_key_pattern >mark %extension_key; diff --git a/x-pack/filebeat/processors/decode_cef/cef/cef_test.go b/x-pack/filebeat/processors/decode_cef/cef/cef_test.go index a0dc7c0c46c3..7ab286e1f2ce 100644 --- a/x-pack/filebeat/processors/decode_cef/cef/cef_test.go +++ b/x-pack/filebeat/processors/decode_cef/cef/cef_test.go @@ -52,6 +52,8 @@ const ( tabMessage = "CEF:0|security|threatmanager|1.0|100|message is padded|10|spt=1232 msg=Tabs\tand\rcontrol\ncharacters are preserved\t src=127.0.0.1" tabNoSepMessage = "CEF:0|security|threatmanager|1.0|100|message has tabs|10|spt=1232 msg=Tab is not a separator\tsrc=127.0.0.1" + + escapedMessage = `CEF:0|security\\compliance|threat\|->manager|1.0|100|message contains escapes|10|spt=1232 msg=Newlines in messages\nare allowed.\r\nAnd so are carriage feeds\\newlines\\\=.` ) var testMessages = []string{ @@ -71,6 +73,7 @@ var testMessages = []string{ paddedMessage, crlfMessage, tabMessage, + escapedMessage, } func TestGenerateFuzzCorpus(t *testing.T) { @@ -374,6 +377,18 @@ func TestEventUnpack(t *testing.T) { "spt": IntegerField(1232), }, e.Extensions) }) + + t.Run("escapes are replaced", func(t *testing.T) { + var e Event + err := e.Unpack(escapedMessage) + assert.NoError(t, err) + assert.Equal(t, `security\compliance`, e.DeviceVendor) + assert.Equal(t, `threat|->manager`, e.DeviceProduct) + assert.Equal(t, map[string]*Field{ + "spt": IntegerField(1232), + "msg": StringField("Newlines in messages\nare allowed.\r\nAnd so are carriage feeds\\newlines\\=."), + }, e.Extensions) + }) } func TestEventUnpackWithFullExtensionNames(t *testing.T) { diff --git a/x-pack/filebeat/processors/decode_cef/cef/parser.go b/x-pack/filebeat/processors/decode_cef/cef/parser.go index cd7658735271..b9e19b03e7c2 100644 --- a/x-pack/filebeat/processors/decode_cef/cef/parser.go +++ b/x-pack/filebeat/processors/decode_cef/cef/parser.go @@ -18,25 +18,26 @@ var _cef_eof_actions []byte = []byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 16, 16, 0, 0, 0, 0, - 19, 22, 22, 22, 19, 22, 22, 22, - 0, + 0, 0, 0, 0, 0, 0, 0, 25, + 25, 0, 0, 0, 0, 28, 32, 32, + 32, 28, 32, 32, 32, 35, 35, 0, } const cef_start int = 1 -const cef_first_final int = 31 +const cef_first_final int = 36 const cef_error int = 0 -const cef_en_gobble_extension int = 28 +const cef_en_gobble_extension int = 33 const cef_en_main int = 1 -const cef_en_main_cef_extensions int = 24 +const cef_en_main_cef_extensions int = 29 //line cef.rl:16 // unpack unpacks a CEF message. func (e *Event) unpack(data string) error { cs, p, pe, eof := 0, 0, len(data), len(data) - mark := 0 + mark, mark_slash := 0, 0 + var escapes []int // Extension key. var extKey string @@ -50,12 +51,12 @@ func (e *Event) unpack(data string) error { e.init(data) -//line parser.go:55 +//line parser.go:56 { cs = cef_start } -//line parser.go:60 +//line parser.go:61 { if (p) == (pe) { goto _test_eof @@ -119,471 +120,545 @@ func (e *Event) unpack(data string) error { case 9: switch data[(p)] { case 92: - goto tr11 + goto tr14 case 124: - goto tr11 + goto tr14 } goto tr1 case 10: switch data[(p)] { case 92: - goto tr15 - case 124: goto tr16 + case 124: + goto tr17 } - goto tr14 + goto tr15 case 11: switch data[(p)] { case 92: - goto tr18 - case 124: goto tr19 + case 124: + goto tr20 } - goto tr17 + goto tr18 case 12: switch data[(p)] { case 92: - goto tr17 + goto tr22 case 124: - goto tr17 + goto tr23 } - goto tr1 + goto tr21 case 13: switch data[(p)] { case 92: - goto tr21 + goto tr24 case 124: - goto tr22 + goto tr24 } - goto tr20 + goto tr1 case 14: switch data[(p)] { case 92: - goto tr24 + goto tr26 case 124: - goto tr25 + goto tr27 } - goto tr23 + goto tr25 case 15: switch data[(p)] { case 92: - goto tr23 + goto tr29 case 124: - goto tr23 + goto tr30 } - goto tr1 + goto tr28 case 16: switch data[(p)] { case 92: - goto tr27 + goto tr32 case 124: - goto tr28 + goto tr33 } - goto tr26 + goto tr31 case 17: switch data[(p)] { case 92: - goto tr30 + goto tr34 case 124: - goto tr31 + goto tr34 } - goto tr29 + goto tr1 case 18: switch data[(p)] { case 92: - goto tr29 + goto tr36 case 124: - goto tr29 + goto tr37 } - goto tr1 + goto tr35 case 19: switch data[(p)] { case 92: - goto tr33 + goto tr39 case 124: - goto tr34 + goto tr40 } - goto tr32 + goto tr38 case 20: switch data[(p)] { case 92: - goto tr36 + goto tr42 case 124: - goto tr37 + goto tr43 } - goto tr35 + goto tr41 case 21: switch data[(p)] { case 92: - goto tr35 + goto tr44 case 124: - goto tr35 + goto tr44 } goto tr1 case 22: + switch data[(p)] { + case 92: + goto tr46 + case 124: + goto tr47 + } + goto tr45 + case 23: + switch data[(p)] { + case 92: + goto tr49 + case 124: + goto tr50 + } + goto tr48 + case 24: + switch data[(p)] { + case 92: + goto tr52 + case 124: + goto tr53 + } + goto tr51 + case 25: + switch data[(p)] { + case 92: + goto tr54 + case 124: + goto tr54 + } + goto tr1 + case 26: + switch data[(p)] { + case 92: + goto tr56 + case 124: + goto tr57 + } + goto tr55 + case 27: switch data[(p)] { case 45: - goto tr38 + goto tr58 case 124: - goto tr39 + goto tr59 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr38 + goto tr58 } case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr38 + goto tr58 } default: - goto tr38 + goto tr58 } goto tr1 - case 23: + case 28: switch data[(p)] { case 45: - goto tr40 + goto tr60 case 124: - goto tr41 + goto tr61 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr40 + goto tr60 } case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr40 + goto tr60 } default: - goto tr40 + goto tr60 } goto tr1 - case 31: + case 36: switch data[(p)] { case 32: - goto tr42 + goto tr62 case 95: - goto tr43 + goto tr63 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr43 + goto tr63 } case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr43 + goto tr63 } default: - goto tr43 + goto tr63 } goto tr1 - case 24: + case 29: switch data[(p)] { case 32: - goto tr42 + goto tr62 case 95: - goto tr43 + goto tr63 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr43 + goto tr63 } case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr43 + goto tr63 } default: - goto tr43 + goto tr63 } goto tr1 - case 25: + case 30: switch data[(p)] { case 44: - goto tr44 + goto tr64 case 46: - goto tr44 + goto tr64 case 61: - goto tr45 + goto tr65 case 93: - goto tr44 + goto tr64 case 95: - goto tr44 + goto tr64 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr44 + goto tr64 } case data[(p)] > 91: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr44 + goto tr64 } default: - goto tr44 + goto tr64 } goto tr1 - case 32: + case 37: switch data[(p)] { case 32: - goto tr55 + goto tr75 case 61: - goto tr46 + goto tr66 case 92: - goto tr56 + goto tr76 } if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr54 + goto tr74 } - goto tr53 - case 33: + goto tr73 + case 38: switch data[(p)] { case 32: - goto tr58 + goto tr79 case 61: - goto tr46 + goto tr66 case 92: - goto tr59 + goto tr80 } if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr57 + goto tr78 } - goto tr48 - case 34: + goto tr77 + case 39: switch data[(p)] { case 32: - goto tr58 + goto tr79 case 61: - goto tr46 + goto tr66 case 92: - goto tr59 + goto tr80 case 95: - goto tr60 + goto tr81 } switch { case data[(p)] < 48: if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr57 + goto tr78 } case data[(p)] > 57: switch { case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr60 + goto tr81 } case data[(p)] >= 65: - goto tr60 + goto tr81 } default: - goto tr60 + goto tr81 } - goto tr48 - case 35: + goto tr77 + case 40: switch data[(p)] { case 32: - goto tr58 + goto tr79 case 44: - goto tr61 + goto tr82 case 46: - goto tr61 + goto tr82 case 61: - goto tr62 + goto tr83 case 92: - goto tr59 + goto tr80 case 95: - goto tr61 + goto tr82 } switch { case data[(p)] < 48: if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr57 + goto tr78 } case data[(p)] > 57: switch { case data[(p)] > 93: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr61 + goto tr82 } case data[(p)] >= 65: - goto tr61 + goto tr82 } default: - goto tr61 + goto tr82 } - goto tr48 - case 36: + goto tr77 + case 41: switch data[(p)] { case 32: - goto tr65 + goto tr86 case 61: - goto tr46 - case 92: goto tr66 + case 92: + goto tr87 } if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr64 + goto tr85 } - goto tr63 - case 37: + goto tr84 + case 42: switch data[(p)] { case 32: - goto tr68 + goto tr90 case 61: - goto tr46 + goto tr66 case 92: - goto tr69 + goto tr91 } if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr67 + goto tr89 } - goto tr47 - case 38: + goto tr88 + case 43: switch data[(p)] { case 32: - goto tr68 + goto tr90 case 61: - goto tr46 + goto tr66 case 92: - goto tr69 + goto tr91 case 95: - goto tr70 + goto tr92 } switch { case data[(p)] < 48: if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr67 + goto tr89 } case data[(p)] > 57: switch { case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr70 + goto tr92 } case data[(p)] >= 65: - goto tr70 + goto tr92 } default: - goto tr70 + goto tr92 } - goto tr47 - case 39: + goto tr88 + case 44: switch data[(p)] { case 32: - goto tr68 + goto tr90 case 44: - goto tr71 + goto tr93 case 46: - goto tr71 + goto tr93 case 61: - goto tr62 + goto tr83 case 92: - goto tr69 + goto tr91 case 95: - goto tr71 + goto tr93 } switch { case data[(p)] < 48: if 9 <= data[(p)] && data[(p)] <= 13 { - goto tr67 + goto tr89 } case data[(p)] > 57: switch { case data[(p)] > 93: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr71 + goto tr93 } case data[(p)] >= 65: - goto tr71 + goto tr93 } default: - goto tr71 + goto tr93 } - goto tr47 - case 26: + goto tr88 + case 31: switch data[(p)] { case 61: - goto tr47 + goto tr67 case 92: - goto tr47 + goto tr67 + case 110: + goto tr67 + case 114: + goto tr67 } - goto tr46 - case 27: + goto tr66 + case 45: switch data[(p)] { + case 32: + goto tr96 case 61: - goto tr48 + goto tr66 case 92: - goto tr48 + goto tr97 } - goto tr46 - case 28: + if 9 <= data[(p)] && data[(p)] <= 13 { + goto tr95 + } + goto tr94 + case 32: + switch data[(p)] { + case 61: + goto tr68 + case 92: + goto tr68 + case 110: + goto tr68 + case 114: + goto tr68 + } + goto tr66 + case 46: + switch data[(p)] { + case 32: + goto tr100 + case 61: + goto tr66 + case 92: + goto tr101 + } + if 9 <= data[(p)] && data[(p)] <= 13 { + goto tr99 + } + goto tr98 + case 33: if data[(p)] == 32 { - goto tr50 + goto tr70 } - goto tr49 - case 29: + goto tr69 + case 34: switch data[(p)] { case 32: - goto tr50 + goto tr70 case 95: - goto tr51 + goto tr71 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr51 + goto tr71 } case data[(p)] > 90: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr51 + goto tr71 } default: - goto tr51 + goto tr71 } - goto tr49 - case 30: + goto tr69 + case 35: switch data[(p)] { case 32: - goto tr50 + goto tr70 case 44: - goto tr51 + goto tr71 case 46: - goto tr51 + goto tr71 case 61: - goto tr52 + goto tr72 case 93: - goto tr51 + goto tr71 case 95: - goto tr51 + goto tr71 } switch { case data[(p)] < 65: if 48 <= data[(p)] && data[(p)] <= 57 { - goto tr51 + goto tr71 } case data[(p)] > 91: if 97 <= data[(p)] && data[(p)] <= 122 { - goto tr51 + goto tr71 } default: - goto tr51 + goto tr71 } - goto tr49 - case 40: + goto tr69 + case 47: if data[(p)] == 32 { - goto tr50 + goto tr70 } - goto tr49 + goto tr69 } tr1: cs = 0 goto _again - tr46: + tr66: cs = 0 - goto f15 + goto f24 tr0: cs = 2 goto _again @@ -611,364 +686,574 @@ func (e *Event) unpack(data string) error { tr8: cs = 8 goto f0 - tr12: - cs = 9 - goto _again + tr15: + cs = 8 + goto f6 tr9: cs = 9 - goto f0 - tr10: - cs = 10 goto f2 - tr13: + tr12: + cs = 9 + goto f4 + tr16: + cs = 9 + goto f7 + tr14: cs = 10 - goto f3 - tr17: - cs = 11 goto _again - tr14: + tr10: cs = 11 - goto f0 - tr18: + goto f3 + tr13: + cs = 11 + goto f5 + tr17: + cs = 11 + goto f8 + tr21: cs = 12 goto _again - tr15: + tr18: cs = 12 goto f0 - tr16: + tr25: + cs = 12 + goto f6 + tr19: + cs = 13 + goto f2 + tr22: cs = 13 goto f4 - tr19: + tr26: cs = 13 - goto f5 - tr23: + goto f7 + tr24: cs = 14 goto _again tr20: - cs = 14 - goto f0 - tr24: cs = 15 - goto _again - tr21: + goto f9 + tr23: + cs = 15 + goto f10 + tr27: cs = 15 + goto f11 + tr31: + cs = 16 + goto _again + tr28: + cs = 16 goto f0 - tr22: + tr35: cs = 16 goto f6 - tr25: - cs = 16 - goto f7 tr29: cs = 17 - goto _again - tr26: + goto f2 + tr32: cs = 17 - goto f0 - tr30: + goto f4 + tr36: + cs = 17 + goto f7 + tr34: cs = 18 goto _again - tr27: - cs = 18 - goto f0 - tr28: + tr30: cs = 19 - goto f8 - tr31: + goto f12 + tr33: cs = 19 - goto f9 - tr35: + goto f13 + tr37: + cs = 19 + goto f14 + tr41: cs = 20 goto _again - tr32: + tr38: cs = 20 goto f0 - tr36: + tr45: + cs = 20 + goto f6 + tr39: cs = 21 - goto _again - tr33: + goto f2 + tr42: cs = 21 - goto f0 - tr34: - cs = 22 - goto f10 - tr37: + goto f4 + tr46: + cs = 21 + goto f7 + tr44: cs = 22 - goto f11 + goto _again tr40: cs = 23 - goto _again - tr38: + goto f15 + tr43: cs = 23 - goto f0 - tr42: + goto f16 + tr47: + cs = 23 + goto f17 + tr51: cs = 24 goto _again - tr44: + tr48: + cs = 24 + goto f0 + tr55: + cs = 24 + goto f6 + tr49: cs = 25 - goto _again - tr43: + goto f2 + tr52: cs = 25 - goto f0 - tr69: + goto f4 + tr56: + cs = 25 + goto f7 + tr54: cs = 26 goto _again - tr66: - cs = 26 - goto f20 - tr59: + tr50: cs = 27 - goto _again - tr56: + goto f18 + tr53: + cs = 27 + goto f19 + tr57: cs = 27 goto f20 - tr49: + tr60: cs = 28 goto _again - tr50: - cs = 29 + tr58: + cs = 28 goto f0 - tr51: + tr62: + cs = 29 + goto _again + tr64: cs = 30 goto _again - tr39: + tr63: + cs = 30 + goto f0 + tr91: cs = 31 - goto f12 - tr41: + goto f4 + tr97: cs = 31 - goto f13 - tr45: + goto f7 + tr87: + cs = 31 + goto f30 + tr80: cs = 32 - goto f14 - tr57: + goto f4 + tr101: + cs = 32 + goto f7 + tr76: + cs = 32 + goto f30 + tr69: cs = 33 goto _again - tr48: - cs = 33 - goto f16 - tr53: - cs = 33 - goto f19 - tr54: - cs = 33 - goto f20 - tr58: + tr70: cs = 34 + goto f0 + tr71: + cs = 35 goto _again - tr55: - cs = 34 - goto f20 + tr59: + cs = 36 + goto f21 tr61: - cs = 35 - goto f16 - tr60: - cs = 35 - goto f22 - tr62: cs = 36 - goto f14 - tr67: - cs = 37 - goto _again - tr47: - cs = 37 - goto f16 - tr63: - cs = 37 - goto f19 - tr64: + goto f22 + tr65: cs = 37 - goto f20 - tr68: + goto f23 + tr78: cs = 38 goto _again - tr65: + tr99: cs = 38 - goto f20 - tr71: + goto f6 + tr77: + cs = 38 + goto f25 + tr73: + cs = 38 + goto f28 + tr74: + cs = 38 + goto f29 + tr98: + cs = 38 + goto f35 + tr79: cs = 39 - goto f16 - tr70: + goto _again + tr100: cs = 39 - goto f23 - tr52: + goto f6 + tr75: + cs = 39 + goto f29 + tr82: cs = 40 - goto f17 + goto f25 + tr81: + cs = 40 + goto f32 + tr83: + cs = 41 + goto f23 + tr89: + cs = 42 + goto _again + tr95: + cs = 42 + goto f6 + tr88: + cs = 42 + goto f25 + tr84: + cs = 42 + goto f28 + tr85: + cs = 42 + goto f29 + tr94: + cs = 42 + goto f35 + tr90: + cs = 43 + goto _again + tr96: + cs = 43 + goto f6 + tr86: + cs = 43 + goto f29 + tr93: + cs = 44 + goto f25 + tr92: + cs = 44 + goto f33 + tr67: + cs = 45 + goto f25 + tr68: + cs = 46 + goto f25 + tr72: + cs = 47 + goto f26 f0: -//line cef.rl:37 +//line cef.rl:38 mark = p + goto _again + f4: +//line cef.rl:41 + + mark_slash = p + + goto _again + f6: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + goto _again f1: -//line cef.rl:40 +//line cef.rl:47 e.Version, _ = strconv.Atoi(data[mark:p]) goto _again - f3: -//line cef.rl:43 + f5: +//line cef.rl:50 - e.DeviceVendor = replaceHeaderEscapes(data[mark:p]) + e.DeviceVendor = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f5: -//line cef.rl:46 + f10: +//line cef.rl:54 - e.DeviceProduct = replaceHeaderEscapes(data[mark:p]) + e.DeviceProduct = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f7: -//line cef.rl:49 + f13: +//line cef.rl:58 - e.DeviceVersion = replaceHeaderEscapes(data[mark:p]) + e.DeviceVersion = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f9: -//line cef.rl:52 + f16: +//line cef.rl:62 - e.DeviceEventClassID = replaceHeaderEscapes(data[mark:p]) + e.DeviceEventClassID = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f11: -//line cef.rl:55 + f19: +//line cef.rl:66 - e.Name = replaceHeaderEscapes(data[mark:p]) + e.Name = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f13: -//line cef.rl:58 + f22: +//line cef.rl:70 e.Severity = data[mark:p] goto _again - f14: -//line cef.rl:61 + f23: +//line cef.rl:73 // A new extension key marks the end of the last extension value. if len(extKey) > 0 && extValueStart <= mark-1 { - e.pushExtension(extKey, replaceExtensionEscapes(data[extValueStart:mark-1])) - extKey, extValueStart, extValueEnd = "", 0, 0 + e.pushExtension(extKey, replaceEscapes(data[extValueStart:mark-1], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] } extKey = data[mark:p] goto _again - f20: -//line cef.rl:69 + f29: +//line cef.rl:81 extValueStart = p extValueEnd = p goto _again - f16: -//line cef.rl:73 + f25: +//line cef.rl:85 extValueEnd = p + 1 goto _again - f15: -//line cef.rl:83 + f24: +//line cef.rl:95 recoveredErrs = append(recoveredErrs, fmt.Errorf("malformed value for %s at pos %d", extKey, p+1)) (p)-- - cs = 28 + cs = 33 + goto _again - f17: -//line cef.rl:87 + f26: +//line cef.rl:99 extKey, extValueStart, extValueEnd = "", 0, 0 // Resume processing at p, the start of the next extension key. p = mark - cs = 24 + cs = 29 + goto _again f2: -//line cef.rl:37 +//line cef.rl:38 mark = p -//line cef.rl:43 +//line cef.rl:41 - e.DeviceVendor = replaceHeaderEscapes(data[mark:p]) + mark_slash = p goto _again - f4: -//line cef.rl:37 + f3: +//line cef.rl:38 mark = p -//line cef.rl:46 +//line cef.rl:50 - e.DeviceProduct = replaceHeaderEscapes(data[mark:p]) + e.DeviceVendor = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f6: -//line cef.rl:37 + f9: +//line cef.rl:38 mark = p -//line cef.rl:49 +//line cef.rl:54 - e.DeviceVersion = replaceHeaderEscapes(data[mark:p]) + e.DeviceProduct = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f8: -//line cef.rl:37 + f12: +//line cef.rl:38 mark = p -//line cef.rl:52 +//line cef.rl:58 - e.DeviceEventClassID = replaceHeaderEscapes(data[mark:p]) + e.DeviceVersion = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f10: -//line cef.rl:37 + f15: +//line cef.rl:38 mark = p -//line cef.rl:55 +//line cef.rl:62 - e.Name = replaceHeaderEscapes(data[mark:p]) + e.DeviceEventClassID = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] goto _again - f12: -//line cef.rl:37 + f18: +//line cef.rl:38 mark = p -//line cef.rl:58 +//line cef.rl:66 + + e.Name = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f21: +//line cef.rl:38 + + mark = p + +//line cef.rl:70 e.Severity = data[mark:p] goto _again - f23: -//line cef.rl:37 + f33: +//line cef.rl:38 mark = p -//line cef.rl:73 +//line cef.rl:85 extValueEnd = p + 1 goto _again - f19: -//line cef.rl:69 + f7: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:41 + + mark_slash = p + + goto _again + f8: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:50 + + e.DeviceVendor = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f11: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:54 + + e.DeviceProduct = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f14: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:58 + + e.DeviceVersion = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f17: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:62 + + e.DeviceEventClassID = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f20: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:66 + + e.Name = replaceEscapes(data[mark:p], mark, escapes) + escapes = escapes[:0] + + goto _again + f35: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:85 + + extValueEnd = p + 1 + + goto _again + f30: +//line cef.rl:81 extValueStart = p extValueEnd = p -//line cef.rl:73 +//line cef.rl:41 + + mark_slash = p + + goto _again + f28: +//line cef.rl:81 + + extValueStart = p + extValueEnd = p + +//line cef.rl:85 extValueEnd = p + 1 goto _again - f22: -//line cef.rl:73 + f32: +//line cef.rl:85 extValueEnd = p + 1 -//line cef.rl:37 +//line cef.rl:38 mark = p @@ -986,38 +1271,50 @@ func (e *Event) unpack(data string) error { } if (p) == eof { switch _cef_eof_actions[cs] { - case 22: -//line cef.rl:76 + case 32: +//line cef.rl:88 // Reaching the EOF marks the end of the final extension value. if len(extKey) > 0 && extValueStart <= extValueEnd { - e.pushExtension(extKey, replaceExtensionEscapes(data[extValueStart:extValueEnd])) - extKey, extValueStart, extValueEnd = "", 0, 0 + e.pushExtension(extKey, replaceEscapes(data[extValueStart:extValueEnd], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] } - case 16: -//line cef.rl:83 + case 25: +//line cef.rl:95 recoveredErrs = append(recoveredErrs, fmt.Errorf("malformed value for %s at pos %d", extKey, p+1)) (p)-- - cs = 28 - goto _again + cs = 33 + + case 35: +//line cef.rl:44 + + escapes = append(escapes, mark_slash, p) + +//line cef.rl:88 + + // Reaching the EOF marks the end of the final extension value. + if len(extKey) > 0 && extValueStart <= extValueEnd { + e.pushExtension(extKey, replaceEscapes(data[extValueStart:extValueEnd], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] + } - case 19: -//line cef.rl:69 + case 28: +//line cef.rl:81 extValueStart = p extValueEnd = p -//line cef.rl:76 +//line cef.rl:88 // Reaching the EOF marks the end of the final extension value. if len(extKey) > 0 && extValueStart <= extValueEnd { - e.pushExtension(extKey, replaceExtensionEscapes(data[extValueStart:extValueEnd])) - extKey, extValueStart, extValueEnd = "", 0, 0 + e.pushExtension(extKey, replaceEscapes(data[extValueStart:extValueEnd], extValueStart, escapes)) + extKey, extValueStart, extValueEnd, escapes = "", 0, 0, escapes[:0] } -//line parser.go:883 +//line parser.go:1116 } } @@ -1026,7 +1323,7 @@ func (e *Event) unpack(data string) error { } } -//line cef.rl:145 +//line cef.rl:161 // Check if state machine completed. if cs < cef_first_final { From 4154447955de13355fc13c3399b8b8f875683c64 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Thu, 9 Dec 2021 10:13:56 -0500 Subject: [PATCH 068/172] Update cloud.google.com/go/pubsub and supporting libraries (#29353) Moving from v1.3.1 to v1.17.1. Updating via `go get cloud.google.com/go/pubsub`. Relates #29352 --- NOTICE.txt | 486 ++++++++++++++++++++++++++++++++++++++++++++++++----- go.mod | 14 +- go.sum | 66 +++++++- 3 files changed, 506 insertions(+), 60 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 8f660fe88437..5761502320cc 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -10,12 +10,12 @@ Third party libraries used by the Elastic Beats project: -------------------------------------------------------------------------------- -Dependency : cloud.google.com/go -Version: v0.83.0 +Dependency : cloud.google.com/go/bigquery +Version: v1.8.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/cloud.google.com/go@v0.83.0/LICENSE: +Contents of probable licence file $GOMODCACHE/cloud.google.com/go/bigquery@v1.8.0/LICENSE: Apache License @@ -222,12 +222,12 @@ Contents of probable licence file $GOMODCACHE/cloud.google.com/go@v0.83.0/LICENS -------------------------------------------------------------------------------- -Dependency : cloud.google.com/go/bigquery -Version: v1.8.0 +Dependency : cloud.google.com/go/monitoring +Version: v1.1.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/cloud.google.com/go/bigquery@v1.8.0/LICENSE: +Contents of probable licence file $GOMODCACHE/cloud.google.com/go/monitoring@v1.1.0/LICENSE: Apache License @@ -435,11 +435,11 @@ Contents of probable licence file $GOMODCACHE/cloud.google.com/go/bigquery@v1.8. -------------------------------------------------------------------------------- Dependency : cloud.google.com/go/pubsub -Version: v1.3.1 +Version: v1.17.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/cloud.google.com/go/pubsub@v1.3.1/LICENSE: +Contents of probable licence file $GOMODCACHE/cloud.google.com/go/pubsub@v1.17.1/LICENSE: Apache License @@ -16767,11 +16767,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/oauth2 -Version: v0.0.0-20210514164344-f6687ab2804c +Version: v0.0.0-20211005180243-6b3c2da341f1 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/oauth2@v0.0.0-20210514164344-f6687ab2804c/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/oauth2@v0.0.0-20211005180243-6b3c2da341f1/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -16915,11 +16915,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/time -Version: v0.0.0-20210611083556-38a9dc6acbc6 +Version: v0.0.0-20210723032227-1f47c861a9ac Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.0.0-20210611083556-38a9dc6acbc6/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.0.0-20210723032227-1f47c861a9ac/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -16989,11 +16989,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : google.golang.org/api -Version: v0.48.0 +Version: v0.58.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/google.golang.org/api@v0.48.0/LICENSE: +Contents of probable licence file $GOMODCACHE/google.golang.org/api@v0.58.0/LICENSE: Copyright (c) 2011 Google Inc. All rights reserved. @@ -19331,6 +19331,430 @@ Public License instead of this License. Indirect dependencies +-------------------------------------------------------------------------------- +Dependency : cloud.google.com/go +Version: v0.97.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/cloud.google.com/go@v0.97.0/LICENSE: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +-------------------------------------------------------------------------------- +Dependency : cloud.google.com/go/kms +Version: v1.0.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/cloud.google.com/go/kms@v1.0.0/LICENSE: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + -------------------------------------------------------------------------------- Dependency : cloud.google.com/go/storage Version: v1.10.0 @@ -26318,11 +26742,11 @@ Contents of probable licence file $GOMODCACHE/github.com/google/shlex@v0.0.0-201 -------------------------------------------------------------------------------- Dependency : github.com/googleapis/gax-go/v2 -Version: v2.0.5 +Version: v2.1.1 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/googleapis/gax-go/v2@v2.0.5/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/googleapis/gax-go/v2@v2.1.1/LICENSE: Copyright 2016, Google Inc. All rights reserved. @@ -30055,36 +30479,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/jstemmer/go-junit-report -Version: v0.9.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/jstemmer/go-junit-report@v0.9.1/LICENSE: - -Copyright (c) 2012 Joel Stemmer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------------- Dependency : github.com/jtolds/gls Version: v4.20.0+incompatible diff --git a/go.mod b/go.mod index 5330c1dc46dc..70af77f8e936 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/elastic/beats/v7 go 1.17 require ( - cloud.google.com/go v0.83.0 cloud.google.com/go/bigquery v1.8.0 - cloud.google.com/go/pubsub v1.3.1 + cloud.google.com/go/monitoring v1.1.0 + cloud.google.com/go/pubsub v1.17.1 code.cloudfoundry.org/go-diodes v0.0.0-20190809170250-f77fb823c7ee // indirect code.cloudfoundry.org/go-loggregator v7.4.0+incompatible code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a // indirect @@ -165,13 +165,13 @@ require ( golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 golang.org/x/net v0.0.0-20211020060615-d418f374d309 - golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c + golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 golang.org/x/text v0.3.7 - golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/tools v0.1.7 - google.golang.org/api v0.48.0 + google.golang.org/api v0.58.0 google.golang.org/genproto v0.0.0-20211021150943-2b146023228c google.golang.org/grpc v1.41.0 google.golang.org/protobuf v1.27.1 @@ -193,6 +193,7 @@ require ( ) require ( + cloud.google.com/go v0.97.0 // indirect code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect github.com/Azure/azure-amqp-common-go/v3 v3.2.1 // indirect github.com/Azure/azure-pipeline-go v0.2.1 // indirect @@ -227,7 +228,7 @@ require ( github.com/google/gofuzz v1.1.0 // indirect github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/gnostic v0.4.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/cronexpr v1.1.0 // indirect @@ -246,7 +247,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.11 // indirect - github.com/jstemmer/go-junit-report v0.9.1 // indirect github.com/karrick/godirwalk v1.15.6 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/markbates/pkger v0.17.0 // indirect diff --git a/go.sum b/go.sum index 64389aae72c6..28f0ed5236f0 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,14 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -34,11 +40,16 @@ cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm cloud.google.com/go/bigtable v1.3.0/go.mod h1:z5EyKrPE8OQmeg4h5MNdKvuSnI9CCT49Ki3f23aBzio= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/kms v1.0.0 h1:YkIeqPXqTAlwXk3Z2/WG0d6h1tqJQjU354WftjEoP9E= +cloud.google.com/go/kms v1.0.0/go.mod h1:nhUehi+w7zht2XrUfvTRNpxrfayBHqP4lu2NSywui/0= +cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo= +cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.17.1 h1:s2UGTTphpnUQ0Wppkp2OprR4pS3nlBpPvyL2GV9cqdc= +cloud.google.com/go/pubsub v1.17.1/go.mod h1:4qDxMr1WsM9+aQAz36ltDwCIM+R0QdlseyFjBuNvnss= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -854,6 +865,7 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -864,8 +876,10 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= @@ -1043,7 +1057,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3TDYCcsFy9hpqb0= @@ -1786,8 +1799,12 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1915,7 +1932,13 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1941,8 +1964,9 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 h1:Vv0JUPWTyeqUq42B2WJ1FeIDjjvGKoA2Ss+Ts0lAVbs= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2023,6 +2047,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2060,8 +2086,15 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0 h1:RDAPWfNFY06dffEXfn7hZF5Fr1ZbnChzfQZAPyBd1+I= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0 h1:MDkAbYIB1JpSgCTOCYYoIec/coMlKK4oVbpnBLLcyT0= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2123,6 +2156,23 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -2155,6 +2205,8 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= From 7afc4e17e851bd4daf7c2338c7530c1abb45b6ee Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 9 Dec 2021 17:21:49 +0200 Subject: [PATCH 069/172] Update k8s autodiscover metadata in nodes earlier (#29289) --- CHANGELOG.next.asciidoc | 1 + .../autodiscover/providers/kubernetes/pod.go | 207 ++---------------- .../providers/kubernetes/pod_test.go | 57 ++++- libbeat/common/kubernetes/eventhandler.go | 109 +++++++++ libbeat/common/kubernetes/metadata/pod.go | 4 - .../common/kubernetes/metadata/pod_test.go | 8 +- libbeat/common/kubernetes/util.go | 111 +++++++++- libbeat/common/kubernetes/util_test.go | 10 +- .../add_kubernetes_metadata/indexers_test.go | 9 +- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../composable/providers/kubernetes/pod.go | 156 ++----------- 11 files changed, 335 insertions(+), 338 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 93d6c7cd1bed..3f99e29360fe 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -297,6 +297,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add http.pprof.enabled option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] - Support custom analyzers in fields.yml. {issue}28540[28540] {pull}28926[28926] - SASL/SCRAM in the Kafka output is no longer beta. {pull}29126[29126] +- Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] - Support self signed certificates on outputs {pull}29229[29229] *Auditbeat* diff --git a/libbeat/autodiscover/providers/kubernetes/pod.go b/libbeat/autodiscover/providers/kubernetes/pod.go index 945e39467b56..be423080068b 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod.go +++ b/libbeat/autodiscover/providers/kubernetes/pod.go @@ -33,7 +33,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/bus" "github.com/elastic/beats/v7/libbeat/common/kubernetes" "github.com/elastic/beats/v7/libbeat/common/kubernetes/metadata" - "github.com/elastic/beats/v7/libbeat/common/safemapstr" "github.com/elastic/beats/v7/libbeat/logp" ) @@ -125,8 +124,13 @@ func NewPodEventer(uuid uuid.UUID, cfg *common.Config, client k8s.Interface, pub watcher.AddEventHandler(p) + if nodeWatcher != nil && (config.Hints.Enabled() || metaConf.Node.Enabled()) { + updater := kubernetes.NewNodePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) + nodeWatcher.AddEventHandler(updater) + } + if namespaceWatcher != nil && (config.Hints.Enabled() || metaConf.Namespace.Enabled()) { - updater := newNamespacePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) + updater := kubernetes.NewNamespacePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) namespaceWatcher.AddEventHandler(updater) } @@ -256,47 +260,6 @@ func (p *pod) Stop() { } } -type containerInPod struct { - id string - runtime string - spec kubernetes.Container - status kubernetes.PodContainerStatus -} - -// getContainersInPod returns all the containers defined in a pod and their statuses. -// It includes init and ephemeral containers. -func getContainersInPod(pod *kubernetes.Pod) []*containerInPod { - var containers []*containerInPod - for _, c := range pod.Spec.Containers { - containers = append(containers, &containerInPod{spec: c}) - } - for _, c := range pod.Spec.InitContainers { - containers = append(containers, &containerInPod{spec: c}) - } - for _, c := range pod.Spec.EphemeralContainers { - c := kubernetes.Container(c.EphemeralContainerCommon) - containers = append(containers, &containerInPod{spec: c}) - } - - statuses := make(map[string]*kubernetes.PodContainerStatus) - mapStatuses := func(s []kubernetes.PodContainerStatus) { - for i := range s { - statuses[s[i].Name] = &s[i] - } - } - mapStatuses(pod.Status.ContainerStatuses) - mapStatuses(pod.Status.InitContainerStatuses) - mapStatuses(pod.Status.EphemeralContainerStatuses) - for _, c := range containers { - if s, ok := statuses[c.spec.Name]; ok { - c.id, c.runtime = kubernetes.ContainerIDWithRuntime(*s) - c.status = *s - } - } - - return containers -} - // emit emits the events for the given pod according to its state and // the given flag. // It emits a pod event if the pod has at least a running container, @@ -312,15 +275,15 @@ func getContainersInPod(pod *kubernetes.Pod) []*containerInPod { // Network information is only included in events for running containers // and for pods with at least one running container. func (p *pod) emit(pod *kubernetes.Pod, flag string) { - annotations := podAnnotations(pod) - namespaceAnnotations := podNamespaceAnnotations(pod, p.namespaceWatcher) + annotations := kubernetes.PodAnnotations(pod) + namespaceAnnotations := kubernetes.PodNamespaceAnnotations(pod, p.namespaceWatcher) eventList := make([][]bus.Event, 0) portsMap := common.MapStr{} - containers := getContainersInPod(pod) + containers := kubernetes.GetContainersInPod(pod) anyContainerRunning := false for _, c := range containers { - if c.status.State.Running != nil { + if c.Status.State.Running != nil { anyContainerRunning = true } @@ -339,7 +302,7 @@ func (p *pod) emit(pod *kubernetes.Pod, flag string) { eventList = append([][]bus.Event{{event}}, eventList...) } - delay := (flag == "stop" && podTerminated(pod, containers)) + delay := (flag == "stop" && kubernetes.PodTerminated(pod, containers)) p.publishAll(eventList, delay) } @@ -350,22 +313,22 @@ func (p *pod) emit(pod *kubernetes.Pod, flag string) { // running. // If the container ID is unknown, only "stop" events are generated. // It also returns a map with the named ports. -func (p *pod) containerPodEvents(flag string, pod *kubernetes.Pod, c *containerInPod, annotations, namespaceAnnotations common.MapStr) ([]bus.Event, common.MapStr) { - if c.id == "" && flag != "stop" { +func (p *pod) containerPodEvents(flag string, pod *kubernetes.Pod, c *kubernetes.ContainerInPod, annotations, namespaceAnnotations common.MapStr) ([]bus.Event, common.MapStr) { + if c.ID == "" && flag != "stop" { return nil, nil } // This must be an id that doesn't depend on the state of the container // so it works also on `stop` if containers have been already deleted. - eventID := fmt.Sprintf("%s.%s", pod.GetObjectMeta().GetUID(), c.spec.Name) + eventID := fmt.Sprintf("%s.%s", pod.GetObjectMeta().GetUID(), c.Spec.Name) - meta := p.metagen.Generate(pod, metadata.WithFields("container.name", c.spec.Name)) + meta := p.metagen.Generate(pod, metadata.WithFields("container.name", c.Spec.Name)) cmeta := common.MapStr{ - "id": c.id, - "runtime": c.runtime, + "id": c.ID, + "runtime": c.Runtime, "image": common.MapStr{ - "name": c.spec.Image, + "name": c.Spec.Image, }, } @@ -375,16 +338,16 @@ func (p *pod) containerPodEvents(flag string, pod *kubernetes.Pod, c *containerI kubemeta = kubemeta.Clone() kubemeta["annotations"] = annotations kubemeta["container"] = common.MapStr{ - "id": c.id, - "name": c.spec.Name, - "image": c.spec.Image, - "runtime": c.runtime, + "id": c.ID, + "name": c.Spec.Name, + "image": c.Spec.Image, + "runtime": c.Runtime, } if len(namespaceAnnotations) != 0 { kubemeta["namespace_annotations"] = namespaceAnnotations } - ports := c.spec.Ports + ports := c.Spec.Ports if len(ports) == 0 { // Ensure that at least one event is generated for this container. // Set port to zero to signify that the event is from a container @@ -408,7 +371,7 @@ func (p *pod) containerPodEvents(flag string, pod *kubernetes.Pod, c *containerI } // Include network information only if the container is running, // so templates that need network don't generate a config. - if c.status.State.Running != nil { + if c.Status.State.Running != nil { if port.Name != "" && port.ContainerPort != 0 { portsMap[port.Name] = port.ContainerPort } @@ -457,71 +420,6 @@ func (p *pod) podEvent(flag string, pod *kubernetes.Pod, ports common.MapStr, in return event } -// podAnnotations returns the annotations in a pod -func podAnnotations(pod *kubernetes.Pod) common.MapStr { - annotations := common.MapStr{} - for k, v := range pod.GetObjectMeta().GetAnnotations() { - safemapstr.Put(annotations, k, v) - } - return annotations -} - -// podNamespaceAnnotations returns the annotations of the namespace of the pod -func podNamespaceAnnotations(pod *kubernetes.Pod, watcher kubernetes.Watcher) common.MapStr { - if watcher == nil { - return nil - } - - rawNs, ok, err := watcher.Store().GetByKey(pod.Namespace) - if !ok || err != nil { - return nil - } - - namespace, ok := rawNs.(*kubernetes.Namespace) - if !ok { - return nil - } - - annotations := common.MapStr{} - for k, v := range namespace.GetAnnotations() { - safemapstr.Put(annotations, k, v) - } - return annotations -} - -// podTerminating returns true if a pod is marked for deletion or is in a phase beyond running. -func podTerminating(pod *kubernetes.Pod) bool { - if pod.GetObjectMeta().GetDeletionTimestamp() != nil { - return true - } - - switch pod.Status.Phase { - case kubernetes.PodRunning, kubernetes.PodPending: - default: - return true - } - - return false -} - -// podTerminated returns true if a pod is terminated, this method considers a -// pod as terminated if none of its containers are running (or going to be running). -func podTerminated(pod *kubernetes.Pod, containers []*containerInPod) bool { - // Pod is not marked for termination, so it is not terminated. - if !podTerminating(pod) { - return false - } - - // If any container is running, the pod is not terminated yet. - for _, container := range containers { - if container.status.State.Running != nil { - return false - } - } - - return true -} - // publishAll publishes all events in the event list in the same order. If delay is true // publishAll schedules the publication of the events after the configured `CleanupPeriod` // and returns inmediatelly. @@ -540,60 +438,3 @@ func (p *pod) publishAll(eventList [][]bus.Event, delay bool) { p.publishFunc(events) } } - -// podUpdaterHandlerFunc is a function that handles pod updater notifications. -type podUpdaterHandlerFunc func(interface{}) - -// podUpdaterStore is the interface that an object needs to implement to be -// used as a pod updater store. -type podUpdaterStore interface { - List() []interface{} -} - -// namespacePodUpdater notifies updates on pods when their namespaces are updated. -type namespacePodUpdater struct { - handler podUpdaterHandlerFunc - store podUpdaterStore - locker sync.Locker -} - -// newNamespacePodUpdater creates a namespacePodUpdater -func newNamespacePodUpdater(handler podUpdaterHandlerFunc, store podUpdaterStore, locker sync.Locker) *namespacePodUpdater { - return &namespacePodUpdater{ - handler: handler, - store: store, - locker: locker, - } -} - -// OnUpdate handles update events on namespaces. -func (n *namespacePodUpdater) OnUpdate(obj interface{}) { - ns, ok := obj.(*kubernetes.Namespace) - if !ok { - return - } - - // n.store.List() returns a snapshot at this point. If a delete is received - // from the main watcher, this loop may generate an update event after the - // delete is processed, leaving configurations that would never be deleted. - // Also this loop can miss updates, what could leave outdated configurations. - // Avoid these issues by locking the processing of events from the main watcher. - if n.locker != nil { - n.locker.Lock() - defer n.locker.Unlock() - } - for _, pod := range n.store.List() { - pod, ok := pod.(*kubernetes.Pod) - if ok && pod.Namespace == ns.Name { - n.handler(pod) - } - } -} - -// OnAdd handles add events on namespaces. Nothing to do, if pods are added to this -// namespace they will generate their own add events. -func (*namespacePodUpdater) OnAdd(interface{}) {} - -// OnDelete handles delete events on namespaces. Nothing to do, if pods are deleted from this -// namespace they will generate their own delete events. -func (*namespacePodUpdater) OnDelete(interface{}) {} diff --git a/libbeat/autodiscover/providers/kubernetes/pod_test.go b/libbeat/autodiscover/providers/kubernetes/pod_test.go index 5388eeb4e6dc..adf98a7cdade 100644 --- a/libbeat/autodiscover/providers/kubernetes/pod_test.go +++ b/libbeat/autodiscover/providers/kubernetes/pod_test.go @@ -1900,6 +1900,7 @@ func TestPod_EmitEvent(t *testing.T) { } client := k8sfake.NewSimpleClientset() + addResourceMetadata := metadata.GetDefaultResourceMetadataConfig() for _, test := range tests { t.Run(test.Message, func(t *testing.T) { mapper, err := template.NewConfigMapper(nil, nil, nil) @@ -1907,7 +1908,7 @@ func TestPod_EmitEvent(t *testing.T) { t.Fatal(err) } - metaGen := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, client, nil, nil, nil) + metaGen := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, client, nil, nil, addResourceMetadata) p := &Provider{ config: defaultConfig(), bus: bus.New(logp.NewLogger("bus"), "test"), @@ -1986,7 +1987,7 @@ func TestNamespacePodUpdater(t *testing.T) { t.Run(title, func(t *testing.T) { handler := &mockUpdaterHandler{} store := &mockUpdaterStore{objects: c.pods} - updater := newNamespacePodUpdater(handler.OnUpdate, store, &sync.Mutex{}) + updater := kubernetes.NewNamespacePodUpdater(handler.OnUpdate, store, &sync.Mutex{}) namespace := &kubernetes.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -2000,6 +2001,58 @@ func TestNamespacePodUpdater(t *testing.T) { } } +func TestNodePodUpdater(t *testing.T) { + pod := func(name, node string) *kubernetes.Pod { + return &kubernetes.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1.PodSpec{ + NodeName: node, + }, + } + } + + cases := map[string]struct { + pods []interface{} + expected []interface{} + }{ + "no pods": {}, + "two pods but only one in node": { + pods: []interface{}{ + pod("onepod", "foo"), + pod("onepod", "bar"), + }, + expected: []interface{}{ + pod("onepod", "foo"), + }, + }, + "two pods but none in node": { + pods: []interface{}{ + pod("onepod", "bar"), + pod("otherpod", "bar"), + }, + }, + } + + for title, c := range cases { + t.Run(title, func(t *testing.T) { + handler := &mockUpdaterHandler{} + store := &mockUpdaterStore{objects: c.pods} + updater := kubernetes.NewNodePodUpdater(handler.OnUpdate, store, &sync.Mutex{}) + + node := &kubernetes.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + } + updater.OnUpdate(node) + + assert.EqualValues(t, c.expected, handler.objects) + }) + } +} + type mockUpdaterHandler struct { objects []interface{} } diff --git a/libbeat/common/kubernetes/eventhandler.go b/libbeat/common/kubernetes/eventhandler.go index eebe33d4d764..b499b409fe32 100644 --- a/libbeat/common/kubernetes/eventhandler.go +++ b/libbeat/common/kubernetes/eventhandler.go @@ -17,6 +17,10 @@ package kubernetes +import ( + "sync" +) + // ResourceEventHandler can handle notifications for events that happen to a // resource. The events are informational only, so you can't return an // error. @@ -120,3 +124,108 @@ func (r FilteringResourceEventHandler) OnDelete(obj interface{}) { } r.Handler.OnDelete(obj) } + +// podUpdaterHandlerFunc is a function that handles pod updater notifications. +type podUpdaterHandlerFunc func(interface{}) + +// podUpdaterStore is the interface that an object needs to implement to be +// used as a pod updater store. +type podUpdaterStore interface { + List() []interface{} +} + +// namespacePodUpdater notifies updates on pods when their namespaces are updated. +type namespacePodUpdater struct { + handler podUpdaterHandlerFunc + store podUpdaterStore + locker sync.Locker +} + +// NewNamespacePodUpdater creates a namespacePodUpdater +func NewNamespacePodUpdater(handler podUpdaterHandlerFunc, store podUpdaterStore, locker sync.Locker) *namespacePodUpdater { + return &namespacePodUpdater{ + handler: handler, + store: store, + locker: locker, + } +} + +// OnUpdate handles update events on namespaces. +func (n *namespacePodUpdater) OnUpdate(obj interface{}) { + ns, ok := obj.(*Namespace) + if !ok { + return + } + + // n.store.List() returns a snapshot at this point. If a delete is received + // from the main watcher, this loop may generate an update event after the + // delete is processed, leaving configurations that would never be deleted. + // Also this loop can miss updates, what could leave outdated configurations. + // Avoid these issues by locking the processing of events from the main watcher. + if n.locker != nil { + n.locker.Lock() + defer n.locker.Unlock() + } + for _, pod := range n.store.List() { + pod, ok := pod.(*Pod) + if ok && pod.Namespace == ns.Name { + n.handler(pod) + } + } +} + +// OnAdd handles add events on namespaces. Nothing to do, if pods are added to this +// namespace they will generate their own add events. +func (*namespacePodUpdater) OnAdd(interface{}) {} + +// OnDelete handles delete events on namespaces. Nothing to do, if pods are deleted from this +// namespace they will generate their own delete events. +func (*namespacePodUpdater) OnDelete(interface{}) {} + +// nodePodUpdater notifies updates on pods when their nodes are updated. +type nodePodUpdater struct { + handler podUpdaterHandlerFunc + store podUpdaterStore + locker sync.Locker +} + +// NewNodePodUpdater creates a nodePodUpdater +func NewNodePodUpdater(handler podUpdaterHandlerFunc, store podUpdaterStore, locker sync.Locker) *nodePodUpdater { + return &nodePodUpdater{ + handler: handler, + store: store, + locker: locker, + } +} + +// OnUpdate handles update events on nodes. +func (n *nodePodUpdater) OnUpdate(obj interface{}) { + node, ok := obj.(*Node) + if !ok { + return + } + + // n.store.List() returns a snapshot at this point. If a delete is received + // from the main watcher, this loop may generate an update event after the + // delete is processed, leaving configurations that would never be deleted. + // Also this loop can miss updates, what could leave outdated configurations. + // Avoid these issues by locking the processing of events from the main watcher. + if n.locker != nil { + n.locker.Lock() + defer n.locker.Unlock() + } + for _, pod := range n.store.List() { + pod, ok := pod.(*Pod) + if ok && pod.Spec.NodeName == node.Name { + n.handler(pod) + } + } +} + +// OnAdd handles add events on namespaces. Nothing to do, if pods are added to this +// namespace they will generate their own add events. +func (*nodePodUpdater) OnAdd(interface{}) {} + +// OnDelete handles delete events on namespaces. Nothing to do, if pods are deleted from this +// namespace they will generate their own delete events. +func (*nodePodUpdater) OnDelete(interface{}) {} diff --git a/libbeat/common/kubernetes/metadata/pod.go b/libbeat/common/kubernetes/metadata/pod.go index ec6328aee968..174b3667419e 100644 --- a/libbeat/common/kubernetes/metadata/pod.go +++ b/libbeat/common/kubernetes/metadata/pod.go @@ -46,10 +46,6 @@ func NewPodMetadataGenerator( namespace MetaGen, addResourceMetadata *AddResourceMetadataConfig) MetaGen { - if addResourceMetadata == nil { - addResourceMetadata = GetDefaultResourceMetadataConfig() - } - return &pod{ resource: NewResourceMetadataGenerator(cfg, client), store: pods, diff --git a/libbeat/common/kubernetes/metadata/pod_test.go b/libbeat/common/kubernetes/metadata/pod_test.go index a780d3d2daf4..2ce0ad19877b 100644 --- a/libbeat/common/kubernetes/metadata/pod_test.go +++ b/libbeat/common/kubernetes/metadata/pod_test.go @@ -36,6 +36,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common/kubernetes" ) +var addResourceMetadata = GetDefaultResourceMetadataConfig() + func TestPod_Generate(t *testing.T) { client := k8sfake.NewSimpleClientset() uid := "005f3b90-4b9d-12f8-acf0-31020a840133" @@ -374,7 +376,7 @@ func TestPod_Generate(t *testing.T) { }) assert.NoError(t, err) - metagen := NewPodMetadataGenerator(config, nil, client, nil, nil, nil) + metagen := NewPodMetadataGenerator(config, nil, client, nil, nil, addResourceMetadata) for _, test := range tests { t.Run(test.name, func(t *testing.T) { assert.Equal(t, test.output, metagen.Generate(test.input)) @@ -496,7 +498,7 @@ func TestPod_GenerateFromName(t *testing.T) { assert.NoError(t, err) pods := cache.NewStore(cache.MetaNamespaceKeyFunc) pods.Add(test.input) - metagen := NewPodMetadataGenerator(config, pods, client, nil, nil, nil) + metagen := NewPodMetadataGenerator(config, pods, client, nil, nil, addResourceMetadata) accessor, err := meta.Accessor(test.input) require.NoError(t, err) @@ -618,7 +620,7 @@ func TestPod_GenerateWithNodeNamespace(t *testing.T) { namespaces.Add(test.namespace) nsMeta := NewNamespaceMetadataGenerator(config, namespaces, client) - metagen := NewPodMetadataGenerator(config, pods, client, nodeMeta, nsMeta, nil) + metagen := NewPodMetadataGenerator(config, pods, client, nodeMeta, nsMeta, addResourceMetadata) t.Run(test.name, func(t *testing.T) { assert.Equal(t, test.output, metagen.Generate(test.input)) }) diff --git a/libbeat/common/kubernetes/util.go b/libbeat/common/kubernetes/util.go index 3314a0dd9f0a..b27f32a041f6 100644 --- a/libbeat/common/kubernetes/util.go +++ b/libbeat/common/kubernetes/util.go @@ -24,6 +24,9 @@ import ( "os" "strings" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/safemapstr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" @@ -192,7 +195,7 @@ func discoverByMachineId(nd *DiscoverKubernetesNodeParams, ctx context.Context) return } -// GetMachineID returns the machine-id +// GetMachineID returns the machine-idadd_kubernetes_metadata/indexers_test.go // borrowed from machineID of cadvisor. func (hd *DefaultDiscoveryUtils) GetMachineID() string { for _, file := range []string{ @@ -226,3 +229,109 @@ func InClusterNamespace() (string, error) { } return strings.TrimSpace(string(data)), nil } + +type ContainerInPod struct { + ID string + Runtime string + Spec Container + Status PodContainerStatus +} + +// GetContainersInPod returns all the containers defined in a pod and their statuses. +// It includes init and ephemeral containers. +func GetContainersInPod(pod *Pod) []*ContainerInPod { + var containers []*ContainerInPod + for _, c := range pod.Spec.Containers { + containers = append(containers, &ContainerInPod{Spec: c}) + } + for _, c := range pod.Spec.InitContainers { + containers = append(containers, &ContainerInPod{Spec: c}) + } + for _, c := range pod.Spec.EphemeralContainers { + c := Container(c.EphemeralContainerCommon) + containers = append(containers, &ContainerInPod{Spec: c}) + } + + statuses := make(map[string]*PodContainerStatus) + mapStatuses := func(s []PodContainerStatus) { + for i := range s { + statuses[s[i].Name] = &s[i] + } + } + mapStatuses(pod.Status.ContainerStatuses) + mapStatuses(pod.Status.InitContainerStatuses) + mapStatuses(pod.Status.EphemeralContainerStatuses) + for _, c := range containers { + if s, ok := statuses[c.Spec.Name]; ok { + c.ID, c.Runtime = ContainerIDWithRuntime(*s) + c.Status = *s + } + } + + return containers +} + +// PodAnnotations returns the annotations in a pod +func PodAnnotations(pod *Pod) common.MapStr { + annotations := common.MapStr{} + for k, v := range pod.GetObjectMeta().GetAnnotations() { + safemapstr.Put(annotations, k, v) + } + return annotations +} + +// PodNamespaceAnnotations returns the annotations of the namespace of the pod +func PodNamespaceAnnotations(pod *Pod, watcher Watcher) common.MapStr { + if watcher == nil { + return nil + } + + rawNs, ok, err := watcher.Store().GetByKey(pod.Namespace) + if !ok || err != nil { + return nil + } + + namespace, ok := rawNs.(*Namespace) + if !ok { + return nil + } + + annotations := common.MapStr{} + for k, v := range namespace.GetAnnotations() { + safemapstr.Put(annotations, k, v) + } + return annotations +} + +// PodTerminating returns true if a pod is marked for deletion or is in a phase beyond running. +func PodTerminating(pod *Pod) bool { + if pod.GetObjectMeta().GetDeletionTimestamp() != nil { + return true + } + + switch pod.Status.Phase { + case PodRunning, PodPending: + default: + return true + } + + return false +} + +// PodTerminated returns true if a pod is terminated, this method considers a +// pod as terminated if none of its containers are running (or going to be running). +func PodTerminated(pod *Pod, containers []*ContainerInPod) bool { + // Pod is not marked for termination, so it is not terminated. + if !PodTerminating(pod) { + return false + } + + // If any container is running, the pod is not terminated yet. + for _, container := range containers { + if container.Status.State.Running != nil { + return false + } + } + + return true +} diff --git a/libbeat/common/kubernetes/util_test.go b/libbeat/common/kubernetes/util_test.go index 44fc9a046604..2a2ed77b6822 100644 --- a/libbeat/common/kubernetes/util_test.go +++ b/libbeat/common/kubernetes/util_test.go @@ -73,7 +73,7 @@ func TestDiscoverKubernetesNode(t *testing.T) { namespace: "", }, { - name: "test value with not incluster, machine id not retrieved, env var not set", + name: "test value with not incluster, machine ID not retrieved, env var not set", host: "", node: "", err: ge, @@ -130,7 +130,7 @@ func TestDiscoverKubernetesNode(t *testing.T) { init: createResources, }, { - name: "test value without inCluster, machine-id empty and env var not set", + name: "test value without inCluster, machine-ID empty and env var not set", host: "", isInCluster: false, node: "", @@ -141,7 +141,7 @@ func TestDiscoverKubernetesNode(t *testing.T) { namespace: "", }, { - name: "test value without inCluster, machine-id set, node not found and env var not set", + name: "test value without inCluster, machine-ID set, node not found and env var not set", host: "", isInCluster: false, node: "", @@ -152,7 +152,7 @@ func TestDiscoverKubernetesNode(t *testing.T) { namespace: "", }, { - name: "test value without inCluster, machine-id set, node found and env var not set", + name: "test value without inCluster, machine-ID set, node found and env var not set", host: "", isInCluster: false, node: "worker-2", @@ -164,7 +164,7 @@ func TestDiscoverKubernetesNode(t *testing.T) { init: createResources, }, { - name: "test value without inCluster, machine-id set, node not found and env var set", + name: "test value without inCluster, machine-ID set, node not found and env var set", host: "", isInCluster: false, node: "worker-2", diff --git a/libbeat/processors/add_kubernetes_metadata/indexers_test.go b/libbeat/processors/add_kubernetes_metadata/indexers_test.go index 51ba288974c6..9897a6534de9 100644 --- a/libbeat/processors/add_kubernetes_metadata/indexers_test.go +++ b/libbeat/processors/add_kubernetes_metadata/indexers_test.go @@ -32,7 +32,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common/kubernetes" ) -var metagen = metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, nil) +var addResourceMetadata = metadata.GetDefaultResourceMetadataConfig() +var metagen = metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, addResourceMetadata) func TestPodIndexer(t *testing.T) { var testConfig = common.NewConfig() @@ -90,7 +91,7 @@ func TestPodIndexer(t *testing.T) { func TestPodUIDIndexer(t *testing.T) { var testConfig = common.NewConfig() - metaGenWithPodUID := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, nil) + metaGenWithPodUID := metadata.NewPodMetadataGenerator(common.NewConfig(), nil, nil, nil, nil, addResourceMetadata) podUIDIndexer, err := NewPodUIDIndexer(*testConfig, metaGenWithPodUID) assert.NoError(t, err) @@ -301,7 +302,7 @@ func TestFilteredGenMeta(t *testing.T) { }) assert.NoError(t, err) - filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, nil) + filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, addResourceMetadata) podIndexer, err = NewPodNameIndexer(*testConfig, filteredGen) assert.NoError(t, err) @@ -338,7 +339,7 @@ func TestFilteredGenMetaExclusion(t *testing.T) { }) assert.NoError(t, err) - filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, nil) + filteredGen := metadata.NewPodMetadataGenerator(config, nil, nil, nil, nil, addResourceMetadata) podIndexer, err := NewPodNameIndexer(*testConfig, filteredGen) assert.NoError(t, err) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 759fe4078537..385f87aa19d4 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -150,3 +150,4 @@ - Add diagnostics collect command to gather beat metadata, config, policy, and logs and bundle it into an archive. {pull}28461[28461] - Add `KIBANA_FLEET_SERVICE_TOKEN` to Elastic Agent container. {pull}28096[28096] - Allow pprof endpoints for elastic-agent or beats if enabled. {pull}28983[28983] {pull}29155[29155] +- Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go index bb9ec52887fe..94630a10913c 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go @@ -44,29 +44,6 @@ type providerData struct { processors []map[string]interface{} } -type containerInPod struct { - id string - runtime string - spec kubernetes.Container - status kubernetes.PodContainerStatus -} - -// podUpdaterHandlerFunc is a function that handles pod updater notifications. -type podUpdaterHandlerFunc func(interface{}) - -// podUpdaterStore is the interface that an object needs to implement to be -// used as a pod updater store. -type podUpdaterStore interface { - List() []interface{} -} - -// namespacePodUpdater notifies updates on pods when their namespaces are updated. -type namespacePodUpdater struct { - handler podUpdaterHandlerFunc - store podUpdaterStore - locker sync.Locker -} - // NewPodEventer creates an eventer that can discover and process pod objects func NewPodEventer( comm composable.DynamicProviderComm, @@ -121,8 +98,13 @@ func NewPodEventer( watcher.AddEventHandler(p) + if nodeWatcher != nil && metaConf.Node.Enabled() { + updater := kubernetes.NewNodePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) + nodeWatcher.AddEventHandler(updater) + } + if namespaceWatcher != nil && metaConf.Namespace.Enabled() { - updater := newNamespacePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) + updater := kubernetes.NewNamespacePodUpdater(p.unlockedUpdate, watcher.Store(), &p.crossUpdate) namespaceWatcher.AddEventHandler(updater) } @@ -162,7 +144,7 @@ func (p *pod) Stop() { func (p *pod) emitRunning(pod *kubernetes.Pod) { - namespaceAnnotations := podNamespaceAnnotations(pod, p.namespaceWatcher) + namespaceAnnotations := kubernetes.PodNamespaceAnnotations(pod, p.namespaceWatcher) data := generatePodData(pod, p.config, p.metagen, namespaceAnnotations) data.mapping["scope"] = p.scope @@ -286,7 +268,7 @@ func generateContainerData( kubeMetaGen metadata.MetaGen, namespaceAnnotations common.MapStr) { - containers := getContainersInPod(pod) + containers := kubernetes.GetContainersInPod(pod) // Pass annotations to all events so that it can be used in templating and by annotation builders. annotations := common.MapStr{} @@ -298,14 +280,14 @@ func generateContainerData( // If it doesn't have an ID, container doesn't exist in // the runtime, emit only an event if we are stopping, so // we are sure of cleaning up configurations. - if c.id == "" { + if c.ID == "" { continue } // ID is the combination of pod UID + container name - eventID := fmt.Sprintf("%s.%s", pod.GetObjectMeta().GetUID(), c.spec.Name) + eventID := fmt.Sprintf("%s.%s", pod.GetObjectMeta().GetUID(), c.Spec.Name) - meta := kubeMetaGen.Generate(pod, metadata.WithFields("container.name", c.spec.Name)) + meta := kubeMetaGen.Generate(pod, metadata.WithFields("container.name", c.Spec.Name)) kubemetaMap, err := meta.GetValue("kubernetes") if err != nil { continue @@ -323,10 +305,10 @@ func generateContainerData( //container ECS fields cmeta := common.MapStr{ - "id": c.id, - "runtime": c.runtime, + "id": c.ID, + "runtime": c.Runtime, "image": common.MapStr{ - "name": c.spec.Image, + "name": c.Spec.Image, }, } @@ -353,13 +335,13 @@ func generateContainerData( // add container metadata under kubernetes.container.* to // make them available to dynamic var resolution containerMeta := common.MapStr{ - "id": c.id, - "name": c.spec.Name, - "image": c.spec.Image, - "runtime": c.runtime, + "id": c.ID, + "name": c.Spec.Name, + "image": c.Spec.Image, + "runtime": c.Runtime, } - if len(c.spec.Ports) > 0 { - for _, port := range c.spec.Ports { + if len(c.Spec.Ports) > 0 { + for _, port := range c.Spec.Ports { containerMeta.Put("port", fmt.Sprintf("%v", port.ContainerPort)) containerMeta.Put("port_name", port.Name) k8sMapping["container"] = containerMeta @@ -371,101 +353,3 @@ func generateContainerData( } } } - -// podNamespaceAnnotations returns the annotations of the namespace of the pod -func podNamespaceAnnotations(pod *kubernetes.Pod, watcher kubernetes.Watcher) common.MapStr { - if watcher == nil { - return nil - } - - rawNs, ok, err := watcher.Store().GetByKey(pod.Namespace) - if !ok || err != nil { - return nil - } - - namespace, ok := rawNs.(*kubernetes.Namespace) - if !ok { - return nil - } - - annotations := common.MapStr{} - for k, v := range namespace.GetAnnotations() { - safemapstr.Put(annotations, k, v) - } - return annotations -} - -// newNamespacePodUpdater creates a namespacePodUpdater -func newNamespacePodUpdater(handler podUpdaterHandlerFunc, store podUpdaterStore, locker sync.Locker) *namespacePodUpdater { - return &namespacePodUpdater{ - handler: handler, - store: store, - locker: locker, - } -} - -// OnUpdate handles update events on namespaces. -func (n *namespacePodUpdater) OnUpdate(obj interface{}) { - ns, ok := obj.(*kubernetes.Namespace) - if !ok { - return - } - - // n.store.List() returns a snapshot at this point. If a delete is received - // from the main watcher, this loop may generate an update event after the - // delete is processed, leaving configurations that would never be deleted. - // Also this loop can miss updates, what could leave outdated configurations. - // Avoid these issues by locking the processing of events from the main watcher. - if n.locker != nil { - n.locker.Lock() - defer n.locker.Unlock() - } - for _, pod := range n.store.List() { - pod, ok := pod.(*kubernetes.Pod) - if ok && pod.Namespace == ns.Name { - n.handler(pod) - } - } -} - -// OnAdd handles add events on namespaces. Nothing to do, if pods are added to this -// namespace they will generate their own add events. -func (*namespacePodUpdater) OnAdd(interface{}) {} - -// OnDelete handles delete events on namespaces. Nothing to do, if pods are deleted from this -// namespace they will generate their own delete events. -func (*namespacePodUpdater) OnDelete(interface{}) {} - -// getContainersInPod returns all the containers defined in a pod and their statuses. -// It includes init and ephemeral containers. -func getContainersInPod(pod *kubernetes.Pod) []*containerInPod { - var containers []*containerInPod - for _, c := range pod.Spec.Containers { - containers = append(containers, &containerInPod{spec: c}) - } - for _, c := range pod.Spec.InitContainers { - containers = append(containers, &containerInPod{spec: c}) - } - for _, c := range pod.Spec.EphemeralContainers { - c := kubernetes.Container(c.EphemeralContainerCommon) - containers = append(containers, &containerInPod{spec: c}) - } - - statuses := make(map[string]*kubernetes.PodContainerStatus) - mapStatuses := func(s []kubernetes.PodContainerStatus) { - for i := range s { - statuses[s[i].Name] = &s[i] - } - } - mapStatuses(pod.Status.ContainerStatuses) - mapStatuses(pod.Status.InitContainerStatuses) - mapStatuses(pod.Status.EphemeralContainerStatuses) - for _, c := range containers { - if s, ok := statuses[c.spec.Name]; ok { - c.id, c.runtime = kubernetes.ContainerIDWithRuntime(*s) - c.status = *s - } - } - - return containers -} From 70ac1b054be58aa3c3c9057d78d72fe8c6a623ae Mon Sep 17 00:00:00 2001 From: Mariana Dima Date: Thu, 9 Dec 2021 17:08:53 +0100 Subject: [PATCH 070/172] Agent configuration overridden by default fleet config (#29297) * replace config * changelog * add test on merge * fmt --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../pkg/agent/application/application.go | 4 +-- .../pkg/agent/application/application_test.go | 33 +++++++++++++++++++ x-pack/elastic-agent/pkg/agent/cmd/run.go | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 385f87aa19d4..b75a405d4bba 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -91,6 +91,7 @@ - Snapshot artifact lookup will use agent.download proxy settings. {issue}27903[27903] {pull}27904[27904] - Fix lazy acker to only add new actions to the batch. {pull}27981[27981] - Allow HTTP metrics to run in bootstrap mode. Add ability to adjust timeouts for Fleet Server. {pull}28260[28260] +- Fix agent configuration overwritten by default fleet config. {pull}29297[29297] ==== New features diff --git a/x-pack/elastic-agent/pkg/agent/application/application.go b/x-pack/elastic-agent/pkg/agent/application/application.go index e2f7a55ce3ef..d0de160340de 100644 --- a/x-pack/elastic-agent/pkg/agent/application/application.go +++ b/x-pack/elastic-agent/pkg/agent/application/application.go @@ -39,10 +39,11 @@ type upgraderControl interface { } // New creates a new Agent and bootstrap the required subsystem. -func New(log *logger.Logger, pathConfigFile string, reexec reexecManager, statusCtrl status.Controller, uc upgraderControl, agentInfo *info.AgentInfo) (Application, error) { +func New(log *logger.Logger, reexec reexecManager, statusCtrl status.Controller, uc upgraderControl, agentInfo *info.AgentInfo) (Application, error) { // Load configuration from disk to understand in which mode of operation // we must start the elastic-agent, the mode of operation cannot be changed without restarting the // elastic-agent. + pathConfigFile := paths.ConfigFile() rawConfig, err := config.LoadFile(pathConfigFile) if err != nil { return nil, err @@ -66,7 +67,6 @@ func createApplication( ) (Application, error) { log.Info("Detecting execution mode") ctx := context.Background() - cfg, err := configuration.NewFromConfig(rawConfig) if err != nil { return nil, err diff --git a/x-pack/elastic-agent/pkg/agent/application/application_test.go b/x-pack/elastic-agent/pkg/agent/application/application_test.go index 7c1975fef642..7ae0032d4833 100644 --- a/x-pack/elastic-agent/pkg/agent/application/application_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/application_test.go @@ -3,3 +3,36 @@ // you may not use this file except in compliance with the Elastic License. package application + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" +) + +func TestMergeFleetConfig(t *testing.T) { + cfg := map[string]interface{}{ + "fleet": map[string]interface{}{ + "enabled": true, + "kibana": map[string]interface{}{"host": "demo"}, + "access_api_key": "123", + }, + "agent": map[string]interface{}{ + "grpc": map[string]interface{}{ + "port": uint16(6790), + }, + }, + } + + rawConfig := config.MustNewConfigFrom(cfg) + storage, conf, err := mergeFleetConfig(rawConfig) + require.NoError(t, err) + assert.NotNil(t, storage) + assert.NotNil(t, conf) + assert.Equal(t, conf.Fleet.Enabled, cfg["fleet"].(map[string]interface{})["enabled"]) + assert.Equal(t, conf.Fleet.AccessAPIKey, cfg["fleet"].(map[string]interface{})["access_api_key"]) + assert.Equal(t, conf.Settings.GRPC.Port, cfg["agent"].(map[string]interface{})["grpc"].(map[string]interface{})["port"].(uint16)) +} diff --git a/x-pack/elastic-agent/pkg/agent/cmd/run.go b/x-pack/elastic-agent/pkg/agent/cmd/run.go index 1c8c1dd4916f..ba37febd674f 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/run.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/run.go @@ -142,7 +142,7 @@ func run(streams *cli.IOStreams, override cfgOverrider) error { } defer control.Stop() - app, err := application.New(logger, pathConfigFile, rex, statusCtrl, control, agentInfo) + app, err := application.New(logger, rex, statusCtrl, control, agentInfo) if err != nil { return err } From da8bc7cc57f670cf3c1153f1d96b75e6bb3206ac Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Thu, 9 Dec 2021 10:28:45 -0800 Subject: [PATCH 071/172] Remote global hostfs variables (#29138) * first pass at fixing hostfs * forgot to commit a bunch of stuff, oops * fix system/linux tests * fix tests * fix other tests * fix diskio tests * take another pass at fixing diskio tests * revert to non-breaking change * fix docs * fix metricbeat legacy config logic, fix a few tests * fix import * fix libraries, docs * fix processors * few code changes --- libbeat/cmd/instance/beat.go | 12 +- libbeat/cmd/instance/metrics/metrics.go | 4 +- libbeat/cmd/root.go | 1 - libbeat/docs/command-reference.asciidoc | 3 +- libbeat/docs/shared-path-config.asciidoc | 7 +- libbeat/metric/system/cgroup/reader.go | 19 +- libbeat/metric/system/cgroup/reader_test.go | 10 +- libbeat/metric/system/cgroup/util.go | 31 ++- libbeat/metric/system/cgroup/util_test.go | 12 +- libbeat/metric/system/numcpu/cpu_linux.go | 10 +- libbeat/metric/system/process/process.go | 1 + libbeat/metric/system/resolve/resolve.go | 56 ++++++ libbeat/paths/paths.go | 39 +--- .../add_docker_metadata.go | 13 +- .../add_docker_metadata_test.go | 3 +- .../processors/add_docker_metadata/config.go | 2 +- .../add_process_metadata.go | 5 +- .../add_process_metadata_test.go | 9 +- .../gosigar_cid_provider.go | 7 +- metricbeat/docs/modules/system.asciidoc | 2 +- metricbeat/docs/running-on-docker.asciidoc | 6 +- metricbeat/internal/metrics/cpu/metrics.go | 5 +- .../internal/metrics/cpu/metrics_aix.go | 3 +- .../internal/metrics/cpu/metrics_darwin.go | 3 +- .../internal/metrics/cpu/metrics_openbsd.go | 3 +- .../metrics/cpu/metrics_procfs_common.go | 8 +- .../internal/metrics/cpu/metrics_test.go | 7 +- .../internal/metrics/cpu/metrics_windows.go | 3 +- metricbeat/internal/metrics/memory/memory.go | 3 +- .../internal/metrics/memory/memory_aix.go | 3 +- .../internal/metrics/memory/memory_darwin.go | 3 +- .../internal/metrics/memory/memory_freebsd.go | 3 +- .../internal/metrics/memory/memory_helpers.go | 7 +- .../internal/metrics/memory/memory_linux.go | 3 +- .../internal/metrics/memory/memory_openbsd.go | 3 +- .../internal/metrics/memory/memory_test.go | 9 +- .../internal/metrics/memory/memory_windows.go | 3 +- metricbeat/internal/sysinit/init.go | 112 +++++++++++ metricbeat/internal/sysinit/module.go | 42 ++++ .../sysinit}/system_linux.go | 8 +- .../sysinit}/system_other.go | 4 +- .../sysinit}/system_windows.go | 4 +- metricbeat/metricbeat.reference.yml | 2 +- .../module/linux/conntrack/conntrack.go | 23 +-- .../module/linux/conntrack/conntrack_test.go | 1 + metricbeat/module/linux/iostat/iostat.go | 1 - metricbeat/module/linux/iostat/iostat_test.go | 1 + metricbeat/module/linux/ksm/ksm.go | 13 +- metricbeat/module/linux/ksm/ksm_test.go | 1 + metricbeat/module/linux/linux.go | 47 +---- metricbeat/module/linux/memory/data.go | 9 +- metricbeat/module/linux/memory/memory.go | 7 +- .../module/linux/memory/memory_linux_test.go | 1 + metricbeat/module/linux/pageinfo/pageinfo.go | 12 +- .../module/linux/pageinfo/pageinfo_test.go | 1 + metricbeat/module/linux/pressure/pressure.go | 25 +-- .../module/linux/pressure/pressure_test.go | 1 + metricbeat/module/linux/rapl/rapl.go | 19 +- metricbeat/module/linux/rapl/rapl_test.go | 5 +- .../module/system/_meta/config.reference.yml | 2 +- metricbeat/module/system/_meta/config.yml | 2 +- metricbeat/module/system/core/core.go | 6 +- metricbeat/module/system/core/core_test.go | 1 + metricbeat/module/system/cpu/cpu.go | 6 +- metricbeat/module/system/cpu/cpu_test.go | 1 + .../module/system/diskio/diskio_test.go | 35 +--- metricbeat/module/system/entropy/entropy.go | 15 +- .../module/system/entropy/entropy_test.go | 17 +- .../module/system/filesystem/filesystem.go | 5 +- .../system/filesystem/filesystem_test.go | 4 +- metricbeat/module/system/filesystem/helper.go | 6 +- metricbeat/module/system/fsstat/fsstat.go | 5 +- .../module/system/fsstat/fsstat_test.go | 1 + metricbeat/module/system/load/load_test.go | 1 + metricbeat/module/system/memory/memory.go | 8 +- .../module/system/memory/memory_test.go | 1 + .../module/system/network/network_test.go | 1 + .../network_summary/network_summary_test.go | 1 + .../module/system/process/_meta/data.json | 180 +++++++----------- .../module/system/process/_meta/docs.asciidoc | 2 +- metricbeat/module/system/process/process.go | 10 +- .../module/system/process/process_test.go | 1 + .../process_summary/process_summary_test.go | 1 + .../module/system/raid/_meta/docs.asciidoc | 1 - .../module/system/raid/blockinfo/getdev.go | 2 +- metricbeat/module/system/raid/raid.go | 36 +--- metricbeat/module/system/raid/raid_test.go | 7 +- .../module/system/service/service_test.go | 1 + metricbeat/module/system/socket/socket.go | 5 +- .../module/system/socket/socket_test.go | 1 + .../system/socket_summary/socket_summary.go | 6 +- .../system/socket_summary/sockstat_linux.go | 6 +- .../system/socket_summary/sockstat_other.go | 3 +- metricbeat/module/system/system.go | 56 +----- .../module/system/uptime/uptime_test.go | 1 + metricbeat/modules.d/system.yml | 2 +- x-pack/metricbeat/metricbeat.reference.yml | 2 +- 97 files changed, 545 insertions(+), 556 deletions(-) create mode 100644 libbeat/metric/system/resolve/resolve.go create mode 100644 metricbeat/internal/sysinit/init.go create mode 100644 metricbeat/internal/sysinit/module.go rename metricbeat/{module/system => internal/sysinit}/system_linux.go (93%) rename metricbeat/{module/system => internal/sysinit}/system_other.go (94%) rename metricbeat/{module/system => internal/sysinit}/system_windows.go (95%) diff --git a/libbeat/cmd/instance/beat.go b/libbeat/cmd/instance/beat.go index 3e1da0f62fb3..eb126966094e 100644 --- a/libbeat/cmd/instance/beat.go +++ b/libbeat/cmd/instance/beat.go @@ -47,7 +47,6 @@ import ( "github.com/elastic/beats/v7/libbeat/cloudid" "github.com/elastic/beats/v7/libbeat/cmd/instance/metrics" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/elastic/beats/v7/libbeat/common/file" "github.com/elastic/beats/v7/libbeat/common/reload" "github.com/elastic/beats/v7/libbeat/common/seccomp" @@ -1130,22 +1129,13 @@ func initPaths(cfg *common.Config) error { // the paths field. After we will unpack the complete configuration and keystore reference // will be correctly replaced. partialConfig := struct { - Path paths.Path `config:"path"` - Hostfs string `config:"system.hostfs"` + Path paths.Path `config:"path"` }{} - if paths.IsCLISet() { - cfgwarn.Deprecate("8.0.0", "This flag will be removed in the future and replaced by a config value.") - } - if err := cfg.Unpack(&partialConfig); err != nil { return fmt.Errorf("error extracting default paths: %+v", err) } - // Read the value for hostfs as `system.hostfs` - // In the config, there is no `path.hostfs`, as we're merely using the path struct to carry the hostfs variable. - partialConfig.Path.Hostfs = partialConfig.Hostfs - if err := paths.InitPaths(&partialConfig.Path); err != nil { return fmt.Errorf("error setting default paths: %+v", err) } diff --git a/libbeat/cmd/instance/metrics/metrics.go b/libbeat/cmd/instance/metrics/metrics.go index 0df87a522f3c..5542e083bee9 100644 --- a/libbeat/cmd/instance/metrics/metrics.go +++ b/libbeat/cmd/instance/metrics/metrics.go @@ -31,8 +31,8 @@ import ( "github.com/elastic/beats/v7/libbeat/metric/system/cpu" "github.com/elastic/beats/v7/libbeat/metric/system/numcpu" "github.com/elastic/beats/v7/libbeat/metric/system/process" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/monitoring" - "github.com/elastic/beats/v7/libbeat/paths" ) var ( @@ -288,7 +288,7 @@ func reportBeatCgroups(_ monitoring.Mode, V monitoring.Visitor) { } cgroups, err := cgroup.NewReaderOptions(cgroup.ReaderOptions{ - RootfsMountpoint: paths.Paths.Hostfs, + RootfsMountpoint: resolve.NewTestResolver("/"), IgnoreRootCgroups: true, CgroupsHierarchyOverride: os.Getenv(libbeatMonitoringCgroupsHierarchyOverride), }) diff --git a/libbeat/cmd/root.go b/libbeat/cmd/root.go index f239cbe0c7e7..be2cb9d441ae 100644 --- a/libbeat/cmd/root.go +++ b/libbeat/cmd/root.go @@ -105,7 +105,6 @@ func GenRootCmdWithSettings(beatCreator beat.Creator, settings instance.Settings rootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.data")) rootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.logs")) rootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.home")) - rootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("system.hostfs")) rootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("strict.perms")) if f := flag.CommandLine.Lookup("plugin"); f != nil { rootCmd.PersistentFlags().AddGoFlag(f) diff --git a/libbeat/docs/command-reference.asciidoc b/libbeat/docs/command-reference.asciidoc index 38cc5937ff0f..d761c7f4b169 100644 --- a/libbeat/docs/command-reference.asciidoc +++ b/libbeat/docs/command-reference.asciidoc @@ -706,7 +706,8 @@ endif::[] *`--system.hostfs MOUNT_POINT`*:: -Specifies the mount point of the host's filesystem for use in monitoring a host. +Specifies the mount point of the host's filesystem for use in monitoring a host. +This flag is depricated, and an alternate hostfs should be specified via the `hostfs` module config value. ifeval::["{beatname_lc}"=="packetbeat"] diff --git a/libbeat/docs/shared-path-config.asciidoc b/libbeat/docs/shared-path-config.asciidoc index 33390ca7faa7..44c4e6d28090 100644 --- a/libbeat/docs/shared-path-config.asciidoc +++ b/libbeat/docs/shared-path-config.asciidoc @@ -107,15 +107,15 @@ Example: path.logs: /var/log/beats ------------------------------------------------------------------------------ +ifeval::["{beatname_lc}"=="metricbeat"] [float] ==== `system.hostfs` Specifies the mount point of the host's filesystem for use in monitoring a host. This can either be set in the config, or with the `--system.hostfs` CLI flag. This is used for cgroup self-monitoring. -ifeval::["{beatname_lc}"=="metricbeat"] -This is also used by the system module to read files from `/proc` and `/sys`. -endif::[] +This is also used by the system module to read files from `/proc` and `/sys`. +This option is deprecated and will be removed in a future release. To set the filesystem root, use the `hostfs` flag inside the module-level config. Example: @@ -123,3 +123,4 @@ Example: ------------------------------------------------------------------------------ system.hostfs: /mount/rootfs ------------------------------------------------------------------------------ +endif::[] \ No newline at end of file diff --git a/libbeat/metric/system/cgroup/reader.go b/libbeat/metric/system/cgroup/reader.go index f8497de1b42e..c8ea95bb371f 100644 --- a/libbeat/metric/system/cgroup/reader.go +++ b/libbeat/metric/system/cgroup/reader.go @@ -21,12 +21,14 @@ import ( "fmt" "io/ioutil" "path/filepath" + "strconv" "strings" "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup/cgv1" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup/cgv2" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) // StatsV1 contains metrics and limits from each of the cgroup subsystems. @@ -71,7 +73,7 @@ type mount struct { type Reader struct { // Mountpoint of the root filesystem. Defaults to / if not set. This can be // useful for example if you mount / as /rootfs inside of a container. - rootfsMountpoint string + rootfsMountpoint resolve.Resolver ignoreRootCgroups bool // Ignore a cgroup when its path is "/". cgroupsHierarchyOverride string cgroupMountpoints Mountpoints // Mountpoints for each subsystem (e.g. cpu, cpuacct, memory, blkio). @@ -81,8 +83,8 @@ type Reader struct { type ReaderOptions struct { // RootfsMountpoint holds the mountpoint of the root filesystem. // - // If unspecified, "/" is assumed. - RootfsMountpoint string + // pass + RootfsMountpoint resolve.Resolver // IgnoreRootCgroups ignores cgroup subsystem with the path "/". IgnoreRootCgroups bool @@ -98,7 +100,7 @@ type ReaderOptions struct { } // NewReader creates and returns a new Reader. -func NewReader(rootfsMountpoint string, ignoreRootCgroups bool) (*Reader, error) { +func NewReader(rootfsMountpoint resolve.Resolver, ignoreRootCgroups bool) (*Reader, error) { return NewReaderOptions(ReaderOptions{ RootfsMountpoint: rootfsMountpoint, IgnoreRootCgroups: ignoreRootCgroups, @@ -107,10 +109,6 @@ func NewReader(rootfsMountpoint string, ignoreRootCgroups bool) (*Reader, error) // NewReaderOptions creates and returns a new Reader with the given options. func NewReaderOptions(opts ReaderOptions) (*Reader, error) { - if opts.RootfsMountpoint == "" { - opts.RootfsMountpoint = "/" - } - // Determine what subsystems are supported by the kernel. subsystems, err := SupportedSubsystems(opts.RootfsMountpoint) // We can return a not-quite-an-error ErrCgroupsMissing here, so return the bare error. @@ -134,7 +132,8 @@ func NewReaderOptions(opts ReaderOptions) (*Reader, error) { // CgroupsVersion reports if the given PID is attached to a V1 or V2 controller func (r *Reader) CgroupsVersion(pid int) (CgroupsVersion, error) { - cgPath := filepath.Join(r.rootfsMountpoint, "/proc/", fmt.Sprintf("%d", pid), "cgroup") + cgPath := filepath.Join("/proc/", strconv.Itoa(pid), "cgroup") + cgPath = r.rootfsMountpoint.ResolveHostFS(cgPath) cgraw, err := ioutil.ReadFile(cgPath) if err != nil { return CgroupsV1, errors.Wrapf(err, "error reading %s", cgPath) @@ -227,7 +226,7 @@ func (r *Reader) GetV2StatsForProcess(pid int) (*StatsV2, error) { // ProcessCgroupPaths is a wrapper around Reader.ProcessCgroupPaths for libraries that only need the slimmer functionality from // the gosigar cgroups code. This does not have the same function signature, and consumers still need to distinguish between v1 and v2 cgroups. -func ProcessCgroupPaths(hostfs string, pid int) (PathList, error) { +func ProcessCgroupPaths(hostfs resolve.Resolver, pid int) (PathList, error) { reader, err := NewReader(hostfs, false) if err != nil { return PathList{}, errors.Wrap(err, "error creating cgroups reader") diff --git a/libbeat/metric/system/cgroup/reader_test.go b/libbeat/metric/system/cgroup/reader_test.go index bd539d305603..d6f707086ed5 100644 --- a/libbeat/metric/system/cgroup/reader_test.go +++ b/libbeat/metric/system/cgroup/reader_test.go @@ -23,6 +23,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) const ( @@ -31,7 +33,7 @@ const ( ) func TestReaderGetStatsV1(t *testing.T) { - reader, err := NewReader("testdata/docker", true) + reader, err := NewReader(resolve.NewTestResolver("testdata/docker"), true) assert.NoError(t, err, "error in NewReader") stats, err := reader.GetV1StatsForProcess(985) @@ -67,7 +69,7 @@ func TestReaderGetStatsV1(t *testing.T) { } func TestReaderGetStatsV2(t *testing.T) { - reader, err := NewReader("testdata/docker", true) + reader, err := NewReader(resolve.NewTestResolver("testdata/docker"), true) assert.NoError(t, err, "error in NewReader") stats, err := reader.GetV2StatsForProcess(312) @@ -93,7 +95,7 @@ func TestReaderGetStatsHierarchyOverride(t *testing.T) { // within a Docker container. reader, err := NewReaderOptions(ReaderOptions{ - RootfsMountpoint: "testdata/docker", + RootfsMountpoint: resolve.NewTestResolver("testdata/docker"), IgnoreRootCgroups: false, CgroupsHierarchyOverride: "/", }) @@ -113,7 +115,7 @@ func TestReaderGetStatsHierarchyOverride(t *testing.T) { assert.NotZero(t, stats.CPU.CFS.Shares) reader2, err := NewReaderOptions(ReaderOptions{ - RootfsMountpoint: "testdata/docker", + RootfsMountpoint: resolve.NewTestResolver("testdata/docker"), IgnoreRootCgroups: true, CgroupsHierarchyOverride: "/system.slice/", }) diff --git a/libbeat/metric/system/cgroup/util.go b/libbeat/metric/system/cgroup/util.go index 70879b877386..2d1678b790b6 100644 --- a/libbeat/metric/system/cgroup/util.go +++ b/libbeat/metric/system/cgroup/util.go @@ -29,6 +29,7 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) var ( @@ -119,12 +120,8 @@ func parseMountinfoLine(line string) (mountinfo, error) { // SupportedSubsystems returns the subsystems that are supported by the // kernel. The returned map contains a entry for each subsystem. -func SupportedSubsystems(rootfsMountpoint string) (map[string]struct{}, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } - - cgroups, err := os.Open(filepath.Join(rootfsMountpoint, "proc", "cgroups")) +func SupportedSubsystems(rootfs resolve.Resolver) (map[string]struct{}, error) { + cgroups, err := os.Open(rootfs.ResolveHostFS("/proc/cgroups")) if err != nil { if os.IsNotExist(err) { return nil, ErrCgroupsMissing @@ -171,12 +168,9 @@ func SupportedSubsystems(rootfsMountpoint string) (map[string]struct{}, error) { // SubsystemMountpoints returns the mountpoints for each of the given subsystems. // The returned map contains the subsystem name as a key and the value is the // mountpoint. -func SubsystemMountpoints(rootfsMountpoint string, subsystems map[string]struct{}) (Mountpoints, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } +func SubsystemMountpoints(rootfs resolve.Resolver, subsystems map[string]struct{}) (Mountpoints, error) { - mountinfo, err := os.Open(filepath.Join(rootfsMountpoint, "proc", "self", "mountinfo")) + mountinfo, err := os.Open(rootfs.ResolveHostFS("/proc/self/mountinfo")) if err != nil { return Mountpoints{}, err } @@ -199,7 +193,8 @@ func SubsystemMountpoints(rootfsMountpoint string, subsystems map[string]struct{ return Mountpoints{}, err } - if !strings.HasPrefix(mount.mountpoint, rootfsMountpoint) { + // if the mountpoint from the subsystem has a different root than ours, it probably belongs to something else. + if !strings.HasPrefix(mount.mountpoint, rootfs.ResolveHostFS("")) { continue } @@ -237,7 +232,8 @@ func SubsystemMountpoints(rootfsMountpoint string, subsystems map[string]struct{ // ProcessCgroupPaths returns the cgroups to which a process belongs and the // pathname of the cgroup relative to the mountpoint of the subsystem. func (r Reader) ProcessCgroupPaths(pid int) (PathList, error) { - cgroup, err := os.Open(filepath.Join(r.rootfsMountpoint, "proc", strconv.Itoa(pid), "cgroup")) + cgroupPath := filepath.Join("proc", strconv.Itoa(pid), "cgroup") + cgroup, err := os.Open(r.rootfsMountpoint.ResolveHostFS(cgroupPath)) if err != nil { return PathList{}, err //return a blank error so other events can use any file not found errors } @@ -271,15 +267,14 @@ func (r Reader) ProcessCgroupPaths(pid int) (PathList, error) { // For this very annoying edge case, revert to the hostfs flag // If it's not set, warn the user that they've hit this. controllerPath := filepath.Join(r.cgroupMountpoints.V2Loc, path) - // Depending on the test environment, Hostfs can either be blank, or `/` - if r.cgroupMountpoints.V2Loc == "" && len(r.rootfsMountpoint) <= 1 { + if r.cgroupMountpoints.V2Loc == "" && !r.rootfsMountpoint.IsSet() { logp.L().Debugf(`PID %d contains a cgroups V2 path (%s) but no V2 mountpoint was found. This may be because metricbeat is running inside a container on a hybrid system. To monitor cgroups V2 processess in this way, mount the unified (V2) hierarchy inside -the container as /sys/fs/cgroup/unified and start metricbeat with --system.hostfs.`, pid, line) +the container as /sys/fs/cgroup/unified and start the system module with the hostfs setting.`, pid, line) continue - } else if r.cgroupMountpoints.V2Loc == "" && len(r.rootfsMountpoint) > 1 { - controllerPath = filepath.Join(r.rootfsMountpoint, "/sys/fs/cgroup/unified", path) + } else if r.cgroupMountpoints.V2Loc == "" && r.rootfsMountpoint.IsSet() { + controllerPath = r.rootfsMountpoint.ResolveHostFS(filepath.Join("/sys/fs/cgroup/unified", path)) } cgpaths, err := ioutil.ReadDir(controllerPath) diff --git a/libbeat/metric/system/cgroup/util_test.go b/libbeat/metric/system/cgroup/util_test.go index 8766ccb2e043..24ee57849894 100644 --- a/libbeat/metric/system/cgroup/util_test.go +++ b/libbeat/metric/system/cgroup/util_test.go @@ -26,6 +26,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) const dockerTestData = "testdata/docker.zip" @@ -103,7 +105,7 @@ func exists(path string) (bool, error) { } func TestSupportedSubsystems(t *testing.T) { - subsystems, err := SupportedSubsystems("testdata/docker") + subsystems, err := SupportedSubsystems(resolve.NewTestResolver("testdata/docker")) if err != nil { t.Fatal(err) } @@ -126,7 +128,7 @@ func TestSupportedSubsystems(t *testing.T) { } func TestSupportedSubsystemsErrCgroupsMissing(t *testing.T) { - _, err := SupportedSubsystems("testdata/doesnotexist") + _, err := SupportedSubsystems(resolve.NewTestResolver("testdata/doesnotexist")) if err != ErrCgroupsMissing { t.Fatalf("expected ErrCgroupsMissing, but got %v", err) } @@ -144,7 +146,7 @@ func TestSubsystemMountpoints(t *testing.T) { subsystems["memory"] = struct{}{} subsystems["perf_event"] = struct{}{} - mountpoints, err := SubsystemMountpoints("testdata/docker", subsystems) + mountpoints, err := SubsystemMountpoints(resolve.NewTestResolver("testdata/docker"), subsystems) if err != nil { t.Fatal(err) } @@ -161,7 +163,7 @@ func TestSubsystemMountpoints(t *testing.T) { } func TestProcessCgroupPaths(t *testing.T) { - reader, err := NewReader("testdata/docker", false) + reader, err := NewReader(resolve.NewTestResolver("testdata/docker"), false) if err != nil { t.Fatalf("error in NewReader: %s", err) } @@ -185,7 +187,7 @@ func TestProcessCgroupPaths(t *testing.T) { } func TestProcessCgroupPathsV2(t *testing.T) { - reader, err := NewReader("testdata/docker", false) + reader, err := NewReader(resolve.NewTestResolver("testdata/docker"), false) if err != nil { t.Fatalf("error in NewReader: %s", err) } diff --git a/libbeat/metric/system/numcpu/cpu_linux.go b/libbeat/metric/system/numcpu/cpu_linux.go index d8f2e9f821c0..af5a80f51a13 100644 --- a/libbeat/metric/system/numcpu/cpu_linux.go +++ b/libbeat/metric/system/numcpu/cpu_linux.go @@ -21,12 +21,9 @@ import ( "fmt" "io/ioutil" "os" - "path/filepath" "strings" "github.com/pkg/errors" - - "github.com/elastic/beats/v7/libbeat/paths" ) // getCPU implements NumCPU on linux @@ -45,20 +42,19 @@ func getCPU() (int, bool, error) { if isPresent { cpuPath = "/sys/devices/system/cpu/present" } - sysfspath := filepath.Join(paths.Paths.Hostfs, cpuPath) - rawFile, err := ioutil.ReadFile(sysfspath) + rawFile, err := ioutil.ReadFile(cpuPath) // if the file doesn't exist, assume it's a support issue and not a bug if errors.Is(err, os.ErrNotExist) { return -1, false, nil } if err != nil { - return -1, false, errors.Wrapf(err, "error reading file %s", sysfspath) + return -1, false, errors.Wrapf(err, "error reading file %s", cpuPath) } cpuCount, err := parseCPUList(string(rawFile)) if err != nil { - return -1, false, errors.Wrapf(err, "error parsing file %s", sysfspath) + return -1, false, errors.Wrapf(err, "error parsing file %s", cpuPath) } return cpuCount, true, nil } diff --git a/libbeat/metric/system/process/process.go b/libbeat/metric/system/process/process.go index b5a1f486d9dc..a628690ae4b8 100644 --- a/libbeat/metric/system/process/process.go +++ b/libbeat/metric/system/process/process.go @@ -462,6 +462,7 @@ func (procStats *Stats) Init() error { cgReader, err := cgroup.NewReaderOptions(procStats.CgroupOpts) if err == cgroup.ErrCgroupsMissing { logp.Warn("cgroup data collection will be disabled: %v", err) + procStats.EnableCgroups = false } else if err != nil { return errors.Wrap(err, "error initializing cgroup reader") } diff --git a/libbeat/metric/system/resolve/resolve.go b/libbeat/metric/system/resolve/resolve.go new file mode 100644 index 000000000000..3f919897f090 --- /dev/null +++ b/libbeat/metric/system/resolve/resolve.go @@ -0,0 +1,56 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package resolve + +import "path/filepath" + +// Resolver is an interface for HostFS resolvers. This is meant to be generic and (hopefully) future-proof way of dealing with a user-supplied root filesystem path. +// A resolver-style function serves two ends: +// 1) if we attempt to stop consumers from merely "saving off" a string, the underlying implementation can update hostfs values and pass the new paths along to consumers +// 2) This stops different bits of code from making different assumptions about what's in hostfs and otherwise treating the concept differently. It's easy to mix up "hostfs" and "procfs" and "sysfs" as concepts. +// A single resolver forces this logic to be a little more centralized. +type Resolver interface { + // ResolveHostFS Resolves a path based on a user-set HostFS flag, in cases where a user wants to monitor an alternate filesystem root + // If no user root has been set, it will return the input string + ResolveHostFS(string) string + // IsSet returns true if the user has set an alternate filesystem root + IsSet() bool +} + +// TestingResolver is a bare implementation of the resolver, for system tests that need a Resolver object or a test path for input files. +type TestingResolver struct { + path string + isSet bool +} + +// NewTestResolver returns a new resolver for internal testing, or other uses outside metricbeat modules. +func NewTestResolver(path string) TestingResolver { + if path == "" || path == "/" { + return TestingResolver{path: "/", isSet: false} + } + + return TestingResolver{path: path, isSet: true} +} + +func (t TestingResolver) ResolveHostFS(path string) string { + return filepath.Join(t.path, path) +} + +func (t TestingResolver) IsSet() bool { + return t.isSet +} diff --git a/libbeat/paths/paths.go b/libbeat/paths/paths.go index 53cabb9f956e..f73c0e34e97b 100644 --- a/libbeat/paths/paths.go +++ b/libbeat/paths/paths.go @@ -28,8 +28,6 @@ // // path.config - Configuration files and Elasticsearch template default location // -// system.hostfs - supplies an alternate filesystem root for containerized environments -// // These settings can be set via the configuration file or via command line flags. // The CLI flags overwrite the configuration file options. // @@ -40,25 +38,17 @@ package paths import ( - "flag" "fmt" "os" "path/filepath" ) -var ( - // TODO: remove this flag in 8.0 since it should be replaced by system.hostfs configuration option (config.HostFS) - // HostFS is an alternate mountpoint for the filesytem root, for when metricbeat is running inside a container. - hostFS = flag.String("system.hostfs", "", "Mount point of the host's filesystem for use in monitoring a host from within a container") -) - // Path tracks user-configurable path locations and directories type Path struct { Home string Config string Data string Logs string - Hostfs string } // FileType is an enumeration type representing the file types. @@ -74,11 +64,6 @@ const ( Data FileType = "data" // Logs is the path to the beats logs directory Logs FileType = "logs" - // Hostfs is an alternate path to the filesystem root, - // used for system metrics that interact with procfs and sysfs. - // Unlike the other values here, this corrisponds to `system.hostfs` - // and not `path.hostfs`. - Hostfs FileType = "hostfs" ) // Paths is the Path singleton on which the top level functions from this @@ -135,31 +120,15 @@ func (paths *Path) initPaths(cfg *Path) error { paths.Logs = filepath.Join(paths.Home, "logs") } - if *hostFS != "" { - paths.Hostfs = *hostFS - } - - if paths.Hostfs == "" { - paths.Hostfs = "/" - } - return nil } -// IsCLISet returns true if the CLI system.hostfs value has been set -func IsCLISet() bool { - if *hostFS != "" { - return true - } - return false -} - // Resolve resolves a path to a location in one of the default // folders. For example, Resolve(Home, "test") returns an absolute // path for "test" in the home path. func (paths *Path) Resolve(fileType FileType, path string) string { // absolute paths are not changed for non-hostfs file types, since hostfs is a little odd - if filepath.IsAbs(path) && fileType != Hostfs { + if filepath.IsAbs(path) { return path } @@ -172,8 +141,6 @@ func (paths *Path) Resolve(fileType FileType, path string) string { return filepath.Join(paths.Data, path) case Logs: return filepath.Join(paths.Logs, path) - case Hostfs: - return filepath.Join(paths.Hostfs, path) default: panic(fmt.Sprintf("Unknown file type: %s", fileType)) } @@ -189,6 +156,6 @@ func Resolve(fileType FileType, path string) string { // String returns a textual representation func (paths *Path) String() string { - return fmt.Sprintf("Home path: [%s] Config path: [%s] Data path: [%s] Logs path: [%s] Hostfs Path: [%s]", - paths.Home, paths.Config, paths.Data, paths.Logs, paths.Hostfs) + return fmt.Sprintf("Home path: [%s] Config path: [%s] Data path: [%s] Logs path: [%s]", + paths.Home, paths.Config, paths.Data, paths.Logs) } diff --git a/libbeat/processors/add_docker_metadata/add_docker_metadata.go b/libbeat/processors/add_docker_metadata/add_docker_metadata.go index ddea3c85b29c..5282fc27e391 100644 --- a/libbeat/processors/add_docker_metadata/add_docker_metadata.go +++ b/libbeat/processors/add_docker_metadata/add_docker_metadata.go @@ -35,6 +35,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/safemapstr" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/processors" "github.com/elastic/beats/v7/libbeat/processors/actions" ) @@ -59,11 +60,11 @@ type addDockerMetadata struct { fields []string sourceProcessor processors.Processor - pidFields []string // Field names that contain PIDs. - cgroups *common.Cache // Cache of PID (int) to cgropus (map[string]string). - hostFS string // Directory where /proc is found - dedot bool // If set to true, replace dots in labels with `_`. - dockerAvailable bool // If Docker exists in env, then it is set to true + pidFields []string // Field names that contain PIDs. + cgroups *common.Cache // Cache of PID (int) to cgropus (map[string]string). + hostFS resolve.Resolver // Directory where /proc is found + dedot bool // If set to true, replace dots in labels with `_`. + dockerAvailable bool // If Docker exists in env, then it is set to true } const selector = "add_docker_metadata" @@ -114,7 +115,7 @@ func buildDockerMetadataProcessor(log *logp.Logger, cfg *common.Config, watcherC fields: config.Fields, sourceProcessor: sourceProcessor, pidFields: config.MatchPIDs, - hostFS: config.HostFS, + hostFS: resolve.NewTestResolver(config.HostFS), dedot: config.DeDot, dockerAvailable: dockerAvailable, }, nil diff --git a/libbeat/processors/add_docker_metadata/add_docker_metadata_test.go b/libbeat/processors/add_docker_metadata/add_docker_metadata_test.go index 07f3fe232a27..edde24f41841 100644 --- a/libbeat/processors/add_docker_metadata/add_docker_metadata_test.go +++ b/libbeat/processors/add_docker_metadata/add_docker_metadata_test.go @@ -35,11 +35,12 @@ import ( "github.com/elastic/beats/v7/libbeat/common/docker" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) func init() { // Stub out the procfs. - processCgroupPaths = func(_ string, pid int) (cgroup.PathList, error) { + processCgroupPaths = func(_ resolve.Resolver, pid int) (cgroup.PathList, error) { switch pid { case 1000: diff --git a/libbeat/processors/add_docker_metadata/config.go b/libbeat/processors/add_docker_metadata/config.go index c7844de0369e..ddbf9b88796d 100644 --- a/libbeat/processors/add_docker_metadata/config.go +++ b/libbeat/processors/add_docker_metadata/config.go @@ -35,7 +35,7 @@ type Config struct { MatchShortID bool `config:"match_short_id"` // Match to container short ID from a log path present in source field. SourceIndex int `config:"match_source_index"` // Index in the source path split by / to look for container ID. MatchPIDs []string `config:"match_pids"` // A list of fields containing process IDs (PIDs). - HostFS string `config:"system.hostfs"` // Specifies the mount point of the host’s filesystem for use in monitoring a host from within a container. + HostFS string `config:"hostfs"` // Specifies the mount point of the host’s filesystem for use in monitoring a host from within a container. DeDot bool `config:"labels.dedot"` // If set to true, replace dots in labels with `_`. // Annotations are kept after container is killed, until they haven't been diff --git a/libbeat/processors/add_process_metadata/add_process_metadata.go b/libbeat/processors/add_process_metadata/add_process_metadata.go index 0cc6a2ebc48e..e405aa6940b1 100644 --- a/libbeat/processors/add_process_metadata/add_process_metadata.go +++ b/libbeat/processors/add_process_metadata/add_process_metadata.go @@ -30,6 +30,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/atomic" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/processors" jsprocessor "github.com/elastic/beats/v7/libbeat/processors/script/javascript/module/processor" ) @@ -134,9 +135,9 @@ func newProcessMetadataProcessorWithProvider(cfg *common.Config, provider proces p.cgroupsCache = common.NewCacheWithRemovalListener(config.CgroupCacheExpireTime, 100, evictionListener) p.cgroupsCache.StartJanitor(config.CgroupCacheExpireTime) - p.cidProvider = newCidProvider(config.HostPath, config.CgroupPrefixes, config.CgroupRegex, processCgroupPaths, p.cgroupsCache) + p.cidProvider = newCidProvider(resolve.NewTestResolver(config.HostPath), config.CgroupPrefixes, config.CgroupRegex, processCgroupPaths, p.cgroupsCache) } else { - p.cidProvider = newCidProvider(config.HostPath, config.CgroupPrefixes, config.CgroupRegex, processCgroupPaths, nil) + p.cidProvider = newCidProvider(resolve.NewTestResolver(config.HostPath), config.CgroupPrefixes, config.CgroupRegex, processCgroupPaths, nil) } } diff --git a/libbeat/processors/add_process_metadata/add_process_metadata_test.go b/libbeat/processors/add_process_metadata/add_process_metadata_test.go index 1238702d0f4f..51f4a33172ee 100644 --- a/libbeat/processors/add_process_metadata/add_process_metadata_test.go +++ b/libbeat/processors/add_process_metadata/add_process_metadata_test.go @@ -31,6 +31,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) func TestAddProcessMetadata(t *testing.T) { @@ -74,7 +75,7 @@ func TestAddProcessMetadata(t *testing.T) { } // mock of the cgroup processCgroupPaths - processCgroupPaths = func(_ string, pid int) (cgroup.PathList, error) { + processCgroupPaths = func(_ resolve.Resolver, pid int) (cgroup.PathList, error) { testMap := map[int]cgroup.PathList{ 1: { @@ -758,7 +759,7 @@ func TestUsingCache(t *testing.T) { selfPID := os.Getpid() // mock of the cgroup processCgroupPaths - processCgroupPaths = func(_ string, pid int) (cgroup.PathList, error) { + processCgroupPaths = func(_ resolve.Resolver, pid int) (cgroup.PathList, error) { testStruct := cgroup.PathList{ V1: map[string]cgroup.ControllerPath{ @@ -1057,7 +1058,7 @@ func TestPIDToInt(t *testing.T) { } func TestV2CID(t *testing.T) { - processCgroupPaths = func(_ string, _ int) (cgroup.PathList, error) { + processCgroupPaths = func(_ resolve.Resolver, _ int) (cgroup.PathList, error) { testMap := cgroup.PathList{ V1: map[string]cgroup.ControllerPath{ "cpu": cgroup.ControllerPath{IsV2: true, ControllerPath: "system.slice/docker-2dcbab615aebfa9313feffc5cfdacd381543cfa04c6be3f39ac656e55ef34805.scope"}, @@ -1065,7 +1066,7 @@ func TestV2CID(t *testing.T) { } return testMap, nil } - provider := newCidProvider("", []string{}, "", processCgroupPaths, nil) + provider := newCidProvider(resolve.NewTestResolver(""), []string{}, "", processCgroupPaths, nil) result, err := provider.GetCid(1) assert.NoError(t, err) assert.Equal(t, "2dcbab615aebfa9313feffc5cfdacd381543cfa04c6be3f39ac656e55ef34805", result) diff --git a/libbeat/processors/add_process_metadata/gosigar_cid_provider.go b/libbeat/processors/add_process_metadata/gosigar_cid_provider.go index 98aafaebd2f2..2064648242c6 100644 --- a/libbeat/processors/add_process_metadata/gosigar_cid_provider.go +++ b/libbeat/processors/add_process_metadata/gosigar_cid_provider.go @@ -28,6 +28,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) const ( @@ -36,11 +37,11 @@ const ( type gosigarCidProvider struct { log *logp.Logger - hostPath string + hostPath resolve.Resolver cgroupPrefixes []string cgroupRegex string cidRegex *regexp.Regexp - processCgroupPaths func(string, int) (cgroup.PathList, error) + processCgroupPaths func(resolve.Resolver, int) (cgroup.PathList, error) pidCidCache *common.Cache } @@ -72,7 +73,7 @@ func (p gosigarCidProvider) GetCid(pid int) (result string, err error) { return cid, nil } -func newCidProvider(hostPath string, cgroupPrefixes []string, cgroupRegex string, processCgroupPaths func(string, int) (cgroup.PathList, error), pidCidCache *common.Cache) gosigarCidProvider { +func newCidProvider(hostPath resolve.Resolver, cgroupPrefixes []string, cgroupRegex string, processCgroupPaths func(resolve.Resolver, int) (cgroup.PathList, error), pidCidCache *common.Cache) gosigarCidProvider { return gosigarCidProvider{ log: logp.NewLogger(providerName), hostPath: hostPath, diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc index 61498eb9932b..225285b3264a 100644 --- a/metricbeat/docs/modules/system.asciidoc +++ b/metricbeat/docs/modules/system.asciidoc @@ -185,7 +185,7 @@ metricbeat.modules: processes: ['.*'] # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container - #system.hostfs: "/hostfs" + #hostfs: "/hostfs" # Configure the metric types that are included by these metricsets. cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. diff --git a/metricbeat/docs/running-on-docker.asciidoc b/metricbeat/docs/running-on-docker.asciidoc index c51f1314beed..cc7c8c5b6501 100644 --- a/metricbeat/docs/running-on-docker.asciidoc +++ b/metricbeat/docs/running-on-docker.asciidoc @@ -28,16 +28,16 @@ are isolated as much as possible from the host, the data inside of the container's `/proc` is different than the host's `/proc`. To account for this, you can mount the host's `/proc` filesystem inside of the container and tell Metricbeat to look inside the `/hostfs` directory when looking for `/proc` by -using the `-system.hostfs=/hostfs` CLI flag. +using the `hostfs=/hostfs` config value. <2> By default, cgroup reporting is enabled for the <>, so you need to mount the host's cgroup mountpoints within the container. They need to be -mounted inside the directory specified by the `-system.hostfs` CLI flag. +mounted inside the directory specified by the `hostfs` config value. <3> If you want to be able to monitor filesystems from the host by using the <>, then those filesystems need to be mounted inside of the container. They can be mounted at any location. <4> The <> uses data from `/proc/net/dev`, or -`/hostfs/proc/net/dev` when using `-system.hostfs=/hostfs`. The only way +`/hostfs/proc/net/dev` when using `hostfs=/hostfs`. The only way to make this file contain the host's network devices is to use the `--net=host` flag. This is due to Linux namespacing; simply bind mounting the host's `/proc` to `/hostfs/proc` is not sufficient. diff --git a/metricbeat/internal/metrics/cpu/metrics.go b/metricbeat/internal/metrics/cpu/metrics.go index 931111f1bfe5..75fa38d62d7b 100644 --- a/metricbeat/internal/metrics/cpu/metrics.go +++ b/metricbeat/internal/metrics/cpu/metrics.go @@ -21,6 +21,7 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -69,12 +70,12 @@ calculate CPU percentages, as we average usage across a time period. // Monitor is used to monitor the overall CPU usage of the system over time. type Monitor struct { lastSample CPUMetrics - Hostfs string + Hostfs resolve.Resolver } // New returns a new CPU metrics monitor // Hostfs is only relevant on linux and freebsd. -func New(hostfs string) *Monitor { +func New(hostfs resolve.Resolver) *Monitor { return &Monitor{Hostfs: hostfs} } diff --git a/metricbeat/internal/metrics/cpu/metrics_aix.go b/metricbeat/internal/metrics/cpu/metrics_aix.go index a746e1bd0b21..022e69ea601f 100644 --- a/metricbeat/internal/metrics/cpu/metrics_aix.go +++ b/metricbeat/internal/metrics/cpu/metrics_aix.go @@ -38,6 +38,7 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -59,7 +60,7 @@ func tick2msec(val uint64) uint64 { } // Get returns a metrics object for CPU data -func Get(_ string) (CPUMetrics, error) { +func Get(_ resolve.Resolver) (CPUMetrics, error) { totals, err := getCPUTotals() if err != nil { diff --git a/metricbeat/internal/metrics/cpu/metrics_darwin.go b/metricbeat/internal/metrics/cpu/metrics_darwin.go index 6e18bb70761c..7fe680687df1 100644 --- a/metricbeat/internal/metrics/cpu/metrics_darwin.go +++ b/metricbeat/internal/metrics/cpu/metrics_darwin.go @@ -21,11 +21,12 @@ import ( "github.com/pkg/errors" "github.com/shirou/gopsutil/cpu" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) // Get is the Darwin implementation of Get -func Get(_ string) (CPUMetrics, error) { +func Get(_ resolve.Resolver) (CPUMetrics, error) { // We're using the gopsutil library here. // The code used by both gosigar and go-sysinfo appears to be // the same code as gopsutil, including copy-pasted comments. diff --git a/metricbeat/internal/metrics/cpu/metrics_openbsd.go b/metricbeat/internal/metrics/cpu/metrics_openbsd.go index b0d386bc3fe2..15969d906dad 100644 --- a/metricbeat/internal/metrics/cpu/metrics_openbsd.go +++ b/metricbeat/internal/metrics/cpu/metrics_openbsd.go @@ -36,11 +36,12 @@ import ( "syscall" "unsafe" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) // Get is the OpenBSD implementation of get -func Get(_ string) (CPUMetrics, error) { +func Get(_ resolve.Resolver) (CPUMetrics, error) { // see man 2 sysctl loadGlobal := [C.CPUSTATES]C.long{ diff --git a/metricbeat/internal/metrics/cpu/metrics_procfs_common.go b/metricbeat/internal/metrics/cpu/metrics_procfs_common.go index 3d5b36b5d742..be86cb1213c2 100644 --- a/metricbeat/internal/metrics/cpu/metrics_procfs_common.go +++ b/metricbeat/internal/metrics/cpu/metrics_procfs_common.go @@ -23,16 +23,18 @@ package cpu import ( "bufio" "os" - "path/filepath" "strconv" "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) // Get returns a metrics object for CPU data -func Get(procfs string) (CPUMetrics, error) { - path := filepath.Join(procfs, "/proc/stat") +func Get(procfs resolve.Resolver) (CPUMetrics, error) { + path := procfs.ResolveHostFS("/proc/stat") fd, err := os.Open(path) + defer fd.Close() if err != nil { return CPUMetrics{}, errors.Wrapf(err, "error opening file %s", path) } diff --git a/metricbeat/internal/metrics/cpu/metrics_test.go b/metricbeat/internal/metrics/cpu/metrics_test.go index 3a89afe6b80f..91a3f302375e 100644 --- a/metricbeat/internal/metrics/cpu/metrics_test.go +++ b/metricbeat/internal/metrics/cpu/metrics_test.go @@ -23,11 +23,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) func TestMonitorSample(t *testing.T) { - cpu := &Monitor{lastSample: CPUMetrics{}} + cpu := &Monitor{lastSample: CPUMetrics{}, Hostfs: resolve.NewTestResolver("")} s, err := cpu.Fetch() if err != nil { t.Fatal(err) @@ -40,10 +41,10 @@ func TestMonitorSample(t *testing.T) { func TestCoresMonitorSample(t *testing.T) { - cpuMetrics, err := Get("") + cpuMetrics, err := Get(resolve.NewTestResolver("")) assert.NoError(t, err, "error in Get()") - cores := &Monitor{lastSample: CPUMetrics{list: make([]CPU, len(cpuMetrics.list))}} + cores := &Monitor{lastSample: CPUMetrics{list: make([]CPU, len(cpuMetrics.list))}, Hostfs: resolve.NewTestResolver("")} sample, err := cores.FetchCores() if err != nil { t.Fatal(err) diff --git a/metricbeat/internal/metrics/cpu/metrics_windows.go b/metricbeat/internal/metrics/cpu/metrics_windows.go index d9e4abca19af..7e0a258aa065 100644 --- a/metricbeat/internal/metrics/cpu/metrics_windows.go +++ b/metricbeat/internal/metrics/cpu/metrics_windows.go @@ -27,12 +27,13 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" "github.com/elastic/gosigar/sys/windows" ) // Get fetches Windows CPU system times -func Get(_ string) (CPUMetrics, error) { +func Get(_ resolve.Resolver) (CPUMetrics, error) { idle, kernel, user, err := windows.GetSystemTimes() if err != nil { return CPUMetrics{}, errors.Wrap(err, "GetSystemTimes failed") diff --git a/metricbeat/internal/metrics/memory/memory.go b/metricbeat/internal/metrics/memory/memory.go index eb00ca80202a..79efbdd825e3 100644 --- a/metricbeat/internal/metrics/memory/memory.go +++ b/metricbeat/internal/metrics/memory/memory.go @@ -21,6 +21,7 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -65,7 +66,7 @@ type SwapMetrics struct { } // Get returns platform-independent memory metrics. -func Get(procfs string) (Memory, error) { +func Get(procfs resolve.Resolver) (Memory, error) { base, err := get(procfs) if err != nil { return Memory{}, errors.Wrap(err, "error getting system memory info") diff --git a/metricbeat/internal/metrics/memory/memory_aix.go b/metricbeat/internal/metrics/memory/memory_aix.go index ce31e205a925..326b01e8125e 100644 --- a/metricbeat/internal/metrics/memory/memory_aix.go +++ b/metricbeat/internal/metrics/memory/memory_aix.go @@ -36,6 +36,7 @@ import ( "fmt" "os" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -51,7 +52,7 @@ func init() { system.pagesize = uint64(os.Getpagesize()) } -func get(_ string) (Memory, error) { +func get(_ resolve.Resolver) (Memory, error) { memData := Memory{} meminfo := C.perfstat_memory_total_t{} _, err := C.perfstat_memory_total(nil, &meminfo, C.sizeof_perfstat_memory_total_t, 1) diff --git a/metricbeat/internal/metrics/memory/memory_darwin.go b/metricbeat/internal/metrics/memory/memory_darwin.go index 95c5ab4b8fe1..dac04d070ea4 100644 --- a/metricbeat/internal/metrics/memory/memory_darwin.go +++ b/metricbeat/internal/metrics/memory/memory_darwin.go @@ -39,6 +39,7 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -47,7 +48,7 @@ type xswUsage struct { } // get is the darwin implementation for fetching Memory data -func get(_ string) (Memory, error) { +func get(_ resolve.Resolver) (Memory, error) { var vmstat C.vm_statistics_data_t mem := Memory{} diff --git a/metricbeat/internal/metrics/memory/memory_freebsd.go b/metricbeat/internal/metrics/memory/memory_freebsd.go index 7103e521ab3b..007e5ef21b3d 100644 --- a/metricbeat/internal/metrics/memory/memory_freebsd.go +++ b/metricbeat/internal/metrics/memory/memory_freebsd.go @@ -22,6 +22,7 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -38,7 +39,7 @@ import ( */ import "C" -func get(_ string) (Memory, error) { +func get(_ resolve.Resolver) (Memory, error) { val := C.uint32_t(0) sc := C.size_t(4) diff --git a/metricbeat/internal/metrics/memory/memory_helpers.go b/metricbeat/internal/metrics/memory/memory_helpers.go index 0761e9101465..c935837d88fe 100644 --- a/metricbeat/internal/metrics/memory/memory_helpers.go +++ b/metricbeat/internal/metrics/memory/memory_helpers.go @@ -22,18 +22,19 @@ import ( "bytes" "io" "io/ioutil" - "path/filepath" "strconv" "strings" "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) // ParseMeminfo parses the contents of /proc/meminfo into a hashmap -func ParseMeminfo(rootfs string) (map[string]uint64, error) { +func ParseMeminfo(rootfs resolve.Resolver) (map[string]uint64, error) { table := map[string]uint64{} - meminfoPath := filepath.Join(rootfs, "/proc/meminfo") + meminfoPath := rootfs.ResolveHostFS("/proc/meminfo") err := readFile(meminfoPath, func(line string) bool { fields := strings.Split(line, ":") diff --git a/metricbeat/internal/metrics/memory/memory_linux.go b/metricbeat/internal/metrics/memory/memory_linux.go index e90c153e531e..2aad8b367110 100644 --- a/metricbeat/internal/metrics/memory/memory_linux.go +++ b/metricbeat/internal/metrics/memory/memory_linux.go @@ -20,11 +20,12 @@ package memory import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) // get is the linux implementation for fetching Memory data -func get(rootfs string) (Memory, error) { +func get(rootfs resolve.Resolver) (Memory, error) { table, err := ParseMeminfo(rootfs) if err != nil { return Memory{}, errors.Wrap(err, "error fetching meminfo") diff --git a/metricbeat/internal/metrics/memory/memory_openbsd.go b/metricbeat/internal/metrics/memory/memory_openbsd.go index 05be48008100..addc33e88755 100644 --- a/metricbeat/internal/metrics/memory/memory_openbsd.go +++ b/metricbeat/internal/metrics/memory/memory_openbsd.go @@ -35,6 +35,7 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) @@ -157,7 +158,7 @@ type Swapent struct { sw_path []byte } -func get(_ string) (Memory, error) { +func get(_ resolve.Resolver) (Memory, error) { memData := Memory{} diff --git a/metricbeat/internal/metrics/memory/memory_test.go b/metricbeat/internal/metrics/memory/memory_test.go index e9e0bb63f3c7..4c9c979fdcef 100644 --- a/metricbeat/internal/metrics/memory/memory_test.go +++ b/metricbeat/internal/metrics/memory/memory_test.go @@ -27,11 +27,12 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" ) func TestGetMemory(t *testing.T) { - mem, err := Get("") + mem, err := Get(resolve.NewTestResolver("")) assert.NotNil(t, mem) assert.NoError(t, err) @@ -57,7 +58,7 @@ func TestGetSwap(t *testing.T) { return //no load data on freebsd } - mem, err := Get("") + mem, err := Get(resolve.NewTestResolver("")) assert.NotNil(t, mem) assert.NoError(t, err) @@ -105,7 +106,7 @@ func TestActualMemPercentage(t *testing.T) { func TestMeminfoParse(t *testing.T) { // Make sure we're manually calculating Actual correctly on linux if runtime.GOOS == "linux" { - mem, err := Get("./oldkern") + mem, err := Get(resolve.NewTestResolver("./oldkern")) assert.NoError(t, err) assert.Equal(t, uint64(27307106304), mem.Cached.ValueOr(0)) @@ -116,7 +117,7 @@ func TestMeminfoParse(t *testing.T) { func TestMeminfoPct(t *testing.T) { if runtime.GOOS == "linux" { - memRaw, err := Get("./oldkern") + memRaw, err := Get(resolve.NewTestResolver("./oldkern")) assert.NoError(t, err) assert.Equal(t, float64(0.1606), memRaw.Actual.Used.Pct.ValueOr(0)) assert.Equal(t, float64(0.5933), memRaw.Used.Pct.ValueOr(0)) diff --git a/metricbeat/internal/metrics/memory/memory_windows.go b/metricbeat/internal/metrics/memory/memory_windows.go index 0138825c1395..be0f003552e0 100644 --- a/metricbeat/internal/metrics/memory/memory_windows.go +++ b/metricbeat/internal/metrics/memory/memory_windows.go @@ -20,12 +20,13 @@ package memory import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/libbeat/opt" "github.com/elastic/go-windows" ) // get is the windows implementation of get for memory metrics -func get(_ string) (Memory, error) { +func get(_ resolve.Resolver) (Memory, error) { memData := Memory{} diff --git a/metricbeat/internal/sysinit/init.go b/metricbeat/internal/sysinit/init.go new file mode 100644 index 000000000000..203ccd4b0db6 --- /dev/null +++ b/metricbeat/internal/sysinit/init.go @@ -0,0 +1,112 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package sysinit + +import ( + "flag" + "sync" + + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/common/fleetmode" + "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +var hostfsCLI = flag.String("system.hostfs", "", "Mount point of the host's filesystem for use in monitoring a host from within a container") + +var once sync.Once + +// A wrapper library that allows us to deal with the more complex HostFS setter logic required for legacy metricbeat code. +// This will serve as a generic init function for either the system or linux module. + +// HostFSConfig is a bare struct for unpacking the config we get from agent or metricbeat +type HostFSConfig struct { + HostFS string `config:"hostfs"` +} + +// MetricbeatHostFSConfig +type MetricbeatHostFSConfig struct { + HostFS string `config:"system.hostfs"` +} + +// Init either the system or linux module. This will produce different modules depending on if we're running under agent or not. +func InitSystemModule(base mb.BaseModule) (mb.Module, error) { + // common code for the base use case of `hostfs` being set at the module-level + logger := logp.L() + hostfs, userSet := findConfigValue(base) + if fleetmode.Enabled() { + logger.Infof("initializing HostFS values under agent: %s", hostfs) + return fleetInit(base, hostfs, userSet) + } + return metricbeatInit(base, hostfs, userSet) +} + +func fleetInit(base mb.BaseModule, modulepath string, moduleSet bool) (mb.Module, error) { + once.Do(func() { + InitModule(modulepath) + }) + + // The multiple invocations here might seem buggy, but we're dealing with a case were agent's config schemea (local, per-datastream) must mesh with the global HostFS scheme used by some libraries + // Strictly speaking, we can't guarantee that agent will send consistent HostFS config values across all datastreams, as it treats a global value as per-datastream. + if moduleSet { + InitModule(modulepath) + } + + return &Module{BaseModule: base, HostFS: modulepath, UserSetHostFS: moduleSet}, nil +} + +// Deal with the legacy configs available to metricbeat +func metricbeatInit(base mb.BaseModule, modulePath string, moduleSet bool) (mb.Module, error) { + var hostfs = modulePath + var userSet bool + // allow the CLI to override other settings + if hostfsCLI != nil && *hostfsCLI != "" { + cfgwarn.Deprecate("8.0.0", "The --system.hostfs flag will be removed in the future and replaced by a config value.") + hostfs = *hostfsCLI + userSet = true + } + + once.Do(func() { + InitModule(hostfs) + }) + return &Module{BaseModule: base, HostFS: hostfs, UserSetHostFS: userSet}, nil + +} + +// A user can supply either `system.hostfs` or `hostfs`. +// In additon, we will probably want to change Integration Config values to `hostfs` as well. +// We need to figure out which one we got, if any. +func findConfigValue(base mb.BaseModule) (string, bool) { + partialConfig := HostFSConfig{} + base.UnpackConfig(&partialConfig) + // if the newer value is set, just use that. + if partialConfig.HostFS != "" { + return partialConfig.HostFS, true + } + + legacyConfig := MetricbeatHostFSConfig{} + base.UnpackConfig(&legacyConfig) + if legacyConfig.HostFS != "" { + cfgwarn.Deprecate("8.0.0", "The system.hostfs config value will be removed, use `hostfs` from within the module config.") + // Only fallback to this if the user didn't set anything else + return legacyConfig.HostFS, true + } + + return "/", false + +} diff --git a/metricbeat/internal/sysinit/module.go b/metricbeat/internal/sysinit/module.go new file mode 100644 index 000000000000..411372064a05 --- /dev/null +++ b/metricbeat/internal/sysinit/module.go @@ -0,0 +1,42 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package sysinit + +import ( + "path/filepath" + + "github.com/elastic/beats/v7/metricbeat/mb" +) + +// Module represents the system/linux module +type Module struct { + mb.BaseModule + HostFS string + UserSetHostFS bool +} + +// ResolveHostFS returns a full path based on a user-suppled path, and impliments the Resolver interface +// This is mostly to prevent any chance that other metricsets will develop their own way of +// using a user-suppied hostfs flag. We try to do all the logic in one place. +func (m Module) ResolveHostFS(path string) string { + return filepath.Join(m.HostFS, path) +} + +func (m Module) IsSet() bool { + return m.UserSetHostFS +} diff --git a/metricbeat/module/system/system_linux.go b/metricbeat/internal/sysinit/system_linux.go similarity index 93% rename from metricbeat/module/system/system_linux.go rename to metricbeat/internal/sysinit/system_linux.go index 2281bea3d0fa..4bb992f1441a 100644 --- a/metricbeat/module/system/system_linux.go +++ b/metricbeat/internal/sysinit/system_linux.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package system +package sysinit import ( "os" @@ -24,16 +24,12 @@ import ( "github.com/elastic/gosigar" ) -func initModule(config string) { +func InitModule(config string) { configureHostFS(config) } func configureHostFS(config string) { dir := config - if dir == "" { - dir = "/" - } - // Set environment variables for gopsutil. os.Setenv("HOST_PROC", filepath.Join(dir, "/proc")) os.Setenv("HOST_SYS", filepath.Join(dir, "/sys")) diff --git a/metricbeat/module/system/system_other.go b/metricbeat/internal/sysinit/system_other.go similarity index 94% rename from metricbeat/module/system/system_other.go rename to metricbeat/internal/sysinit/system_other.go index 6b99c5c3fed5..3ce49834b692 100644 --- a/metricbeat/module/system/system_other.go +++ b/metricbeat/internal/sysinit/system_other.go @@ -18,8 +18,8 @@ //go:build !linux && !windows // +build !linux,!windows -package system +package sysinit -func initModule(config string) { +func InitModule(config string) { // Stub method for non-linux. } diff --git a/metricbeat/module/system/system_windows.go b/metricbeat/internal/sysinit/system_windows.go similarity index 95% rename from metricbeat/module/system/system_windows.go rename to metricbeat/internal/sysinit/system_windows.go index bf6f457e24e1..d043c41b4967 100644 --- a/metricbeat/module/system/system_windows.go +++ b/metricbeat/internal/sysinit/system_windows.go @@ -15,14 +15,14 @@ // specific language governing permissions and limitations // under the License. -package system +package sysinit import ( "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/metricbeat/helper" ) -func initModule(config string) { +func InitModule(config string) { if err := helper.CheckAndEnableSeDebugPrivilege(); err != nil { logp.Warn("%v", err) } diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index d25c61ab5f07..46adc5cfdb4f 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -80,7 +80,7 @@ metricbeat.modules: processes: ['.*'] # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container - #system.hostfs: "/hostfs" + #hostfs: "/hostfs" # Configure the metric types that are included by these metricsets. cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. diff --git a/metricbeat/module/linux/conntrack/conntrack.go b/metricbeat/module/linux/conntrack/conntrack.go index c8d9122de09b..4d896a20928a 100644 --- a/metricbeat/module/linux/conntrack/conntrack.go +++ b/metricbeat/module/linux/conntrack/conntrack.go @@ -18,15 +18,13 @@ package conntrack import ( - "path/filepath" - "github.com/pkg/errors" "github.com/prometheus/procfs" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/linux" ) // init registers the MetricSet with the central registry as soon as the program @@ -43,7 +41,7 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - fs procfs.FS + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -51,18 +49,11 @@ type MetricSet struct { func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The linux conntrack metricset is beta.") - sys := base.Module().(linux.LinuxModule) - hostfs := sys.GetHostFS() - - path := filepath.Join(hostfs, "proc") - newFS, err := procfs.NewFS(path) - if err != nil { - return nil, errors.Wrapf(err, "error creating new Host FS at %s", path) - } + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - fs: newFS, + mod: sys, }, nil } @@ -70,7 +61,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - conntrackStats, err := m.fs.ConntrackStat() + newFS, err := procfs.NewFS(m.mod.ResolveHostFS("/proc")) + if err != nil { + return errors.Wrapf(err, "error creating new Host FS at %s", m.mod.ResolveHostFS("/proc")) + } + conntrackStats, err := newFS.ConntrackStat() if err != nil { return errors.Wrap(err, "error fetching conntrack stats") } diff --git a/metricbeat/module/linux/conntrack/conntrack_test.go b/metricbeat/module/linux/conntrack/conntrack_test.go index 32232249597f..e09d9439cc12 100644 --- a/metricbeat/module/linux/conntrack/conntrack_test.go +++ b/metricbeat/module/linux/conntrack/conntrack_test.go @@ -24,6 +24,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestData(t *testing.T) { diff --git a/metricbeat/module/linux/iostat/iostat.go b/metricbeat/module/linux/iostat/iostat.go index 9f40b260cbec..389424ff2fe0 100644 --- a/metricbeat/module/linux/iostat/iostat.go +++ b/metricbeat/module/linux/iostat/iostat.go @@ -70,7 +70,6 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - IOstats, err := diskio.IOCounters(m.includeDevices...) if err != nil { return errors.Wrap(err, "disk io counters") diff --git a/metricbeat/module/linux/iostat/iostat_test.go b/metricbeat/module/linux/iostat/iostat_test.go index be955e5fec4f..7cdbb9f8326f 100644 --- a/metricbeat/module/linux/iostat/iostat_test.go +++ b/metricbeat/module/linux/iostat/iostat_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/linux/ksm/ksm.go b/metricbeat/module/linux/ksm/ksm.go index 67ec072f6bf8..204b9364f54c 100644 --- a/metricbeat/module/linux/ksm/ksm.go +++ b/metricbeat/module/linux/ksm/ksm.go @@ -18,15 +18,13 @@ package ksm import ( - "path/filepath" - "github.com/elastic/beats/v7/libbeat/common" "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/linux" ) // init registers the MetricSet with the central registry as soon as the program @@ -43,7 +41,7 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - fs string + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -51,12 +49,11 @@ type MetricSet struct { func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The linux pageinfo metricset is beta.") - sys := base.Module().(linux.LinuxModule) - hostfs := sys.GetHostFS() + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - fs: filepath.Join(hostfs, "/sys/kernel/mm/ksm"), + mod: sys, }, nil } @@ -64,7 +61,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - ksmData, err := fetchKSMStats(m.fs) + ksmData, err := fetchKSMStats(m.mod.ResolveHostFS("/sys/kernel/mm/ksm")) if err != nil { return errors.Wrap(err, "error fetching KSM stats") } diff --git a/metricbeat/module/linux/ksm/ksm_test.go b/metricbeat/module/linux/ksm/ksm_test.go index f6e4ee50eca7..f4ee324d3d89 100644 --- a/metricbeat/module/linux/ksm/ksm_test.go +++ b/metricbeat/module/linux/ksm/ksm_test.go @@ -24,6 +24,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestData(t *testing.T) { diff --git a/metricbeat/module/linux/linux.go b/metricbeat/module/linux/linux.go index 25a29f15d017..a86b41f3c8fe 100644 --- a/metricbeat/module/linux/linux.go +++ b/metricbeat/module/linux/linux.go @@ -18,56 +18,13 @@ package linux import ( - "time" - - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/metricbeat/internal/sysinit" "github.com/elastic/beats/v7/metricbeat/mb" ) func init() { // Register the ModuleFactory function for the "system" module. - if err := mb.Registry.AddModule("linux", NewModule); err != nil { + if err := mb.Registry.AddModule("linux", sysinit.InitSystemModule); err != nil { panic(err) } } - -type LinuxModule interface { - GetHostFS() string -} - -// Module defines the base module config used in `linux` -type Module struct { - mb.BaseModule - HostFS string `config:"hostfs"` - Period time.Duration -} - -// NewModule initializes a new module -func NewModule(base mb.BaseModule) (mb.Module, error) { - // This only needs to be configured once for all system modules. - - config := struct { - Hostfs string `config:"hostfs"` - Period time.Duration `config:"period"` - }{} - - if err := base.UnpackConfig(&config); err != nil { - return nil, err - } - - dir := config.Hostfs - if dir == "" { - dir = "/" - } - - // Steer towards system.hostfs, since the two behave fundamentally the same, and system.hostfs has a CLI flag that many users may default to. - if len(paths.Paths.Hostfs) > 2 { - dir = paths.Paths.Hostfs - } - - return &Module{BaseModule: base, HostFS: dir, Period: config.Period}, nil -} - -func (m Module) GetHostFS() string { - return m.HostFS -} diff --git a/metricbeat/module/linux/memory/data.go b/metricbeat/module/linux/memory/data.go index ddf2cfc0797a..1f3740a7093e 100644 --- a/metricbeat/module/linux/memory/data.go +++ b/metricbeat/module/linux/memory/data.go @@ -21,13 +21,14 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/internal/metrics/memory" sysinfo "github.com/elastic/go-sysinfo" sysinfotypes "github.com/elastic/go-sysinfo/types" ) // FetchLinuxMemStats gets page_stat and huge pages data for linux -func FetchLinuxMemStats(baseMap common.MapStr) error { +func FetchLinuxMemStats(baseMap common.MapStr, hostfs resolve.Resolver) error { vmstat, err := GetVMStat() if err != nil { @@ -66,7 +67,7 @@ func FetchLinuxMemStats(baseMap common.MapStr) error { } baseMap["page_stats"] = pageStats - thp, err := getHugePages() + thp, err := getHugePages(hostfs) if err != nil { return errors.Wrap(err, "error getting huge pages") } @@ -82,9 +83,9 @@ func FetchLinuxMemStats(baseMap common.MapStr) error { return nil } -func getHugePages() (common.MapStr, error) { +func getHugePages(hostfs resolve.Resolver) (common.MapStr, error) { // see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt - table, err := memory.ParseMeminfo("") + table, err := memory.ParseMeminfo(hostfs) if err != nil { return nil, errors.Wrap(err, "error parsing meminfo") } diff --git a/metricbeat/module/linux/memory/memory.go b/metricbeat/module/linux/memory/memory.go index 35cd407b9b3d..bd71cadc6908 100644 --- a/metricbeat/module/linux/memory/memory.go +++ b/metricbeat/module/linux/memory/memory.go @@ -22,6 +22,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" ) @@ -39,15 +40,17 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking // any MetricSet specific configuration options if there are any. func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The linux memory metricset is beta.") - + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, + mod: sys, }, nil } @@ -56,7 +59,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { rootEvent := common.MapStr{} - err := FetchLinuxMemStats(rootEvent) + err := FetchLinuxMemStats(rootEvent, m.mod) if err != nil { return errors.Wrap(err, "error fetching memory stats") } diff --git a/metricbeat/module/linux/memory/memory_linux_test.go b/metricbeat/module/linux/memory/memory_linux_test.go index bddecc8f8a7c..da9ce77ca936 100644 --- a/metricbeat/module/linux/memory/memory_linux_test.go +++ b/metricbeat/module/linux/memory/memory_linux_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/linux/pageinfo/pageinfo.go b/metricbeat/module/linux/pageinfo/pageinfo.go index e4d700be7dba..2ffad602d990 100644 --- a/metricbeat/module/linux/pageinfo/pageinfo.go +++ b/metricbeat/module/linux/pageinfo/pageinfo.go @@ -20,14 +20,13 @@ package pageinfo import ( "bufio" "os" - "path/filepath" "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/linux" ) // init registers the MetricSet with the central registry as soon as the program @@ -44,7 +43,7 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - fs string + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -52,12 +51,11 @@ type MetricSet struct { func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The linux pageinfo metricset is beta.") - sys := base.Module().(linux.LinuxModule) - hostfs := sys.GetHostFS() + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - fs: hostfs, + mod: sys, }, nil } @@ -65,7 +63,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - pagePath := filepath.Join(m.fs, "/proc/pagetypeinfo") + pagePath := m.mod.ResolveHostFS("/proc/pagetypeinfo") fd, err := os.Open(pagePath) if err != nil { diff --git a/metricbeat/module/linux/pageinfo/pageinfo_test.go b/metricbeat/module/linux/pageinfo/pageinfo_test.go index e16c38fc6016..272e79cb0a70 100644 --- a/metricbeat/module/linux/pageinfo/pageinfo_test.go +++ b/metricbeat/module/linux/pageinfo/pageinfo_test.go @@ -24,6 +24,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestData(t *testing.T) { diff --git a/metricbeat/module/linux/pressure/pressure.go b/metricbeat/module/linux/pressure/pressure.go index 9a0e90c1839c..f352cc04843e 100644 --- a/metricbeat/module/linux/pressure/pressure.go +++ b/metricbeat/module/linux/pressure/pressure.go @@ -19,7 +19,6 @@ package pressure import ( "fmt" - "path/filepath" "runtime" "github.com/pkg/errors" @@ -27,8 +26,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/linux" ) const ( @@ -50,8 +49,7 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - fs string - procfs procfs.FS + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -63,19 +61,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, fmt.Errorf("the %v/%v metricset is only supported on Linux", moduleName, metricsetName) } - sys := base.Module().(linux.LinuxModule) - hostfs := sys.GetHostFS() - - path := filepath.Join(hostfs, "proc") - procfs, err := procfs.NewFS(path) - if err != nil { - return nil, errors.Wrapf(err, "error creating new Host FS at %s", path) - } + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - fs: hostfs, - procfs: procfs, + mod: sys, }, nil } @@ -100,8 +90,13 @@ func fetchLinuxPSIStats(m *MetricSet) ([]common.MapStr, error) { resources := []string{"cpu", "memory", "io"} events := []common.MapStr{} + procfs, err := procfs.NewFS(m.mod.ResolveHostFS("/proc")) + if err != nil { + return nil, errors.Wrapf(err, "error creating new Host FS at %s", m.mod.ResolveHostFS("/proc")) + } + for _, resource := range resources { - psiMetric, err := m.procfs.PSIStatsForResource(resource) + psiMetric, err := procfs.PSIStatsForResource(resource) if err != nil { return nil, errors.Wrap(err, "check that /proc/pressure is available, and/or enabled") } diff --git a/metricbeat/module/linux/pressure/pressure_test.go b/metricbeat/module/linux/pressure/pressure_test.go index 098b9fcbe762..d6b737dc1efd 100644 --- a/metricbeat/module/linux/pressure/pressure_test.go +++ b/metricbeat/module/linux/pressure/pressure_test.go @@ -28,6 +28,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/linux" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/linux/rapl/rapl.go b/metricbeat/module/linux/rapl/rapl.go index f7d3cacf93c6..40a627f53f80 100644 --- a/metricbeat/module/linux/rapl/rapl.go +++ b/metricbeat/module/linux/rapl/rapl.go @@ -37,8 +37,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/linux" ) // init registers the MetricSet with the central registry as soon as the program @@ -83,16 +83,15 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, err } - sys := base.Module().(linux.LinuxModule) - hostfs := sys.GetHostFS() - CPUList, err := getMSRCPUs(hostfs) + sys := base.Module().(resolve.Resolver) + CPUList, err := getMSRCPUs(sys) if err != nil { return nil, errors.Wrap(err, "error getting list of CPUs to query") } // check to see if msr-safe is installed if config.UseMSRSafe { - queryPath := filepath.Join(hostfs, "/dev/cpu/", fmt.Sprint(CPUList[0]), "msr_safe") + queryPath := sys.ResolveHostFS(filepath.Join("/dev/cpu/", fmt.Sprint(CPUList[0]), "msr_safe")) _, err := os.Stat(queryPath) if errors.Is(err, os.ErrNotExist) { return nil, errors.New("no msr_safe device found. Is the kernel module loaded?") @@ -112,7 +111,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { handlers := map[int]rapl.RAPLHandler{} for _, cpu := range CPUList { - formatPath := filepath.Join(hostfs, "/dev/cpu/%d") + formatPath := sys.ResolveHostFS("/dev/cpu/%d") if config.UseMSRSafe { formatPath = filepath.Join(formatPath, "/msr_safe") } else { @@ -205,7 +204,7 @@ func (m *MetricSet) updatePower() map[int]map[rapl.RAPLDomain]energyUsage { // getMSRCPUs forms a list of CPU cores to query // For multi-processor systems, this will be more than 1. -func getMSRCPUs(hostfs string) ([]int, error) { +func getMSRCPUs(hostfs resolve.Resolver) ([]int, error) { CPUs, err := topoPkgCPUMap(hostfs) if err != nil { return nil, errors.Wrap(err, "error fetching CPU topology") @@ -227,12 +226,12 @@ func getMSRCPUs(hostfs string) ([]int, error) { //it is, however, the simplest way to do this. The intel power gadget iterates through each CPU using affinity masks, and runs `cpuid` in a loop to //figure things out //This uses /sys/devices/system/cpu/cpu*/topology/physical_package_id, which is what lscpu does. I *think* geopm does something similar to this. -func topoPkgCPUMap(hostfs string) (map[int][]int, error) { +func topoPkgCPUMap(hostfs resolve.Resolver) (map[int][]int, error) { sysdir := "/sys/devices/system/cpu/" cpuMap := make(map[int][]int) - files, err := ioutil.ReadDir(filepath.Join(hostfs, sysdir)) + files, err := ioutil.ReadDir(hostfs.ResolveHostFS(sysdir)) if err != nil { return nil, err } @@ -242,7 +241,7 @@ func topoPkgCPUMap(hostfs string) (map[int][]int, error) { for _, file := range files { if file.IsDir() && re.MatchString(file.Name()) { - fullPkg := filepath.Join(hostfs, sysdir, file.Name(), "/topology/physical_package_id") + fullPkg := hostfs.ResolveHostFS(filepath.Join(sysdir, file.Name(), "/topology/physical_package_id")) dat, err := ioutil.ReadFile(fullPkg) if err != nil { return nil, errors.Wrapf(err, "error reading file %s", fullPkg) diff --git a/metricbeat/module/linux/rapl/rapl_test.go b/metricbeat/module/linux/rapl/rapl_test.go index d51fbedb1054..43568a5031a2 100644 --- a/metricbeat/module/linux/rapl/rapl_test.go +++ b/metricbeat/module/linux/rapl/rapl_test.go @@ -24,6 +24,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) // func TestData(t *testing.T) { @@ -47,8 +49,7 @@ import ( // } func TestTopo(t *testing.T) { - hostfs := "./testdata/" - + hostfs := resolve.NewTestResolver("./testdata") cpus, err := topoPkgCPUMap(hostfs) assert.NoError(t, err) good := map[int][]int{ diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml index 929f585e7d92..974df87cb0bc 100644 --- a/metricbeat/module/system/_meta/config.reference.yml +++ b/metricbeat/module/system/_meta/config.reference.yml @@ -20,7 +20,7 @@ processes: ['.*'] # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container - #system.hostfs: "/hostfs" + #hostfs: "/hostfs" # Configure the metric types that are included by these metricsets. cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. diff --git a/metricbeat/module/system/_meta/config.yml b/metricbeat/module/system/_meta/config.yml index d13c0ca46837..4f3a66dcfa90 100644 --- a/metricbeat/module/system/_meta/config.yml +++ b/metricbeat/module/system/_meta/config.yml @@ -18,7 +18,7 @@ by_cpu: 5 # include top 5 processes by CPU by_memory: 5 # include top 5 processes by memory # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container -#system.hostfs: "/hostfs" +# hostfs: "/hostfs" - module: system period: 1m diff --git a/metricbeat/module/system/core/core.go b/metricbeat/module/system/core/core.go index 349d45b838f4..7d46bf95a7f4 100644 --- a/metricbeat/module/system/core/core.go +++ b/metricbeat/module/system/core/core.go @@ -23,10 +23,10 @@ package core import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" metrics "github.com/elastic/beats/v7/metricbeat/internal/metrics/cpu" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/metricbeat/module/system" ) func init() { @@ -57,11 +57,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { if config.CPUTicks != nil && *config.CPUTicks { config.Metrics = append(config.Metrics, "ticks") } - sys := base.Module().(system.SystemModule) + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, opts: opts, - cores: metrics.New(sys.GetHostFS()), + cores: metrics.New(sys), }, nil } diff --git a/metricbeat/module/system/core/core_test.go b/metricbeat/module/system/core/core_test.go index dd1b2d87d365..d10bd6f2e444 100644 --- a/metricbeat/module/system/core/core_test.go +++ b/metricbeat/module/system/core/core_test.go @@ -28,6 +28,7 @@ import ( mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" "github.com/elastic/beats/v7/metricbeat/mb/testing/flags" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/cpu/cpu.go b/metricbeat/module/system/cpu/cpu.go index b530dab08794..704cc73b16c0 100644 --- a/metricbeat/module/system/cpu/cpu.go +++ b/metricbeat/module/system/cpu/cpu.go @@ -24,10 +24,10 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" metrics "github.com/elastic/beats/v7/metricbeat/internal/metrics/cpu" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/metricbeat/module/system" ) func init() { @@ -59,11 +59,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { if config.CPUTicks != nil && *config.CPUTicks { config.Metrics = append(config.Metrics, "ticks") } - sys := base.Module().(system.SystemModule) + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, opts: opts, - cpu: metrics.New(sys.GetHostFS()), + cpu: metrics.New(sys), }, nil } diff --git a/metricbeat/module/system/cpu/cpu_test.go b/metricbeat/module/system/cpu/cpu_test.go index cbdf3e8b0a9b..980f1b097fb6 100644 --- a/metricbeat/module/system/cpu/cpu_test.go +++ b/metricbeat/module/system/cpu/cpu_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/diskio/diskio_test.go b/metricbeat/module/system/diskio/diskio_test.go index 6aaf55e4e8ce..57a3fd34a5d9 100644 --- a/metricbeat/module/system/diskio/diskio_test.go +++ b/metricbeat/module/system/diskio/diskio_test.go @@ -22,37 +22,22 @@ package diskio import ( - "os" - "path/filepath" "testing" "time" - "github.com/stretchr/testify/assert" - - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/metricbeat/internal/sysinit" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" -) -func setHostfs(pathString string) { - os.Setenv("HOST_PROC", filepath.Join(pathString, "proc")) - path := paths.Path{ - Hostfs: pathString, - } - paths.InitPaths(&path) -} + "github.com/stretchr/testify/assert" +) func TestDataNameFilter(t *testing.T) { - oldFS := paths.Paths.Hostfs - setHostfs("_meta/testdata") - - defer func() { - setHostfs(oldFS) - }() - + sysinit.InitModule("./_meta/testdata") conf := map[string]interface{}{ "module": "system", "metricsets": []string{"diskio"}, - "diskio.include_devices": []string{"sda", "sda1", "sda2"}, + "diskio.include_devices": []string{"sdb", "sdb1", "sdb2"}, + "hostfs": "./_meta/testdata", } f := mbtest.NewReportingMetricSetV2Error(t, conf) @@ -62,16 +47,10 @@ func TestDataNameFilter(t *testing.T) { } func TestDataEmptyFilter(t *testing.T) { - oldFS := paths.Paths.Hostfs - setHostfs("_meta/testdata") - - defer func() { - setHostfs(oldFS) - }() - conf := map[string]interface{}{ "module": "system", "metricsets": []string{"diskio"}, + "hostfs": "./_meta/testdata", } f := mbtest.NewReportingMetricSetV2Error(t, conf) diff --git a/metricbeat/module/system/entropy/entropy.go b/metricbeat/module/system/entropy/entropy.go index f42ac41bac5b..e3ced9ea3078 100644 --- a/metricbeat/module/system/entropy/entropy.go +++ b/metricbeat/module/system/entropy/entropy.go @@ -22,8 +22,6 @@ package entropy import ( "io/ioutil" - "path" - "path/filepath" "strconv" "strings" @@ -31,8 +29,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" - "github.com/elastic/beats/v7/metricbeat/module/system" ) // init registers the MetricSet with the central registry as soon as the program @@ -49,7 +47,7 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - randomPath string + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -57,12 +55,11 @@ type MetricSet struct { func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The system entropy metricset is beta.") - sys := base.Module().(system.SystemModule) - totalPath := filepath.Join(sys.GetHostFS(), "/proc/sys/kernel/random") + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - randomPath: totalPath, + mod: sys, }, nil } @@ -70,11 +67,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - entropy, err := getEntropyData(path.Join(m.randomPath, "entropy_avail")) + entropy, err := getEntropyData(m.mod.ResolveHostFS("/proc/sys/kernel/random/entropy_avail")) if err != nil { return errors.Wrap(err, "error getting entropy") } - poolsize, err := getEntropyData(path.Join(m.randomPath, "poolsize")) + poolsize, err := getEntropyData(m.mod.ResolveHostFS("/proc/sys/kernel/random/poolsize")) if err != nil { return errors.Wrap(err, "error getting poolsize") } diff --git a/metricbeat/module/system/entropy/entropy_test.go b/metricbeat/module/system/entropy/entropy_test.go index 27142581eb01..131affbb41ad 100644 --- a/metricbeat/module/system/entropy/entropy_test.go +++ b/metricbeat/module/system/entropy/entropy_test.go @@ -25,19 +25,12 @@ import ( "github.com/stretchr/testify/assert" - "github.com/elastic/beats/v7/libbeat/paths" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestData(t *testing.T) { - testPath := paths.Path{ - Hostfs: "./_meta/testdata", - } - if err := paths.InitPaths(&testPath); err != nil { - t.Errorf("error setting default paths: %+v", err) - t.FailNow() - } f := mbtest.NewReportingMetricSetV2Error(t, getConfig()) err := mbtest.WriteEventsReporterV2Error(f, t, ".") if err != nil { @@ -46,14 +39,7 @@ func TestData(t *testing.T) { } func TestFetch(t *testing.T) { - testPath := paths.Path{ - Hostfs: "./_meta/testdata", - } - if err := paths.InitPaths(&testPath); err != nil { - t.Errorf("error setting default paths: %+v", err) - t.FailNow() - } f := mbtest.NewReportingMetricSetV2Error(t, getConfig()) events, errs := mbtest.ReportingFetchV2Error(f) @@ -68,5 +54,6 @@ func getConfig() map[string]interface{} { return map[string]interface{}{ "module": "system", "metricsets": []string{"entropy"}, + "hostfs": "./_meta/testdata", } } diff --git a/metricbeat/module/system/filesystem/filesystem.go b/metricbeat/module/system/filesystem/filesystem.go index 98633fd43450..9d157f76ec59 100644 --- a/metricbeat/module/system/filesystem/filesystem.go +++ b/metricbeat/module/system/filesystem/filesystem.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" @@ -50,9 +51,9 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { if err := base.Module().UnpackConfig(&config); err != nil { return nil, err } - + sys := base.Module().(resolve.Resolver) if config.IgnoreTypes == nil { - config.IgnoreTypes = DefaultIgnoredTypes() + config.IgnoreTypes = DefaultIgnoredTypes(sys) } if len(config.IgnoreTypes) > 0 { logp.Info("Ignoring filesystem types: %s", strings.Join(config.IgnoreTypes, ", ")) diff --git a/metricbeat/module/system/filesystem/filesystem_test.go b/metricbeat/module/system/filesystem/filesystem_test.go index bc3ba234469e..a0ac2cf97ed9 100644 --- a/metricbeat/module/system/filesystem/filesystem_test.go +++ b/metricbeat/module/system/filesystem/filesystem_test.go @@ -25,7 +25,9 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { @@ -49,7 +51,7 @@ func TestData(t *testing.T) { } func getConfig() map[string]interface{} { - ignoreTypes := append(DefaultIgnoredTypes(), "fuse.lxcfs", "fuse.gvfsd-fuse", "nsfs", "squashfs") + ignoreTypes := append(DefaultIgnoredTypes(resolve.NewTestResolver("")), "fuse.lxcfs", "fuse.gvfsd-fuse", "nsfs", "squashfs") return map[string]interface{}{ "module": "system", "metricsets": []string{"filesystem"}, diff --git a/metricbeat/module/system/filesystem/helper.go b/metricbeat/module/system/filesystem/helper.go index 29b68a34d4d2..ec4dd1be14ce 100644 --- a/metricbeat/module/system/filesystem/helper.go +++ b/metricbeat/module/system/filesystem/helper.go @@ -30,7 +30,7 @@ import ( "runtime" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" sigar "github.com/elastic/gosigar" ) @@ -186,10 +186,10 @@ func BuildTypeFilter(ignoreType ...string) Predicate { // DefaultIgnoredTypes tries to guess a sane list of filesystem types that // could be ignored in the running system -func DefaultIgnoredTypes() (types []string) { +func DefaultIgnoredTypes(sys resolve.Resolver) (types []string) { // If /proc/filesystems exist, default ignored types are all marked // as nodev - fsListFile := paths.Resolve(paths.Hostfs, "/proc/filesystems") + fsListFile := sys.ResolveHostFS("/proc/filesystems") if f, err := os.Open(fsListFile); err == nil { scanner := bufio.NewScanner(f) for scanner.Scan() { diff --git a/metricbeat/module/system/fsstat/fsstat.go b/metricbeat/module/system/fsstat/fsstat.go index 6a963dbaf6f5..ff404cdcceee 100644 --- a/metricbeat/module/system/fsstat/fsstat.go +++ b/metricbeat/module/system/fsstat/fsstat.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" "github.com/elastic/beats/v7/metricbeat/module/system/filesystem" @@ -50,9 +51,9 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { if err := base.Module().UnpackConfig(&config); err != nil { return nil, err } - + sys := base.Module().(resolve.Resolver) if config.IgnoreTypes == nil { - config.IgnoreTypes = filesystem.DefaultIgnoredTypes() + config.IgnoreTypes = filesystem.DefaultIgnoredTypes(sys) } if len(config.IgnoreTypes) > 0 { base.Logger().Info("Ignoring filesystem types: %s", strings.Join(config.IgnoreTypes, ", ")) diff --git a/metricbeat/module/system/fsstat/fsstat_test.go b/metricbeat/module/system/fsstat/fsstat_test.go index acfc08b12ec4..e64fc24c265d 100644 --- a/metricbeat/module/system/fsstat/fsstat_test.go +++ b/metricbeat/module/system/fsstat/fsstat_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/load/load_test.go b/metricbeat/module/system/load/load_test.go index 208f75e21576..208178307bf7 100644 --- a/metricbeat/module/system/load/load_test.go +++ b/metricbeat/module/system/load/load_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/memory/memory.go b/metricbeat/module/system/memory/memory.go index af4dbb7f9d2b..9ff4a777aadc 100644 --- a/metricbeat/module/system/memory/memory.go +++ b/metricbeat/module/system/memory/memory.go @@ -25,10 +25,10 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/transform/typeconv" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" metrics "github.com/elastic/beats/v7/metricbeat/internal/metrics/memory" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/metricbeat/module/system" ) func init() { @@ -41,19 +41,19 @@ func init() { // MetricSet for fetching system memory metrics. type MetricSet struct { mb.BaseMetricSet - mod system.SystemModule + mod resolve.Resolver } // New is a mb.MetricSetFactory that returns a memory.MetricSet. func New(base mb.BaseMetricSet) (mb.MetricSet, error) { - sys := base.Module().(system.SystemModule) + sys := base.Module().(resolve.Resolver) return &MetricSet{BaseMetricSet: base, mod: sys}, nil } // Fetch fetches memory metrics from the OS. func (m *MetricSet) Fetch(r mb.ReporterV2) error { - eventRaw, err := metrics.Get(m.mod.GetHostFS()) + eventRaw, err := metrics.Get(m.mod) if err != nil { return errors.Wrap(err, "error fetching memory metrics") } diff --git a/metricbeat/module/system/memory/memory_test.go b/metricbeat/module/system/memory/memory_test.go index 4a5da887ea4a..7d7a11a1263c 100644 --- a/metricbeat/module/system/memory/memory_test.go +++ b/metricbeat/module/system/memory/memory_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/network/network_test.go b/metricbeat/module/system/network/network_test.go index d7fda561b15d..712cce2c44b6 100644 --- a/metricbeat/module/system/network/network_test.go +++ b/metricbeat/module/system/network/network_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/network_summary/network_summary_test.go b/metricbeat/module/system/network_summary/network_summary_test.go index bac14f519217..cb0d44ce3447 100644 --- a/metricbeat/module/system/network_summary/network_summary_test.go +++ b/metricbeat/module/system/network_summary/network_summary_test.go @@ -25,6 +25,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/metric/system/network" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" "github.com/elastic/go-sysinfo/types" ) diff --git a/metricbeat/module/system/process/_meta/data.json b/metricbeat/module/system/process/_meta/data.json index 54c24ddd7f7a..28bd98f6af1d 100644 --- a/metricbeat/module/system/process/_meta/data.json +++ b/metricbeat/module/system/process/_meta/data.json @@ -11,26 +11,32 @@ }, "process": { "args": [ - "/usr/lib/systemd/systemd", - "rhgb", - "--switched-root", - "--system", - "--deserialize", - "31" + "/home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/node", + "/home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/out/vs/server/main.js", + "--start-server", + "--host=127.0.0.1", + "--enable-remote-auto-shutdown", + "--port=0", + "--connection-secret", + "/home/alexk/.vscode-server/.7f6ab5485bbc008386c4386d08766667e155244e.token" ], - "command_line": "/usr/lib/systemd/systemd rhgb --switched-root --system --deserialize 31", + "command_line": "/home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/node /home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/out/vs/server/main.js --start-server --host=127.0.0.1 --enable-remote-auto-shutdown --port=0 --connection-secret /home/alexk/.vscode-server/.7f6ab5485bbc008386c4386d08766667e155244e.token", "cpu": { "pct": 0, - "start_time": "2021-09-29T22:29:55.000Z" + "start_time": "2021-11-15T05:02:43.000Z" }, + "executable": "/home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/node", "memory": { - "pct": 0.0003 + "pct": 0.001 }, - "name": "systemd", - "pgid": 1, - "pid": 1, - "ppid": 0, - "state": "sleeping" + "name": "node", + "parent": { + "pid": 932570 + }, + "pgid": 932516, + "pid": 932578, + "state": "sleeping", + "working_directory": "/home/alexk" }, "service": { "type": "system" @@ -40,8 +46,8 @@ "cgroup": { "cgroups_version": 2, "cpu": { - "id": "init.scope", - "path": "/init.scope", + "id": "session-6.scope", + "path": "/user.slice/user-1000.slice/session-6.scope", "pressure": { "full": { "10": { @@ -53,7 +59,7 @@ "60": { "pct": 0 }, - "total": 50432 + "total": 3879840 }, "some": { "10": { @@ -65,101 +71,36 @@ "60": { "pct": 0 }, - "total": 50879 + "total": 3899569 } }, "stats": { - "periods": 0, "system": { "norm": { "pct": 0 }, - "ns": 2293648, + "ns": 69699800, "pct": 0 }, - "throttled": { - "periods": 0, - "us": 0 - }, "usage": { "norm": { "pct": 0 }, - "ns": 4958009, + "ns": 311034237, "pct": 0 }, "user": { "norm": { "pct": 0 }, - "ns": 2664361, + "ns": 241334437, "pct": 0 } } }, - "id": "init.scope", - "io": { - "id": "init.scope", - "path": "/init.scope", - "pressure": { - "full": { - "10": { - "pct": 0 - }, - "300": { - "pct": 0 - }, - "60": { - "pct": 0 - }, - "total": 2393048 - }, - "some": { - "10": { - "pct": 0 - }, - "300": { - "pct": 0 - }, - "60": { - "pct": 0 - }, - "total": 2402448 - } - }, - "stats": { - "dm-0": { - "discarded": { - "bytes": 0, - "ios": 0 - }, - "read": { - "bytes": 8192, - "ios": 2 - }, - "write": { - "bytes": 0, - "ios": 0 - } - }, - "sda": { - "discarded": { - "bytes": 0, - "ios": 0 - }, - "read": { - "bytes": 8192, - "ios": 2 - }, - "write": { - "bytes": 0, - "ios": 0 - } - } - } - }, + "id": "session-6.scope", "memory": { - "id": "init.scope", + "id": "session-6.scope", "mem": { "events": { "high": 0, @@ -172,7 +113,7 @@ "bytes": 0 }, "usage": { - "bytes": 45223936 + "bytes": 81653760 } }, "memsw": { @@ -188,28 +129,28 @@ "bytes": 0 } }, - "path": "/init.scope", + "path": "/user.slice/user-1000.slice/session-6.scope", "stats": { "active_anon": { - "bytes": 24576 + "bytes": 12288 }, "active_file": { - "bytes": 21671936 + "bytes": 507904 }, "anon": { - "bytes": 8499200 + "bytes": 42983424 }, "anon_thp": { "bytes": 0 }, "file": { - "bytes": 30720000 + "bytes": 34598912 }, "file_dirty": { "bytes": 0 }, "file_mapped": { - "bytes": 14823424 + "bytes": 28467200 }, "file_thp": { "bytes": 0 @@ -219,43 +160,43 @@ }, "htp_collapse_alloc": 0, "inactive_anon": { - "bytes": 8503296 + "bytes": 42967040 }, "inactive_file": { - "bytes": 9019392 + "bytes": 34091008 }, "kernel_stack": { - "bytes": 442368 + "bytes": 376832 }, - "major_page_faults": 169, - "page_activate": 5454, + "major_page_faults": 289, + "page_activate": 135, "page_deactivate": 0, - "page_faults": 105959, + "page_faults": 766278, "page_lazy_free": 0, "page_lazy_freed": 0, "page_refill": 0, "page_scan": 0, "page_steal": 0, "page_tables": { - "bytes": 102400 + "bytes": 2310144 }, "per_cpu": { - "bytes": 36288 + "bytes": 0 }, "shmem": { - "bytes": 28672 + "bytes": 0 }, "shmem_thp": { "bytes": 0 }, "slab": { - "bytes": 5320160 + "bytes": 766496 }, "slab_reclaimable": { - "bytes": 4626072 + "bytes": 298512 }, "slab_unreclaimable": { - "bytes": 694088 + "bytes": 467984 }, "sock": { "bytes": 0 @@ -276,31 +217,38 @@ "workingset_restore_file": 0 } }, - "path": "/init.scope" + "path": "/user.slice/user-1000.slice/session-6.scope" }, - "cmdline": "/usr/lib/systemd/systemd rhgb --switched-root --system --deserialize 31", + "cmdline": "/home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/node /home/alexk/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e/out/vs/server/main.js --start-server --host=127.0.0.1 --enable-remote-auto-shutdown --port=0 --connection-secret /home/alexk/.vscode-server/.7f6ab5485bbc008386c4386d08766667e155244e.token", "cpu": { - "start_time": "2021-09-29T22:29:55.000Z", + "start_time": "2021-11-15T05:02:43.000Z", "total": { "norm": { "pct": 0 }, "pct": 0, - "value": 4640 + "value": 226260 } }, + "fd": { + "limit": { + "hard": 524288, + "soft": 524288 + }, + "open": 23 + }, "memory": { "rss": { - "bytes": 18153472, - "pct": 0.0003 + "bytes": 64372736, + "pct": 0.001 }, - "share": 11046912, - "size": 181272576 + "share": 32768000, + "size": 948490240 }, "state": "sleeping" } }, "user": { - "name": "root" + "name": "alexk" } } \ No newline at end of file diff --git a/metricbeat/module/system/process/_meta/docs.asciidoc b/metricbeat/module/system/process/_meta/docs.asciidoc index af9223c97619..6263b1948180 100644 --- a/metricbeat/module/system/process/_meta/docs.asciidoc +++ b/metricbeat/module/system/process/_meta/docs.asciidoc @@ -113,4 +113,4 @@ A workaround is also required if metricbeat is running inside docker on a hybrid Within docker, metricbeat won't be able to see any V2 cgroups components. If you wish to monitor cgroups V2 from within docker on a hybrid system, you must mount the unified sysfs hierarchy (usually `/sys/fs/cgroups/unified`) inside the container, and then use -`--system.hostfs` to specify the filesystem root within the container. \ No newline at end of file +`system.hostfs` to specify the filesystem root within the container. \ No newline at end of file diff --git a/metricbeat/module/system/process/process.go b/metricbeat/module/system/process/process.go index 72eefa19d54c..a90538e4f6c3 100644 --- a/metricbeat/module/system/process/process.go +++ b/metricbeat/module/system/process/process.go @@ -30,9 +30,9 @@ import ( "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/metric/system/cgroup" "github.com/elastic/beats/v7/libbeat/metric/system/process" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/metricbeat/module/system" ) var debugf = logp.MakeDebug("system.process") @@ -59,13 +59,13 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, err } - sys := base.Module().(system.SystemModule) + sys := base.Module().(resolve.Resolver) enableCgroups := false if runtime.GOOS == "linux" { if config.Cgroups == nil || *config.Cgroups { enableCgroups = true - debugf("process cgroup data collection is enabled, using hostfs='%v'", sys.GetHostFS()) + debugf("process cgroup data collection is enabled, using hostfs='%v'", sys.ResolveHostFS("")) } } @@ -79,7 +79,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { IncludeTop: config.IncludeTop, EnableCgroups: enableCgroups, CgroupOpts: cgroup.ReaderOptions{ - RootfsMountpoint: sys.GetHostFS(), + RootfsMountpoint: sys, IgnoreRootCgroups: true, }, }, @@ -87,7 +87,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { } // If hostfs is set, we may not want to force the hierarchy override, as the user could be expecting a custom path. - if len(sys.GetHostFS()) < 2 { + if !sys.IsSet() { override, isset := os.LookupEnv("LIBBEAT_MONITORING_CGROUPS_HIERARCHY_OVERRIDE") if isset { m.stats.CgroupOpts.CgroupsHierarchyOverride = override diff --git a/metricbeat/module/system/process/process_test.go b/metricbeat/module/system/process/process_test.go index 0a585141cf4d..b1fea79c1548 100644 --- a/metricbeat/module/system/process/process_test.go +++ b/metricbeat/module/system/process/process_test.go @@ -29,6 +29,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestFetch(t *testing.T) { diff --git a/metricbeat/module/system/process_summary/process_summary_test.go b/metricbeat/module/system/process_summary/process_summary_test.go index 22bdf2ae69f8..9eaa85dc86d9 100644 --- a/metricbeat/module/system/process_summary/process_summary_test.go +++ b/metricbeat/module/system/process_summary/process_summary_test.go @@ -29,6 +29,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestData(t *testing.T) { diff --git a/metricbeat/module/system/raid/_meta/docs.asciidoc b/metricbeat/module/system/raid/_meta/docs.asciidoc index e8465147e51d..91528bea99d1 100644 --- a/metricbeat/module/system/raid/_meta/docs.asciidoc +++ b/metricbeat/module/system/raid/_meta/docs.asciidoc @@ -4,4 +4,3 @@ This metricset is available on: - Linux -The config option `raid.mount_point:` can be used to configure the location of the raid metadata. If running this metricset inside a container, you will need to mount `/sys/block` inside the container under the path specified by `--system.hostfs` diff --git a/metricbeat/module/system/raid/blockinfo/getdev.go b/metricbeat/module/system/raid/blockinfo/getdev.go index 457a816c8bed..460b46d60d38 100644 --- a/metricbeat/module/system/raid/blockinfo/getdev.go +++ b/metricbeat/module/system/raid/blockinfo/getdev.go @@ -46,7 +46,7 @@ func ListAll(path string) ([]MDDevice, error) { } if len(mds) == 0 { - return nil, fmt.Errorf("no matches from path %s,", path) + return nil, fmt.Errorf("no matches from path %s", path) } return mds, nil diff --git a/metricbeat/module/system/raid/raid.go b/metricbeat/module/system/raid/raid.go index 9af6e87a9a33..4f03d2e9db65 100644 --- a/metricbeat/module/system/raid/raid.go +++ b/metricbeat/module/system/raid/raid.go @@ -18,15 +18,12 @@ package raid import ( - "path/filepath" - "github.com/pkg/errors" - "github.com/prometheus/procfs" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/metricbeat/module/system" "github.com/elastic/beats/v7/metricbeat/module/system/raid/blockinfo" ) @@ -39,38 +36,17 @@ func init() { // MetricSet contains proc fs data. type MetricSet struct { mb.BaseMetricSet - fs procfs.FS - sysblock string + mod resolve.Resolver } // New creates a new instance of the raid metricset. func New(base mb.BaseMetricSet) (mb.MetricSet, error) { - // Additional configuration options - config := struct { - MountPoint string `config:"raid.mount_point"` - }{} - - if err := base.Module().UnpackConfig(&config); err != nil { - return nil, err - } - sys := base.Module().(system.SystemModule) - if config.MountPoint == "" { - config.MountPoint = sys.GetHostFS() - } - - mountPoint := filepath.Join(config.MountPoint, procfs.DefaultMountPoint) - fs, err := procfs.NewFS(mountPoint) - if err != nil { - return nil, err - } - - sysMountPoint := filepath.Join(config.MountPoint, "/sys/block") - + sys := base.Module().(resolve.Resolver) return &MetricSet{ BaseMetricSet: base, - fs: fs, - sysblock: sysMountPoint, + + mod: sys, }, nil } @@ -84,7 +60,7 @@ func blockto1024(b int64) int64 { // Fetch fetches one event for each device func (m *MetricSet) Fetch(r mb.ReporterV2) error { - devices, err := blockinfo.ListAll(m.sysblock) + devices, err := blockinfo.ListAll(m.mod.ResolveHostFS("/sys/block")) if err != nil { return errors.Wrap(err, "failed to parse sysfs") } diff --git a/metricbeat/module/system/raid/raid_test.go b/metricbeat/module/system/raid/raid_test.go index f1ebaa97270b..4c35394413af 100644 --- a/metricbeat/module/system/raid/raid_test.go +++ b/metricbeat/module/system/raid/raid_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestData(t *testing.T) { @@ -47,8 +48,8 @@ func TestFetch(t *testing.T) { func getConfig() map[string]interface{} { return map[string]interface{}{ - "module": "system", - "metricsets": []string{"raid"}, - "raid.mount_point": "./_meta/testdata", + "module": "system", + "metricsets": []string{"raid"}, + "hostfs": "./_meta/testdata", } } diff --git a/metricbeat/module/system/service/service_test.go b/metricbeat/module/system/service/service_test.go index 1875b4f87374..3aeba519bc96 100644 --- a/metricbeat/module/system/service/service_test.go +++ b/metricbeat/module/system/service/service_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/elastic/beats/v7/libbeat/common" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) var exampleUnits = []dbus.UnitStatus{ diff --git a/metricbeat/module/system/socket/socket.go b/metricbeat/module/system/socket/socket.go index 2e290bddaf2d..560e4aa78030 100644 --- a/metricbeat/module/system/socket/socket.go +++ b/metricbeat/module/system/socket/socket.go @@ -32,7 +32,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" sock "github.com/elastic/beats/v7/metricbeat/helper/socket" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" @@ -69,12 +69,13 @@ type MetricSet struct { // New creates a new instance of the MetricSet. New is responsible for unpacking // any MetricSet specific configuration options if there are any. func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + sys := base.Module().(resolve.Resolver) c := defaultConfig if err := base.Module().UnpackConfig(&c); err != nil { return nil, err } - ptable, err := sock.NewProcTable(paths.Resolve(paths.Hostfs, "/proc")) + ptable, err := sock.NewProcTable(sys.ResolveHostFS("/proc")) if err != nil { return nil, err } diff --git a/metricbeat/module/system/socket/socket_test.go b/metricbeat/module/system/socket/socket_test.go index 38d63c55026a..bd5c485806a2 100644 --- a/metricbeat/module/system/socket/socket_test.go +++ b/metricbeat/module/system/socket/socket_test.go @@ -35,6 +35,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" sock "github.com/elastic/beats/v7/metricbeat/helper/socket" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestData(t *testing.T) { diff --git a/metricbeat/module/system/socket_summary/socket_summary.go b/metricbeat/module/system/socket_summary/socket_summary.go index d34779ab345d..bdc89011f70e 100644 --- a/metricbeat/module/system/socket_summary/socket_summary.go +++ b/metricbeat/module/system/socket_summary/socket_summary.go @@ -24,6 +24,7 @@ import ( "github.com/shirou/gopsutil/net" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" "github.com/elastic/beats/v7/metricbeat/mb" ) @@ -45,12 +46,15 @@ func init() { type MetricSet struct { mb.BaseMetricSet sockstat string + mod resolve.Resolver } // New creates a new instance of the MetricSet. New is responsible for unpacking // any MetricSet specific configuration options if there are any. func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + sys := base.Module().(resolve.Resolver) return &MetricSet{ + mod: sys, BaseMetricSet: base, }, nil } @@ -155,7 +159,7 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) error { } stats := calculateConnStats(conns) - newStats, err := applyEnhancements(stats) + newStats, err := applyEnhancements(stats, m.mod) if err != nil { m.Logger().Debugf("error applying enhancements: %s", err) newStats = stats diff --git a/metricbeat/module/system/socket_summary/sockstat_linux.go b/metricbeat/module/system/socket_summary/sockstat_linux.go index 9aff1d6b002a..b66b8afb7f30 100644 --- a/metricbeat/module/system/socket_summary/sockstat_linux.go +++ b/metricbeat/module/system/socket_summary/sockstat_linux.go @@ -29,7 +29,7 @@ import ( "github.com/shirou/gopsutil/net" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) // SockStat contains data from /proc/net/sockstat @@ -61,8 +61,8 @@ type SockStat struct { } // applyEnhancements gets a list of platform-specific enhancements and apply them to our mapStr object. -func applyEnhancements(data common.MapStr) (common.MapStr, error) { - dir := paths.Resolve(paths.Hostfs, "/proc/net/sockstat") +func applyEnhancements(data common.MapStr, sys resolve.Resolver) (common.MapStr, error) { + dir := sys.ResolveHostFS("/proc/net/sockstat") pageSize := os.Getpagesize() stat, err := parseSockstat(dir) diff --git a/metricbeat/module/system/socket_summary/sockstat_other.go b/metricbeat/module/system/socket_summary/sockstat_other.go index 1df924647b8d..03832b40342b 100644 --- a/metricbeat/module/system/socket_summary/sockstat_other.go +++ b/metricbeat/module/system/socket_summary/sockstat_other.go @@ -24,11 +24,12 @@ import ( "github.com/shirou/gopsutil/net" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/metric/system/resolve" ) //a stub function for non-linux systems //get a list of platform-specific enhancements and apply them to our mapStr object. -func applyEnhancements(data common.MapStr) (common.MapStr, error) { +func applyEnhancements(data common.MapStr, sys resolve.Resolver) (common.MapStr, error) { return data, nil } diff --git a/metricbeat/module/system/system.go b/metricbeat/module/system/system.go index dd1e514c60de..e78cac590784 100644 --- a/metricbeat/module/system/system.go +++ b/metricbeat/module/system/system.go @@ -20,9 +20,7 @@ package system import ( "sync" - "github.com/elastic/beats/v7/libbeat/common/fleetmode" - "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/metricbeat/internal/sysinit" "github.com/elastic/beats/v7/metricbeat/mb" ) @@ -30,57 +28,7 @@ var once sync.Once func init() { // Register the ModuleFactory function for the "system" module. - if err := mb.Registry.AddModule("system", NewModule); err != nil { + if err := mb.Registry.AddModule("system", sysinit.InitSystemModule); err != nil { panic(err) } } - -type HostFSConfig struct { - HostFS string `config:"system.hostfs"` -} - -// Module represents the system module -type Module struct { - mb.BaseModule - HostFS string -} - -type SystemModule interface { - GetHostFS() string -} - -func NewModule(base mb.BaseModule) (mb.Module, error) { - var hostfs string - - // If this is fleet, ignore the global path, as its not being set. - // This is a temporary hack - if fleetmode.Enabled() { - partialConfig := HostFSConfig{} - base.UnpackConfig(&partialConfig) - - if partialConfig.HostFS != "" { - hostfs = partialConfig.HostFS - } else { - hostfs = "/" - } - - logp.Info("In Fleet, using HostFS: %s", hostfs) - } else { - hostfs = paths.Paths.Hostfs - } - - once.Do(func() { - initModule(hostfs) - }) - - // set the main Path, - if fleetmode.Enabled() && len(paths.Paths.Hostfs) < 2 { - paths.Paths.Hostfs = hostfs - } - - return &Module{BaseModule: base, HostFS: hostfs}, nil -} - -func (m Module) GetHostFS() string { - return m.HostFS -} diff --git a/metricbeat/module/system/uptime/uptime_test.go b/metricbeat/module/system/uptime/uptime_test.go index d1ae484cac66..9969cea5f322 100644 --- a/metricbeat/module/system/uptime/uptime_test.go +++ b/metricbeat/module/system/uptime/uptime_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/metricbeat/module/system" ) func TestData(t *testing.T) { diff --git a/metricbeat/modules.d/system.yml b/metricbeat/modules.d/system.yml index f3f929e8f584..3c511e77439d 100644 --- a/metricbeat/modules.d/system.yml +++ b/metricbeat/modules.d/system.yml @@ -21,7 +21,7 @@ by_cpu: 5 # include top 5 processes by CPU by_memory: 5 # include top 5 processes by memory # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container -#system.hostfs: "/hostfs" +# hostfs: "/hostfs" - module: system period: 1m diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index f219b056d099..c89b9288c472 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -80,7 +80,7 @@ metricbeat.modules: processes: ['.*'] # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container - #system.hostfs: "/hostfs" + #hostfs: "/hostfs" # Configure the metric types that are included by these metricsets. cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. From 4de6952d6cb270b4a1fee104db2e3cd040dee4e5 Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Thu, 9 Dec 2021 18:01:56 -0500 Subject: [PATCH 072/172] [automation] update elastic stack version for testing 8.1.0-30a394f1 (#29275) * [Automation] Update elastic stack version to 8.1.0-30a394f1 for testing * Reconfigure compilation rate * Update golden files * Skip failing test Co-authored-by: apmmachine Co-authored-by: Jaime Soriano Pastor Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../audit/test/test-audit-761.log-expected.json | 2 +- libbeat/tests/system/test_dashboard.py | 1 + testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 10 ++++------ .../module/cisco/asa/test/sample.log-expected.json | 4 ++-- .../module/cisco/ftd/test/sample.log-expected.json | 4 ++-- .../panw/panos/test/global_protect.log-expected.json | 6 +++--- .../panos/test/traffic_nanos_time.log-expected.json | 6 +++--- .../module/sophos/utm/test/generated.log-expected.json | 2 +- .../module/sophos/xg/test/event.log-expected.json | 6 +++--- 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/filebeat/module/elasticsearch/audit/test/test-audit-761.log-expected.json b/filebeat/module/elasticsearch/audit/test/test-audit-761.log-expected.json index 7b6233381c9a..372a7d9f667a 100644 --- a/filebeat/module/elasticsearch/audit/test/test-audit-761.log-expected.json +++ b/filebeat/module/elasticsearch/audit/test/test-audit-761.log-expected.json @@ -1,6 +1,6 @@ [ { - "@timestamp": "2020-04-01T13:21:06.725Z", + "@timestamp": "2020-04-01T09:21:06.725Z", "elasticsearch.audit.action": "indices:data/read/mget[shard]", "elasticsearch.audit.indices": [ ".logstash", diff --git a/libbeat/tests/system/test_dashboard.py b/libbeat/tests/system/test_dashboard.py index 338e832b0457..e02a644213e8 100644 --- a/libbeat/tests/system/test_dashboard.py +++ b/libbeat/tests/system/test_dashboard.py @@ -208,6 +208,7 @@ def test_dev_tool_export_dashboard_by_id_unknown_id(self): assert p.returncode != 0 + @unittest.skip("Failing test: https://github.com/elastic/beats/issues/29327") @unittest.skipUnless(INTEGRATION_TESTS, "integration test") @pytest.mark.tag('integration') def test_dev_tool_export_dashboard_by_id_from_space(self): diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index 2445bef87134..1e9a8d26e6ad 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0-2f347a19-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-30a394f1-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.0.0-2f347a19-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-30a394f1-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.0.0-2f347a19-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-30a394f1-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index c9215fe874bb..2f58702a9f1c 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0-2f347a19-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-30a394f1-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -14,10 +14,8 @@ services: - "transport.host=127.0.0.1" - "http.host=0.0.0.0" - "xpack.security.enabled=false" - - "script.context.template.max_compilations_rate=unlimited" - - "script.context.ingest.cache_max_size=2000" - - "script.context.processor_conditional.cache_max_size=2000" - - "script.context.template.cache_max_size=2000" + # We want something as unlimited compilation rate, but 'unlimited' is not valid. + - "script.max_compilations_rate=100000/1m" - "action.destructive_requires_name=false" # Disable geoip updates to prevent golden file test failures when the database # changes and prevent race conditions between tests and database updates. @@ -39,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.0.0-2f347a19-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-30a394f1-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json index fad5d0a80f37..65608c192ee3 100644 --- a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json @@ -102,7 +102,7 @@ ] }, { - "@timestamp": "2014-04-15T09:34:34.000-04:00", + "@timestamp": "2014-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1964,7 +1964,7 @@ ] }, { - "@timestamp": "2018-04-15T09:34:34.000-04:00", + "@timestamp": "2018-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", diff --git a/x-pack/filebeat/module/cisco/ftd/test/sample.log-expected.json b/x-pack/filebeat/module/cisco/ftd/test/sample.log-expected.json index 4d9798688477..5d1987b7ec6b 100644 --- a/x-pack/filebeat/module/cisco/ftd/test/sample.log-expected.json +++ b/x-pack/filebeat/module/cisco/ftd/test/sample.log-expected.json @@ -100,7 +100,7 @@ ] }, { - "@timestamp": "2014-04-15T09:34:34.000-04:00", + "@timestamp": "2014-04-15T11:34:34.000-02:00", "cisco.ftd.destination_interface": "outside", "cisco.ftd.message_id": "106100", "cisco.ftd.rule_name": "acl_in", @@ -1926,7 +1926,7 @@ ] }, { - "@timestamp": "2018-04-15T09:34:34.000-04:00", + "@timestamp": "2018-04-15T11:34:34.000-02:00", "cisco.ftd.destination_interface": "outside", "cisco.ftd.message_id": "106100", "cisco.ftd.rule_name": "acl_in", diff --git a/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json b/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json index cf432b8604bc..39f636866bad 100644 --- a/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json +++ b/x-pack/filebeat/module/panw/panos/test/global_protect.log-expected.json @@ -495,7 +495,7 @@ "user.name": "maxmustermann" }, { - "@timestamp": "2021-10-22T16:10:05.000Z", + "@timestamp": "2021-10-22T14:10:05.000-02:00", "client.address": "10.2.2.2", "client.ip": "10.2.2.2", "client.nat.ip": "10.1.1.1", @@ -553,7 +553,7 @@ "user.name": "host" }, { - "@timestamp": "2021-11-09T21:45:14.000Z", + "@timestamp": "2021-11-09T19:45:14.000-02:00", "client.address": "10.4.4.4", "client.ip": "10.4.4.4", "client.nat.ip": "10.3.3.3", @@ -611,7 +611,7 @@ "user.name": "user" }, { - "@timestamp": "2021-11-09T21:45:14.000Z", + "@timestamp": "2021-11-09T19:45:14.000-02:00", "event.code": "gateway-tunnel-latency", "event.dataset": "panw.panos", "event.duration": 0, diff --git a/x-pack/filebeat/module/panw/panos/test/traffic_nanos_time.log-expected.json b/x-pack/filebeat/module/panw/panos/test/traffic_nanos_time.log-expected.json index 72ffebe6db72..052e18627569 100644 --- a/x-pack/filebeat/module/panw/panos/test/traffic_nanos_time.log-expected.json +++ b/x-pack/filebeat/module/panw/panos/test/traffic_nanos_time.log-expected.json @@ -1,6 +1,6 @@ [ { - "@timestamp": "2021-05-26T16:26:47.000Z", + "@timestamp": "2021-05-26T14:26:47.000-02:00", "client.bytes": 1696, "client.ip": "127.0.0.0", "client.nat.ip": "0.0.0.0", @@ -21,12 +21,12 @@ ], "event.dataset": "panw.panos", "event.duration": 1000000000, - "event.end": "2021-05-26T16:26:31.000Z", + "event.end": "2021-05-26T14:26:31.000-02:00", "event.kind": "event", "event.module": "panw", "event.original": "Oct 30 09:46:42 1,2021-05-26T16:27:07.000000Z,no-serial,TRAFFIC,end,9.1,2021-05-26T16:26:47.000000Z,127.0.0.0,127.0.0.1,0.0.0.0,0.0.0.0,intrazone-default,,,web-browsing,vsys1,untrust,untrust,ethernet1/1,ethernet1/1,Cortex Data Lake,,688290,1,35834,443,35834,20077,0x1400070,tcp,allow,7291,1696,5595,21,2021-05-26T16:26:30.000000Z,1,medium-risk,,620386,0x8800000000000000,US,SG,,14,7,tcp-fin,22,18,0,0,,GP cloud service,from-policy,,,0,,0,1970-01-01T00:00:00.000000Z,N/A,0,0,0,0,6a2f6161-88f2-4afc-8dd5-256bc4505a64,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,", "event.outcome": "success", - "event.start": "2021-05-26T16:26:30.000Z", + "event.start": "2021-05-26T14:26:30.000-02:00", "event.timezone": "-02:00", "event.type": [ "allowed", diff --git a/x-pack/filebeat/module/sophos/utm/test/generated.log-expected.json b/x-pack/filebeat/module/sophos/utm/test/generated.log-expected.json index a50b36685969..efb44a7b6668 100644 --- a/x-pack/filebeat/module/sophos/utm/test/generated.log-expected.json +++ b/x-pack/filebeat/module/sophos/utm/test/generated.log-expected.json @@ -3701,4 +3701,4 @@ "sophos.utm" ] } -] +] \ No newline at end of file diff --git a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json index 55e793967da6..179a156aaf58 100644 --- a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json @@ -775,7 +775,7 @@ "sophos.xg.branch_name": "Gaurav Patel", "sophos.xg.device": "SFW", "sophos.xg.device_name": "XG125w", - "sophos.xg.eventtime": "2017-03-16T12:56:01.000+02:00", + "sophos.xg.eventtime": "2017-03-16T08:56:01.000-02:00", "sophos.xg.log_component": "RED", "sophos.xg.log_subtype": "System", "sophos.xg.log_type": "Event", @@ -821,7 +821,7 @@ "sophos.xg.branch_name": "Gaurav Patel", "sophos.xg.device": "SFW", "sophos.xg.device_name": "XG125w", - "sophos.xg.eventtime": "2017-03-16T12:53:27.000+02:00", + "sophos.xg.eventtime": "2017-03-16T08:53:27.000-02:00", "sophos.xg.log_component": "RED", "sophos.xg.log_subtype": "System", "sophos.xg.log_type": "Event", @@ -867,7 +867,7 @@ "sophos.xg.branch_name": "NY", "sophos.xg.device": "SFW", "sophos.xg.device_name": "XG125w", - "sophos.xg.eventtime": "2017-03-16T12:46:26.000+02:00", + "sophos.xg.eventtime": "2017-03-16T08:46:26.000-02:00", "sophos.xg.log_component": "RED", "sophos.xg.log_subtype": "System", "sophos.xg.log_type": "Event", From 381309447096ac8e679cf53a4fc0f7692e4072ab Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Mon, 13 Dec 2021 02:06:39 -0500 Subject: [PATCH 073/172] [Automation] Update elastic stack version to 8.1.0-b6e7e1f3 for testing (#29387) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index 1e9a8d26e6ad..7ca185c80fe2 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-30a394f1-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b6e7e1f3-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-30a394f1-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-b6e7e1f3-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-30a394f1-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-b6e7e1f3-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 2f58702a9f1c..4cf5ba1db37e 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-30a394f1-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b6e7e1f3-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-30a394f1-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-b6e7e1f3-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 8b0f9d0a5a1d19c12b499df1cb2f114befbb39fb Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 13 Dec 2021 13:18:04 +0100 Subject: [PATCH 074/172] fix: check the activation script exists on Python virtual environments (#29265) (#29288) (cherry picked from commit 52e87f02c416fd5d13ab45ad74848fe70b310639) Co-authored-by: Ivan Fernandez Calvo --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 179d54f78550..9139d4ad34e7 100644 --- a/Makefile +++ b/Makefile @@ -184,7 +184,7 @@ notice: ## python-env : Sets up the virtual python environment. .PHONY: python-env python-env: - @test -d $(PYTHON_ENV) || ${PYTHON_EXE} -m venv $(VENV_PARAMS) $(PYTHON_ENV) + @test -f $(PYTHON_ENV)/bin/activate || ${PYTHON_EXE} -m venv $(VENV_PARAMS) $(PYTHON_ENV) @. $(PYTHON_ENV)/bin/activate; \ ${PYTHON_EXE} -m pip install -q --upgrade pip autopep8==1.5.4 pylint==2.4.4; \ find $(PYTHON_ENV) -type d -name dist-packages -exec sh -c "echo dist-packages > {}.pth" ';' From 2ef9595c22f17a5a373fd1eaccf2caf730a79f03 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 13 Dec 2021 16:03:59 +0100 Subject: [PATCH 075/172] Forward port 7.16.0 changelog to master (#29391) --- CHANGELOG.asciidoc | 165 ++++++++++++++++++++++++++++++++++ CHANGELOG.next.asciidoc | 106 ---------------------- libbeat/docs/release.asciidoc | 1 + 3 files changed, 166 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 8f0348c51b14..32d965a98b3e 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -17,6 +17,171 @@ Changes will be described in a later alpha / beta. === Beats version 8.0.0-alpha1 Changes will be described in a later alpha / beta. +[[release-notes-7.16.0]] +=== Beats version 7.16.0 +https://github.com/elastic/beats/compare/v7.15.2...v7.16.0[View commits] + +==== Breaking changes + +*Affecting all Beats* + +- Load index templates v2 (composable index templates) by default when talking to ES 7.16 or ES 8.x. Please note that you cannot load templates into Elasticsearch 7.8 or older with this default. To load templates to these ES version, set `setup.template.type` back to `legacy`. {pull}28538[28538] +- Previously, RE2 and thus Golang had a bug where `(|a)*` matched more characters than `(|a)+`. To stay consistent with PCRE, the bug was fixed. Configurations that rely on the old, buggy behaviour has to be adjusted. See more about Golang bug: https://github.com/golang/go/issues/46123 {pull}27543[27543] +- Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131] + +*Heartbeat* + +- Change behavior in case of duplicate monitor IDs in configs to be last monitor wins. {pull}29041[29041] + +*Metricbeat* + +- Align fields to Beats naming conventions in GCP module. {issue}27231[27231] {pull}27974[27974] + +*Functionbeat* + +- Support for Google Cloud Functions have been removed, as it has been in Beta for a long time and been broken for a few releases. Please use other tools provided by Elastic to fetch data from GCP (e.g. Filebeat). + +==== Bugfixes + +*Affecting all Beats* + +- Fix discovery of Nomad allocations with multiple events during startup. {pull}28700[28700] +- Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] +- Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] +- Fix `decode_json_processor` to always respect `add_error_key` {pull}29107[29107] +- Fix `add_labels` flattening of array values. {pull}29211[29211] +- Skip `add_kubernetes_metadata` processor when Kubernetes metadata are already present {pull}27689[27689] + +*Auditbeat* + +- Fix handling of root and relative paths {issue}24430[24430] {pull}28354[28354] +- Fix handling of long file names on Windows. {issue}25334[25334] {pull}28517[28517] +- System/socket dataset: Fix uninstallation of return kprobes. {issue}28608[28608] {pull}28609[28609] +- Fix auditbeat tracing struct decoding. {pull}28580[28580] + +*Filebeat* + +- Update indentation for azure filebeat configuration. {pull}26604[26604] +- Tolerate faults when Windows Event Log session is interrupted {issue}27947[27947] {pull}28191[28191] +- Add support for username in Cisco ASA security negotiation logs {pull}26975[26975] +- Relax time parsing and capture group and session type in Cisco ASA module {issue}24710[24710] {pull}28325[28325] +- Correctly track bytes read when max_bytes is exceeded. {issue}28317[28317] {pull}28352[28352] +- Fix parsing of apache log levels including numbers. {pull}28717[28717] +- Upgrade `azure-eventhub` SDK reference, contains potential checkpoint fixes. {pull}28919[28919] +- Revert usageDetails api version to 2019-01-01. {pull}28995[28995] +- Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] +- Fix `threatintel.misp` filters configuration. {issue}27970[27970] +- Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] + +*Heartbeat* + +- Fix broken seccomp filtering and improve security via `setcap` and `setuid` when running as root on linux in containers. {pull}27878[27878] +- Log browser `zip_url` download failures as `warn` instead of as `info`. {pull}28440[28440] +- Properly locate base stream in fleet configs. {pull}28455[28455] +- Stop logging params values. {pull}28774[28774] +- Remove accidentally included `cups` library in Docker images. {pull}28853[pull] +- Fix broken monitors with newer versions of image relying on `dup3`. {pull}28938[pull + +*Metricbeat* + +- `beat` module respects `basepath` config option. {pull}28162[28162] +- Fix list_docker.go {pull}28374[28374] +- Fix RDS metadata in Cloudwatch metricset. {pull}29106[29106] +- Errors should be thrown as errors. Metricsets inside metricbeat will now throw errors as the `error` log level. {pull}27804[27804] + +*Winlogbeat* + +- Tolerate faults when Windows Event Log session is interrupted {issue}27947[27947] {pull}28191[28191] +- Add ECS 1.9 new users fields {pull}26509[26509] +- Don't split hyphenated tokens {pull}28483[28483] +- Correctly handle AccessMask if it is an integer or list of masks. {pull}29016[29016] + +==== Added + +*Affecting all Beats* + +- Allow non-padded base64 data to be decoded by `decode_base64_field` {pull}27311[27311], {issue}27021[27021] +- The Kafka support library Sarama has been updated to 1.29.1. {pull}27717[27717] +- Kafka is now supported up to version 2.8.0. {pull}27720[27720] +- Add Huawei Cloud provider to add_cloud_metadata. {pull}27607[27607] +- Add default seccomp policy for linux arm64. {pull}27955[27955] +- Add cluster level add_kubernetes_metadata support for centralized enrichment {pull}24621[24621] +- Update cloud.google.com/go library. {pull}28229[28229] +- Add additional metadata to the root HTTP endpoint. {pull}28265[28265] +- Upgrade k8s.io/client-go library. {pull}28228[28228] +- Update ECS to 1.12.0. {pull}27770[27770] +- Fields mapped as `match_only_text` will automatically fallback to a `text` mapping when using Elasticsearch versions that do not support `match_only_text`. {pull}27770[27770] +- Do not load ML jobs to Elasticsearch 8.x from new Beats 7.x releases. {pull}27771[27771] +- Update kubernetes scheduler and controllermanager endpoints in elastic-agent-standalone-kubernetes.yaml with secure ports {pull}28675[28675] +- Add default seccomp policy for Linux arm64. {pull}27955[27955] +- Add `http.pprof.enabled` option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] +- Enable IMDSv2 support for `add_cloud_metadata` processor on AWS. {issue}22101[22101] {pull}28285[28285] + +*Filebeat* + +- Add `timezone` config option to the `decode_cef` processor. {issue}27232[27232] {pull}27727[27727] +- Add `timezone` config option to the `syslog` input. {pull}27727[27727] +- Added support for parsing syslog dates containing a leading 0 (e.g. `Sep 01`) rather than a space. {pull}27775[27775] +- Add base64 Encode functionality to `httpjson` input. {pull}27681[27681] +- Add `join` and `sprintf` functions to `httpjson` input. {pull}27735[27735] +- Improve memory usage of line reader of `log` and `filestream` input. {pull}27782[27782] +- Add `ignore_empty_value` flag to `httpjson` `split` processor. {pull}27880[27880] +- Add support for passing a prefix on S3 bucket list mode for AWS-S3 input {pull}28252[28252] {issue}27965[27965] +- Update Cisco ASA/FTD ingest pipeline grok/dissect patterns for multiple message IDs. {issue}26869[26869] {pull}26879[26879] +- Add write access to `url.value` from `request.transforms` in `httpjson` input. {pull}27937[27937] +- Add Base64 encoded HMAC and UUID template functions to `httpjson` input {pull}27873[27873] +- Release checkpoint module as GA. {pull}27814[27814] +- Make aws-cloudwatch input GA. {pull}28161[28161] +- Move processing to ingest node for AWS vpcflow fileset. {pull}28168[28168] +- Release zoom module as GA. {pull}28106[28106] +- Add support for secondary object attribute handling in ThreatIntel MISP module {pull}28124[28124] +- Azure signinlogs - Add support for ManagedIdentitySignInLogs, NonInteractiveUserSignInLogs, and ServicePrincipalSignInLogs. {issue}23653[23653] +- Add `base64Decode` and `base64DecodeNoPad` functions to `httpsjon` templates. {pull}28385[28385] +- Add 'early_limit' config option for Rate-Limiting `httpjson`. Default rate-limiting for Okta will start when remaining is `1`. {pull}28513[28513] +- Add latency config option for `aws-cloudwatch` input. {pull}28509[28509] +- Added proxy support to `threatintel/malwarebazaar`. {pull}28533[28533] +- Sophos UTM: Support logs containing hostname in Syslog header. {pull}28638[28638] +- Moving Oracle Filebeat module to GA. {pull}28754[28754] +- Add support in `aws-s3` input for S3 notification from SNS to SQS. {pull}28800[28800] +- Add support in `aws-s3` input for custom script parsing of S3 notifications. {pull}28946[28946] +- Improve error handling in `aws-s3` input for malformed S3 notifications. {issue}28828[28828] {pull}28946[28946] +- `filestream` and `log` inputs accept null (`\u0000`) as line terminator. {pull}28998[28998] + +*Heartbeat* + +- Support JSON expressions / validation of JSON arrays. {pull}28073[28073] +- Experimental `run once` mode. {pull}25972[25972] +- Add `keyword` multi-field mapping for `synthetics.step.name`. {pull}28452[28452] + +*Metricbeat* + +- Enable `journald` input type in Filebeat. {issue}7955[7955] {pull}27351[27351] +- Added a new beta `enterprisesearch` module for Elastic Enterprise Search {pull}27549[27549] +- Register additional name for `storage` metricset in the azure module. {pull}28447[28447] +- Update reference to gosigar pacakge for filesystem windows fix. {pull}28909[28909] +- Override `Host()` on statsd MetricSet {pull}29103[29103] +- Add Linux pressure metricset {pull}27355[27355] +- Add User-Agent header to HTTP requests. {issue}18160[18160] {pull}27509[27509] + +*Functionbeat* + +- Add support for AWS Kinesis record deaggregation {pull}28241[28241] + +*Winlogbeat* + +- Add support for event language selection from config file {pull}19818[19818] + +==== Deprecated + +*Affecting all Beats* + +- Deprecate `setup.template.type`. In the future Beats will load data streams instead of regular indices. + +*Filebeat* + +- Deprecate `log` input in favour of `filestream` input. {pull}28623[28623] + + [[release-notes-7.15.2]] === Beats version 7.15.2 https://github.com/elastic/beats/compare/v7.15.1...v7.15.2[View commits] diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 3f99e29360fe..247bbd5de00d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -13,14 +13,11 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove the non-ECS `agent.hostname` field. Use the `agent.name` or `agent.id` fields for an identifier. {issue}16377[16377] {pull}18328[18328] - Make error message about locked data path actionable. {pull}18667[18667] - Remove the deprecated `xpack.monitoring.*` settings. Going forward only `monitoring.*` settings may be used. {issue}9424[9424] {pull}18608[18608] -- Skip add_kubernetes_metadata processor when kubernetes metadata are already present {pull}27689[27689] - Remove deprecated/undocumented IncludeCreatorMetadata setting from kubernetes metadata config options {pull}28006[28006] - Remove deprecated fields from kubernetes module {pull}28046[28046] - Remove deprecated config option aws_partition. {pull}28120[28120] - Improve stats API {pull}27963[27963] -- Enable IMDSv2 support for `add_cloud_metadata` processor on AWS. {issue}22101[22101] {pull}28285[28285] - Libbeat: logp package forces ECS compliant logs. Logs are JSON formatted. Options to enable ECS/JSON have been removed. {issue}15544[15544] {pull}28573[28573] -- Previously, RE2 and thus Golang had a bug where `(|a)*` matched more characters than `(|a)+`. To stay consistent with PCRE, the bug was fixed. Configurations that rely on the old, buggy behaviour has to be adjusted. See more about Golang bug: https://github.com/golang/go/issues/46123 {pull}27543[27543] - Update docker client. {pull}28716[28716] - Remove `auto` from the available options of `setup.ilm.enabled` and set the default value to `true`. {pull}28671[28671] - add_process_metadata processor: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] @@ -31,18 +28,11 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] -- Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131] *Auditbeat* - File integrity dataset (macOS): Replace unnecessary `file.origin.raw` (type keyword) with `file.origin.text` (type `text`). {issue}12423[12423] {pull}15630[15630] - Change event.kind=error to event.kind=event to comply with ECS. {issue}18870[18870] {pull}20685[20685] -- File integrity dataset: Remove non-ECS `hash.*` fields. Hashes are under `file.hash.*`. {issue}19039[19039] {pull}28378[28378] -- Auditd dataset: Removes the authentication_success and authentication_failure event.type values for user logins. {issue}19039[19039] {pull}28378[28378] -- Fix handling of long file names on Windows. {issue}25334[25334] {pull}28517[28517] -- System/socket dataset: Fix uninstallation of return kprobes. {issue}28608[28608] {pull}28609[28609] -- Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] -- Fix auditbeat tracing struct decoding. {pull}28580[28580] *Filebeat* @@ -54,30 +44,11 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Preserve case of http.request.method. ECS prior to 1.6 specified normalizing to lowercase, which lost information. Affects filesets: apache/access, elasticsearch/audit, iis/access, iis/error, nginx/access, nginx/ingress_controller, aws/elb, suricata/eve, zeek/http. {issue}18154[18154] {pull}18359[18359] - Add `while_pattern` type to multiline reader. {pull}19662[19662] - Add support for GMT timezone offsets in `decode_cef`. {pull}20993[20993] -- Fix parsing of Elasticsearch node name by `elasticsearch/slowlog` fileset. {pull}14547[14547] -- Removes old module aliases for `googlecloud` (moved to gcp) and `apache2` (moved to apache). {pull}27919[27919] -- Removes old module name aliases (gsuite) and removing old cyberark module in favor of the new cyberarkpas{pull}27915[27915] -- Only filesets that are explicitly configured will be enabled. {issue}17256[17256] {pull}27526[27526] -- All filesets are disabled in the default configuration. {issue}17256[17256] {pull}27762[27762] -- Remove deprecated fields in Kafka module. {pull}27938[27938] -- Remove deprecated fields in coredns module. {pull}28196[28196] -- Remove old `httpjson` config implementation. {pull}28054[28054] -- Added dataset `threatq` to the `threatintel` module to ingest indicators from ThreatQ {issue}27423[27423] -- Fail to start Filebat if none between `queue_url`, `bucket_arn` or `non_aws_bucket_name` is set for a configured aws-s3 input {issue}13911[13911] {pull}28666[28666] -- All modules: Replace usages of deprecated ECS fields `process.ppid` and `log.original` with `process.parent.pid` and `event.original`. {pull}28620[28620] -- Replace usages of `host.user.*` fields with `user.*` in `cisco`, `microsoft` and `oracle` modules. {pull}28620[28620] -- Remove `docker` input. Please use `filestream` input with `container` parser or `container` input. {pull}28817[28817] -- Change `threatintel` module to use new `threat.*` ECS fields. {pull}29014[29014] -- `filestream` and `log` inputs accept null (`\u0000`) as line terminator. {pull}28998[28998] *Heartbeat* -- Change behavior in case of duplicate monitor IDs in configs to be last monitor wins. {pull}29041[29041] *Metricbeat* -- Add Linux pressure metricset {pull}27355[27355] -- Add User-Agent header to HTTP requests. {issue}18160[18160] {pull}27509[27509] -- Errors should be thrown as errors. Metricsets inside Metricbeat will now throw errors as the `error` log level. {pull}27804[27804] - Remove deprecated fields in Docker module. {issue}11835[11835] {pull}27933[27933] - Remove deprecated fields in Kafka module. {pull}27938[27938] - Remove deprecated config option default_region from aws module. {pull}28120[28120] @@ -86,7 +57,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove linux-only metrics from diskio, memory {pull}28292[28292] - Remove deprecated config option perfmon.counters from windows/perfmon metricset. {pull}28282[28282] - Remove deprecated fields in Redis module. {issue}11835[11835] {pull}28246[28246] -- Align fields to Beats naming conventions in GCP module. {issue}27231[27231] {pull}27974[27974] - system/process metricset: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] *Packetbeat* @@ -109,7 +79,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Functionbeat* -- Support for Google Cloud Functions have been removed, as it has been in Beta for a long time and been broken for a few releases. Please use other tools provided by Elastic to fetch data from GCP (e.g. Filebeat). ==== Bugfixes @@ -139,14 +108,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Output errors when Kibana index pattern setup fails. {pull}20121[20121] - Fix issue in autodiscover that kept inputs stopped after config updates. {pull}20305[20305] - Add service resource in k8s cluster role. {pull}20546[20546] -- Periodic metrics in logs will now report `libbeat.output.events.active` and `beat.memstats.rss` as gauges (rather than counters). {pull}22877[22877] -- Fix discovery of Nomad allocations with multiple events during startup. {pull}28700[28700] - Allows disable pod events enrichment with deployment name {pull}28521[28521] - Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] -- Skip configuration checks in autodiscover for configurations that are already running {pull}29048[29048] -- Fix `decode_json_processor` to always respect `add_error_key` {pull}29107[29107] -- Fix `add_labels` flattening of array values. {pull}29211[29211] - Overwrite index name in index template correctly. {issue}28571[28571] {pull}29299[29299] *Auditbeat* @@ -154,7 +118,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - system/package: Fix parsing of Installed-Size field of DEB packages. {issue}16661[16661] {pull}17188[17188] - system module: Fix panic during initialisation when /proc/stat can't be read. {pull}17569[17569] - system/package: Fix an error that can occur while trying to persist package metadata. {issue}18536[18536] {pull}18887[18887] -- Fix handling of root and relative paths {issue}24430[24430] {pull}28354[28354] - system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] *Filebeat* @@ -183,28 +146,13 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix `okta` geoip lookup in pipeline for `destination.ip` {pull}20454[20454] - Fix mapping exception in the `googlecloud/audit` dataset pipeline. {issue}18465[18465] {pull}20465[20465] - Fix `cisco` asa and ftd parsing of messages 106102 and 106103. {pull}20469[20469] -- Update indentation for azure filebeat configuration. {pull}26604[26604] -- Add support for passing a prefix on S3 bucket list mode for AWS-S3 input {pull}28252[28252] {issue}27965[27965] - Resolve issue with @timestamp for defender_atp. {pull}28272[28272] -- Tolerate faults when Windows Event Log session is interrupted {issue}27947[27947] {pull}28191[28191] -- Add support for username in cisco asa security negotiation logs {pull}26975[26975] -- Relax time parsing and capture group and session type in Cisco ASA module {issue}24710[24710] {pull}28325[28325] -- Correctly track bytes read when max_bytes is exceeded. {issue}28317[28317] {pull}28352[28352] -- Fix parsing of apache log levels including numbers. {pull}28717[28717] -- Upgrade azure-eventhub sdk reference, contains potential checkpoint fixes. {pull}28919[28919] -- Revert usageDetails api version to 2019-01-01. {pull}28995[28995] -- Fix in `aws-s3` input regarding provider discovery through endpoint {pull}28963[28963] - Fix `threatintel.misp` filters configuration. {issue}27970[27970] -- Fix opening files on Windows in filestream so open files can be deleted. {issue}29113[29113] {pull}29180[29180] - Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] - Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] *Heartbeat* -- Fix broken seccomp filtering and improve security via `setcap` and `setuid` when running as root on linux in containers. {pull}27878[27878] -- Log browser `zip_url` download failures as `warn` instead of as `info`. {pull}28440[28440] -- Properly locate base stream in fleet configs. {pull}28455[28455] -- Stop logging params values. {pull}28774[28774] - Remove accidentally included cups library in docker images. {pull}28853[pull] - Fix broken monitors with newer versions of image relying on dup3. {pull}28938[pull] @@ -237,11 +185,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Modify doc for app_insights metricset to contain example of config. {pull}20185[20185] - Add required option for `metrics` in app_insights. {pull}20406[20406] - Groups same timestamp metric values to one event in the app_insights metricset. {pull}20403[20403] -- `beat` module respects `basepath` config option. {pull}28162[28162] -- Fix list_docker.go {pull}28374[28374] - Use xpack.enabled on SM modules to write into .monitoring indices when using Metricbeat standalone {pull}28365[28365] - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] -- Fix rds metadata in cloudwatch metricset. {pull}29106[29106] *Packetbeat* @@ -251,10 +196,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Winlogbeat* - Add source.ip validation for event ID 4778 in the Security module. {issue}19627[19627] -- Tolerate faults when Windows Event Log session is interrupted {issue}27947[27947] {pull}28191[28191] -- Add ECS 1.9 new users fields {pull}26509[26509] -- Don't split hyphenated tokens {pull}28483[28483] -- Correctly handle AccessMask if it is an integer or list of masks. {pull}29016[29016] *Functionbeat* @@ -278,20 +219,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add TLS support to Kerberos authentication in Elasticsearch. {pull}18607[18607] - Add config option `rotate_on_startup` to file output {issue}19150[19150] {pull}19347[19347] - Set index.max_docvalue_fields_search in index template to increase value to 200 fields. {issue}20215[20215] -- Allow non-padded base64 data to be decoded by decode_base64_field {pull}27311[27311], {issue}27021[27021] -- The Kafka support library Sarama has been updated to 1.29.1. {pull}27717[27717] -- Kafka is now supported up to version 2.8.0. {pull}27720[27720] -- Add Huawei Cloud provider to add_cloud_metadata. {pull}27607[27607] -- Add default seccomp policy for linux arm64. {pull}27955[27955] -- Add cluster level add_kubernetes_metadata support for centralized enrichment {pull}24621[24621] -- Update ECS to 1.12.0. {pull}27770[27770] -- Fields mapped as `match_only_text` will automatically fallback to a `text` mapping when using Elasticsearch versions that do not support `match_only_text`. {pull}27770[27770] -- Update cloud.google.com/go library. {pull}28229[28229] -- Add additional metadata to the root HTTP endpoint. {pull}28265[28265] -- Upgrade k8s.io/client-go library. {pull}28228[28228] - Upgrade prometheus library. {pull}28716[28716] - Name all k8s workqueue. {pull}28085[28085] -- Update kubernetes scheduler and controllermanager endpoints in elastic-agent-standalone-kubernetes.yaml with secure ports {pull}28675[28675] - Add options to configure k8s client qps/burst. {pull}28151[28151] - Update to ECS 8.0 fields. {pull}28620[28620] - Add http.pprof.enabled option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] @@ -328,44 +257,17 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Improved performance of PANW sample dashboards. {issue}19031[19031] {pull}19032[19032] - Add event.ingested for CrowdStrike module {pull}20138[20138] - Add support for additional fields and FirewallMatchEvent type events in CrowdStrike module {pull}20138[20138] -- Add `timezone` config option to the `decode_cef` processor. {issue}27232[27232] {pull}27727[27727] -- Add `timezone` config option to the `syslog` input. {pull}27727[27727] -- Added support for parsing syslog dates containing a leading 0 (e.g. `Sep 01`) rather than a space. {pull}27775[27775] -- Add base64 Encode functionality to httpjson input. {pull}27681[27681] -- Add `join` and `sprintf` functions to `httpjson` input. {pull}27735[27735] -- Improve memory usage of line reader of `log` and `filestream` input. {pull}27782[27782] -- Add `ignore_empty_value` flag to `httpjson` `split` processor. {pull}27880[27880] -- Update Cisco ASA/FTD ingest pipeline grok/dissect patterns for multiple message IDs. {issue}26869[26869] {pull}26879[26879] -- Add write access to `url.value` from `request.transforms` in `httpjson` input. {pull}27937[27937] -- Add Base64 encoded HMAC and UUID template functions to `httpjson` input {pull}27873[27873] -- Release checkpoint module as GA. {pull}27814[27814] -- Make aws-cloudwatch input GA. {pull}28161[28161] -- Move processing to ingest node for AWS vpcflow fileset. {pull}28168[28168] -- Release zoom module as GA. {pull}28106[28106] -- Add support for secondary object attribute handling in ThreatIntel MISP module {pull}28124[28124] - Azure signinlogs - Add support for ManagedIdentitySignInLogs, NonInteractiveUserSignInLogs, and ServicePrincipalSignInLogs. {issue}23653[23653] -- Add `base64Decode` and `base64DecodeNoPad` functions to `httpsjon` templates. {pull}28385[28385] -- Add 'early_limit' config option for Rate-Limiting `httpjson`. Default rate-limiting for Okta will start when remaining is `1`. {pull}28513[28513] -- Add latency config option for aws-cloudwatch input. {pull}28509[28509] -- Added proxy support to threatintel/malwarebazaar. {pull}28533[28533] - Add `text/csv` decoder to `httpjson` input {pull}28564[28564] - Update `aws-s3` input to connect to non AWS S3 buckets {issue}28222[28222] {pull}28234[28234] -- Sophos UTM: Support logs containing hostname in syslog header. {pull}28638[28638] -- Moving Oracle Filebeat module to GA. {pull}28754[28754] - Add support for '/var/log/pods/' path for add_kubernetes_metadata processor with `resource_type: pod`. {pull}28868[28868] - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] -- Add support in aws-s3 input for s3 notification from SNS to SQS. {pull}28800[28800] -- Add support in aws-s3 input for custom script parsing of s3 notifications. {pull}28946[28946] -- Improve error handling in aws-s3 input for malformed s3 notifications. {issue}28828[28828] {pull}28946[28946] - Add support for parsers on journald input {pull}29070[29070] - Add elapsed time information to `aws-s3` input errors and log messages. {pull}29328[29328] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] *Heartbeat* -- Support JSON expressions / validation of JSON arrays. {pull}28073[28073] -- Experimental 'run once' mode. {pull}25972[25972] -- Add `keyword` multi-field mapping for `synthetics.step.name`. {pull}28452[28452] *Metricbeat* @@ -378,24 +280,17 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Added documentation for running Metricbeat in Cloud Foundry. {pull}17275[17275] - Remove required for region/zone and make stackdriver a metricset in googlecloud. {issue}16785[16785] {pull}18398[18398] - Add memory metrics into compute googlecloud. {pull}18802[18802] -- Enable `journald` input type in Filebeat. {issue}7955[7955] {pull}27351[27351] -- Added a new beta `enterprisesearch` module for Elastic Enterprise Search {pull}27549[27549] - Preliminary AIX support {pull}27954[27954] -- Register additional name for `storage` metricset in the azure module. {pull}28447[28447] -- Update reference to gosigar pacakge for filesystem windows fix. {pull}28909[28909] -- Override `Host()` on statsd MetricSet {pull}29103[29103] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] *Packetbeat* *Functionbeat* -- Add support for AWS Kinesis record deaggregation {pull}28241[28241] *Winlogbeat* - Add more DNS error codes to the Sysmon module. {issue}15685[15685] -- Add support for event language selection from config file {pull}19818[19818] - Add configuration option for registry file flush timeout {issue}29001[29001] {pull}29053[29053] *Elastic Log Driver* @@ -409,7 +304,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Filebeat* -- Deprecate `log` input in favour of `filestream` input. {pull}28623[28623] *Heartbeat* diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index aed042ea25bc..a2d210eaeabe 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -11,6 +11,7 @@ upgrade. * <> * <> * <> +* <> * <> * <> * <> From 5a9fdafee4766475987bae6cd4dfad56b5082f78 Mon Sep 17 00:00:00 2001 From: joereith Date: Mon, 13 Dec 2021 11:32:16 -0500 Subject: [PATCH 076/172] Metricbeat fails to build linux/mips* targets on linux/amd64 hosts (#28323) * Update io_helper_linux.go This edit allows for cross compiling linux/mips* targets on linux/amd64 hosts. before this edit I was getting the following error with the following command: ```bash user@user:~/Documents/projects/beats/metricbeat$ GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -trimpath -ldflags="-s -w" -o metricbeat_mipsle # github.com/elastic/beats/v7/libbeat/metric/system/cgroup/cgv2 ../libbeat/metric/system/cgroup/cgv2/io_helper_linux.go:55:16: constant 18446726481523507200 overflows uint32 ../libbeat/metric/system/cgroup/cgv2/io_helper_linux.go:56:54: constant 17592184995840 overflows uint32 ../libbeat/metric/system/cgroup/cgv2/io_helper_linux.go:57:15: invalid operation: curMajor == major (mismatched types uint32 and uint64) ../libbeat/metric/system/cgroup/cgv2/io_helper_linux.go:57:36: invalid operation: curMinor == minor (mismatched types uint32 and uint64) ``` * Update io_helper_linux.go Fixing unnecessary type castings --- libbeat/metric/system/cgroup/cgv2/io_helper_linux.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libbeat/metric/system/cgroup/cgv2/io_helper_linux.go b/libbeat/metric/system/cgroup/cgv2/io_helper_linux.go index c56c903cfc87..b62709c73526 100644 --- a/libbeat/metric/system/cgroup/cgv2/io_helper_linux.go +++ b/libbeat/metric/system/cgroup/cgv2/io_helper_linux.go @@ -30,10 +30,13 @@ import ( // fetchDeviceName will attempt to find a device name associated with a major/minor pair // the bool indicates if a device was found. -func fetchDeviceName(major, minor uint64) (bool, string, error) { +func fetchDeviceName(major uint64, minor uint64) (bool, string, error) { // iterate over /dev/ and pull major and minor values found := false var devName string + var curMajor uint64 + var curMinor uint64 + var devID uint64 walkFunc := func(path string, d fs.DirEntry, err error) error { if d.IsDir() && path != "/dev/" { return fs.SkipDir @@ -49,12 +52,13 @@ func fetchDeviceName(major, minor uint64) (bool, string, error) { if !ok { return nil } - devID := infoT.Rdev + devID = uint64(infoT.Rdev) + // do some bitmapping to extract the major and minor device values // The odd duplicated logic here is to deal with 32 and 64 bit values. // see bits/sysmacros.h - curMajor := ((devID & 0xfffff00000000000) >> 32) | ((devID & 0x00000000000fff00) >> 8) - curMinor := ((devID & 0x00000000000000ff) >> 0) | ((devID & 0x00000ffffff00000) >> 12) + curMajor = ((devID & 0xfffff00000000000) >> 32) | ((devID & 0x00000000000fff00) >> 8) + curMinor = ((devID & 0x00000000000000ff) >> 0) | ((devID & 0x00000ffffff00000) >> 12) if curMajor == major && curMinor == minor { found = true devName = d.Name() From 6b03b3b56c154214b717e0c5c45a9ce496779f5e Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 13 Dec 2021 20:49:03 +0100 Subject: [PATCH 077/172] Forward port 7.16.1 changelog to master (#29409) * Forward port 7.16.1 changelog to 8.0 (#29408) * docs: Prepare Changelog for 7.16.1 (#29404) * docs: Close changelog for 7.16.1 * Review and cleanup * Additional cleanup Co-authored-by: Andres Rodriguez (cherry picked from commit 0f81eea724195c72778ac5d8fff5737b7befdd31) * Review and cleanup Co-authored-by: Elastic Machine (cherry picked from commit 20aaab20e11b10171382c577606965c0ce584e4b) * Review and cleanup --- CHANGELOG.asciidoc | 16 ++++++++++++++++ CHANGELOG.next.asciidoc | 2 -- libbeat/docs/release.asciidoc | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 32d965a98b3e..082ef758cb62 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -17,6 +17,22 @@ Changes will be described in a later alpha / beta. === Beats version 8.0.0-alpha1 Changes will be described in a later alpha / beta. +[[release-notes-7.16.1]] +=== Beats version 7.16.1 +https://github.com/elastic/beats/compare/v7.16.0...v7.16.1[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Overwrite index name in index template correctly. {issue}28571[28571] {pull}29299[29299] + +==== Added + +*Filebeat* + +- Add elapsed time information to `aws-s3` input errors and log messages. {pull}29328[29328] + [[release-notes-7.16.0]] === Beats version 7.16.0 https://github.com/elastic/beats/compare/v7.15.2...v7.16.0[View commits] diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 247bbd5de00d..e6e1cab2f18d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -111,7 +111,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Allows disable pod events enrichment with deployment name {pull}28521[28521] - Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] - Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] -- Overwrite index name in index template correctly. {issue}28571[28571] {pull}29299[29299] *Auditbeat* @@ -263,7 +262,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support for '/var/log/pods/' path for add_kubernetes_metadata processor with `resource_type: pod`. {pull}28868[28868] - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support for parsers on journald input {pull}29070[29070] -- Add elapsed time information to `aws-s3` input errors and log messages. {pull}29328[29328] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] *Heartbeat* diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index a2d210eaeabe..1529ebf2872b 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -11,6 +11,7 @@ upgrade. * <> * <> * <> +* <> * <> * <> * <> From 633f7dc1edc8e426453f745481cf28c599b09c29 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 13 Dec 2021 22:41:46 +0200 Subject: [PATCH 078/172] Update k8s library (#29394) Signed-off-by: chrismark --- CHANGELOG.next.asciidoc | 1 + NOTICE.txt | 312 +++++++++++++++++++++++++++++++++++----- go.mod | 31 ++-- go.sum | 65 ++++++--- 4 files changed, 346 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e6e1cab2f18d..38a1f05c043b 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -227,6 +227,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - SASL/SCRAM in the Kafka output is no longer beta. {pull}29126[29126] - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] - Support self signed certificates on outputs {pull}29229[29229] +- Update k8s library {pull}29394[29394] *Auditbeat* diff --git a/NOTICE.txt b/NOTICE.txt index 5761502320cc..148e4680e06a 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -10434,11 +10434,11 @@ Contents of probable licence file $GOMODCACHE/github.com/gorhill/cronexpr@v0.0.0 -------------------------------------------------------------------------------- Dependency : github.com/gorilla/mux -Version: v1.7.3 +Version: v1.8.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/gorilla/mux@v1.7.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gorilla/mux@v1.8.0/LICENSE: Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. @@ -16656,11 +16656,11 @@ THE SOFTWARE. -------------------------------------------------------------------------------- Dependency : golang.org/x/crypto -Version: v0.0.0-20210616213533-5ff15b29337e +Version: v0.0.0-20210817164053-32db794688a5 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.0.0-20210616213533-5ff15b29337e/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.0.0-20210817164053-32db794688a5/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -18285,11 +18285,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : k8s.io/api -Version: v0.21.1 +Version: v0.23.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/api@v0.21.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/api@v0.23.0/LICENSE: Apache License @@ -18497,11 +18497,11 @@ Contents of probable licence file $GOMODCACHE/k8s.io/api@v0.21.1/LICENSE: -------------------------------------------------------------------------------- Dependency : k8s.io/apimachinery -Version: v0.21.1 +Version: v0.23.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/apimachinery@v0.21.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/apimachinery@v0.23.0/LICENSE: Apache License @@ -18709,11 +18709,11 @@ Contents of probable licence file $GOMODCACHE/k8s.io/apimachinery@v0.21.1/LICENS -------------------------------------------------------------------------------- Dependency : k8s.io/client-go -Version: v0.21.1 +Version: v0.23.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/client-go@v0.21.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/client-go@v0.23.0/LICENSE: Apache License @@ -24299,11 +24299,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : github.com/evanphx/json-patch -Version: v4.9.0+incompatible +Version: v4.12.0+incompatible Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch@v4.9.0+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch@v4.12.0+incompatible/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -24677,11 +24677,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/go-logr/logr -Version: v0.4.0 +Version: v1.2.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v0.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v1.2.0/LICENSE: Apache License Version 2.0, January 2004 @@ -26779,11 +26779,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : github.com/googleapis/gnostic -Version: v0.4.1 +Version: v0.5.5 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/googleapis/gnostic@v0.4.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/googleapis/gnostic@v0.5.5/LICENSE: Apache License @@ -30450,11 +30450,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/json-iterator/go -Version: v1.1.11 +Version: v1.1.12 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.11/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.12/LICENSE: MIT License @@ -32036,11 +32036,11 @@ Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0 -------------------------------------------------------------------------------- Dependency : github.com/modern-go/reflect2 -Version: v1.0.1 +Version: v1.0.2 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.2/LICENSE: Apache License Version 2.0, January 2004 @@ -32309,11 +32309,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/onsi/ginkgo -Version: v1.12.1 +Version: v1.14.0 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo@v1.12.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo@v1.14.0/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -34558,11 +34558,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/term -Version: v0.0.0-20210220032956-6a3ed077a48d +Version: v0.0.0-20210615171337-6886f2dfbf5b Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.0.0-20210220032956-6a3ed077a48d/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.0.0-20210615171337-6886f2dfbf5b/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -36076,11 +36076,11 @@ third-party archives. -------------------------------------------------------------------------------- Dependency : k8s.io/klog/v2 -Version: v2.9.0 +Version: v2.30.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/klog/v2@v2.9.0/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/klog/v2@v2.30.0/LICENSE: Apache License Version 2.0, January 2004 @@ -36277,11 +36277,11 @@ third-party archives. -------------------------------------------------------------------------------- Dependency : k8s.io/kube-openapi -Version: v0.0.0-20210305001622-591a79e4bda7 +Version: v0.0.0-20211115234752-e816edb12b65 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/kube-openapi@v0.0.0-20210305001622-591a79e4bda7/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/kube-openapi@v0.0.0-20211115234752-e816edb12b65/LICENSE: Apache License @@ -36489,11 +36489,11 @@ Contents of probable licence file $GOMODCACHE/k8s.io/kube-openapi@v0.0.0-2021030 -------------------------------------------------------------------------------- Dependency : k8s.io/utils -Version: v0.0.0-20201110183641-67b214c5f920 +Version: v0.0.0-20210930125809-cb0fa318a74b Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/k8s.io/utils@v0.0.0-20201110183641-67b214c5f920/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/utils@v0.0.0-20210930125809-cb0fa318a74b/LICENSE: Apache License @@ -37105,13 +37105,261 @@ library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. +-------------------------------------------------------------------------------- +Dependency : sigs.k8s.io/json +Version: v0.0.0-20211020170558-c049b76a60c6 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/json@v0.0.0-20211020170558-c049b76a60c6/LICENSE: + +Files other than internal/golang/* licensed under: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +------------------ + +internal/golang/* files licensed under: + + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + -------------------------------------------------------------------------------- Dependency : sigs.k8s.io/structured-merge-diff/v4 -Version: v4.1.0 +Version: v4.1.2 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/structured-merge-diff/v4@v4.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/structured-merge-diff/v4@v4.1.2/LICENSE: Apache License Version 2.0, January 2004 diff --git a/go.mod b/go.mod index 70af77f8e936..4cf5253b1a10 100644 --- a/go.mod +++ b/go.mod @@ -98,7 +98,7 @@ require ( github.com/google/gopacket v1.1.19 github.com/google/uuid v1.3.0 github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 - github.com/gorilla/mux v1.7.3 + github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.1.1 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/go-retryablehttp v0.6.6 @@ -162,7 +162,7 @@ require ( go.uber.org/atomic v1.8.0 go.uber.org/multierr v1.5.0 go.uber.org/zap v1.14.1 - golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 golang.org/x/net v0.0.0-20211020060615-d418f374d309 golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 @@ -186,9 +186,9 @@ require ( gotest.tools v2.2.0+incompatible gotest.tools/gotestsum v0.6.0 howett.net/plist v0.0.0-20181124034731-591f970eefbb - k8s.io/api v0.21.1 - k8s.io/apimachinery v0.21.1 - k8s.io/client-go v0.21.1 + k8s.io/api v0.23.0 + k8s.io/apimachinery v0.23.0 + k8s.io/client-go v0.23.0 kernel.org/pub/linux/libs/security/libcap/cap v1.2.57 ) @@ -216,9 +216,9 @@ require ( github.com/docker/distribution v2.7.1+incompatible // indirect github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect github.com/eapache/queue v1.1.0 // indirect - github.com/evanphx/json-patch v4.9.0+incompatible // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fearful-symmetry/gomsr v0.0.1 // indirect - github.com/go-logr/logr v0.4.0 // indirect + github.com/go-logr/logr v1.2.0 // indirect github.com/gobuffalo/here v0.6.0 // indirect github.com/godbus/dbus/v5 v5.0.5 // indirect github.com/golang-jwt/jwt/v4 v4.0.0 // indirect @@ -229,7 +229,7 @@ require ( github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/gax-go/v2 v2.1.1 // indirect - github.com/googleapis/gnostic v0.4.1 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/cronexpr v1.1.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect @@ -246,7 +246,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.11 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/karrick/godirwalk v1.15.6 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/markbates/pkger v0.17.0 // indirect @@ -257,7 +257,7 @@ require ( github.com/moby/spdystream v0.2.0 // indirect github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pierrec/lz4 v2.6.0+incompatible // indirect github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect @@ -269,15 +269,16 @@ require ( go.elastic.co/fastjson v1.1.0 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/mod v0.5.1 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - k8s.io/klog/v2 v2.9.0 // indirect - k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 // indirect - k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect kernel.org/pub/linux/libs/security/libcap/psx v1.2.57 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect sigs.k8s.io/yaml v1.2.0 // indirect ) diff --git a/go.sum b/go.sum index 28f0ed5236f0..49cf15709b89 100644 --- a/go.sum +++ b/go.sum @@ -566,8 +566,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -577,6 +578,7 @@ github.com/fearful-symmetry/gorapl v0.0.4 h1:TMn4fhhtIAd+C3NrAl638oaYlX1vgcKNVVd github.com/fearful-symmetry/gorapl v0.0.4/go.mod h1:XoeZ+5v0tJX9WMvzqdPaaKAdX7y17mDN3pxDGemINR0= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/foxcpp/go-mockdns v0.0.0-20201212160233-ede2f9158d15/go.mod h1:tPg4cp4nseejPd+UKxtCVQ2hUxNTZ7qQZJa7CLriIeo= @@ -586,6 +588,7 @@ github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebP github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -608,8 +611,9 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647 h1:whypLownH338a3Ork2w9t0KUKtVxbXYySuz7V1YGsJo= @@ -822,6 +826,7 @@ github.com/gomodule/redigo v1.8.3 h1:HR0kYDX2RJZvAup8CsiJwxB4dTCSC0AaUq6S4SiLwUc github.com/gomodule/redigo v1.8.3/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= @@ -882,8 +887,10 @@ github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss= github.com/gophercloud/gophercloud v0.18.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= @@ -895,8 +902,9 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -1054,8 +1062,9 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= @@ -1201,8 +1210,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= @@ -1240,14 +1250,16 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.2.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -1479,6 +1491,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1673,8 +1686,9 @@ golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1762,6 +1776,7 @@ golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1785,6 +1800,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1891,6 +1907,7 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1937,6 +1954,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1944,8 +1962,9 @@ golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAU golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2028,6 +2047,7 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -2143,6 +2163,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -2301,14 +2322,16 @@ k8s.io/api v0.17.5/go.mod h1:0zV5/ungglgy2Rlm3QK8fbxkXVs+BSJWpJP/+8gUVLY= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= +k8s.io/api v0.23.0 h1:WrL1gb73VSC8obi8cuYETJGXEoFNEh3LU0Pt+Sokgro= +k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg= k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= +k8s.io/apimachinery v0.23.0 h1:mIfWRMjBuMdolAWJ3Fd+aPTMv3X9z+waiARMpvvb0HQ= +k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= @@ -2316,8 +2339,9 @@ k8s.io/client-go v0.17.5/go.mod h1:S8uZpBpjJJdEH/fEyxcqg7Rn0P5jH+ilkgBHjriSmNo= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= +k8s.io/client-go v0.23.0 h1:vcsOqyPq7XV3QmQRCBH/t9BICJM9Q1M18qahjv+rebY= +k8s.io/client-go v0.23.0/go.mod h1:hrDnpnK1mSr65lHHcUuIZIXDgEbzc7/683c6hyG4jTA= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= @@ -2327,24 +2351,30 @@ k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200316234421-82d701f24f9d/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= kernel.org/pub/linux/libs/security/libcap/cap v1.2.57 h1:2nmqI+aw7EQZuelYktkQHBE4jESD2tOR+lOJEnv/Apo= kernel.org/pub/linux/libs/security/libcap/cap v1.2.57/go.mod h1:uI99C3r4SXvJeuqoEtx/eWt7UbmfqqZ80H8q+9t/A7I= kernel.org/pub/linux/libs/security/libcap/psx v1.2.57 h1:NOFATXSf5z/cMR3HIwQ3Xrd3nwnWl5xThmNr5U/F0pI= @@ -2355,11 +2385,14 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= From bc09710f82822904d0fa13a0689f44cdeaaf480c Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Tue, 14 Dec 2021 08:34:21 +1030 Subject: [PATCH 079/172] x-pack/filebeat/input/netflow: record IPv6 src and dst addresses (#29383) --- CHANGELOG.next.asciidoc | 1 + x-pack/filebeat/input/netflow/convert.go | 32 ++- ...-extended-uniflow-template-256.golden.json | 4 +- .../IPFIX-Barracuda-firewall.golden.json | 16 +- ...IPFIX-Mikrotik-RouterOS-6.39.2.golden.json | 250 +++++++++++++++--- ...er-with-variable-length-fields.golden.json | 8 +- .../golden/IPFIX-Nokia-BRAS.golden.json | 4 +- .../golden/IPFIX-OpenBSD-pflow.golden.json | 52 ++-- .../testdata/golden/IPFIX-Procera.golden.json | 22 +- ...are-virtual-distributed-switch.golden.json | 14 +- .../IPFIX-YAF-basic-with-applabel.golden.json | 4 +- ...igured-with-include_flowset_id.golden.json | 8 +- .../netflow/testdata/golden/IPFIX.golden.json | 24 +- ...w-9-Cisco-1941-K9-release-15.1.golden.json | 68 ++--- .../golden/Netflow-9-Cisco-ASA.golden.json | 28 +- ...o-ASR-9000-series-template-260.golden.json | 44 +-- .../Netflow-9-Cisco-ASR1001--X.golden.json | 48 ++-- ...flow-9-Fortigate-FortiOS-5.2.1.golden.json | 4 +- ...-9-Fortigate-FortiOS-54x-appid.golden.json | 36 +-- .../testdata/golden/Netflow-9-H3C.golden.json | 48 ++-- .../golden/Netflow-9-IE150-IE151.golden.json | 4 +- ...et-in-large-zero-filled-packet.golden.json | 4 +- ...Palo-Alto-PAN--OS-with-app--id.golden.json | 16 +- .../golden/Netflow-9-Streamcore.golden.json | 8 +- ...ti-Edgerouter-with-MPLS-labels.golden.json | 12 +- ...etflow-9-field-layer2segmentid.golden.json | 4 +- ..._netflow-reduced-size-encoding.golden.json | 8 +- .../golden/Netflow-9-macaddress.golden.json | 56 ++-- ...w-9-multiple-netflow-exporters.golden.json | 30 ++- .../Netflow-9-nprobe-DPI-L7.golden.json | 1 - ...-template-with-0-length-fields.golden.json | 20 +- .../golden/Netflow-9-valid-01.golden.json | 26 +- ...netflow9_e10s_4_7byte_pad.pcap.golden.json | 12 +- ...flow9_ubiquiti_edgerouter.pcap.golden.json | 4 +- 34 files changed, 570 insertions(+), 350 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 38a1f05c043b..50cb3176b8f2 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -149,6 +149,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix `threatintel.misp` filters configuration. {issue}27970[27970] - Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] - Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] +- Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] *Heartbeat* diff --git a/x-pack/filebeat/input/netflow/convert.go b/x-pack/filebeat/input/netflow/convert.go index 465cd3efd021..2f10b33c2382 100644 --- a/x-pack/filebeat/input/netflow/convert.go +++ b/x-pack/filebeat/input/netflow/convert.go @@ -5,9 +5,11 @@ package netflow import ( + "bytes" "encoding/base64" "encoding/binary" "net" + "sort" "strconv" "strings" "time" @@ -196,6 +198,10 @@ func flowToBeatEvent(flow record.Record, internalNetworks []string) (event beat. ecsSource["ip"] = ip relatedIP = append(relatedIP, ip) ecsSource["locality"] = getIPLocality(internalNetworks, ip).String() + } else if ip, found := getKeyIP(flow.Fields, "sourceIPv6Address"); found { + ecsSource["ip"] = ip + relatedIP = append(relatedIP, ip) + ecsSource["locality"] = getIPLocality(internalNetworks, ip).String() } if sourcePort, found := getKeyUint64(flow.Fields, "sourceTransportPort"); found { ecsSource["port"] = sourcePort @@ -209,6 +215,10 @@ func flowToBeatEvent(flow record.Record, internalNetworks []string) (event beat. ecsDest["ip"] = ip relatedIP = append(relatedIP, ip) ecsDest["locality"] = getIPLocality(internalNetworks, ip).String() + } else if ip, found := getKeyIP(flow.Fields, "destinationIPv6Address"); found { + ecsDest["ip"] = ip + relatedIP = append(relatedIP, ip) + ecsDest["locality"] = getIPLocality(internalNetworks, ip).String() } if destPort, found := getKeyUint64(flow.Fields, "destinationTransportPort"); found { ecsDest["port"] = destPort @@ -321,11 +331,31 @@ func flowToBeatEvent(flow record.Record, internalNetworks []string) (event beat. event.Fields["network"] = ecsNetwork } if len(relatedIP) > 0 { - event.Fields["related"] = common.MapStr{"ip": relatedIP} + event.Fields["related"] = common.MapStr{"ip": uniqueIPs(relatedIP)} } return } +// unique returns ips lexically sorted and with repeated elements +// omitted. +func uniqueIPs(ips []net.IP) []net.IP { + if len(ips) < 2 { + return ips + } + sort.Slice(ips, func(i, j int) bool { return bytes.Compare(ips[i], ips[j]) < 0 }) + curr := 0 + for i, ip := range ips { + if ip.Equal(ips[curr]) { + continue + } + curr++ + if curr < i { + ips[curr], ips[i] = ips[i], nil + } + } + return ips[:curr+1] +} + func getKeyUint64(dict record.Map, key string) (value uint64, found bool) { iface, found := dict[key] if !found { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-extended-uniflow-template-256.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-extended-uniflow-template-256.golden.json index fbc2f5e3d2ab..a983b980e1de 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-extended-uniflow-template-256.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-extended-uniflow-template-256.golden.json @@ -169,8 +169,8 @@ }, "related": { "ip": [ - "64.235.151.76", - "10.236.5.4" + "10.236.5.4", + "64.235.151.76" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-firewall.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-firewall.golden.json index ec4f36b10faf..4fae641f6379 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-firewall.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Barracuda-firewall.golden.json @@ -145,8 +145,8 @@ }, "related": { "ip": [ - "10.99.252.50", - "10.99.130.239" + "10.99.130.239", + "10.99.252.50" ] }, "source": { @@ -225,8 +225,8 @@ }, "related": { "ip": [ - "10.99.130.239", - "10.98.243.20" + "10.98.243.20", + "10.99.130.239" ] }, "source": { @@ -385,8 +385,8 @@ }, "related": { "ip": [ - "10.99.168.140", - "10.98.243.20" + "10.98.243.20", + "10.99.168.140" ] }, "source": { @@ -545,8 +545,8 @@ }, "related": { "ip": [ - "10.99.168.140", - "10.98.243.20" + "10.98.243.20", + "10.99.168.140" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Mikrotik-RouterOS-6.39.2.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Mikrotik-RouterOS-6.39.2.golden.json index 36fea0d68e1f..99fb1859cfc0 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Mikrotik-RouterOS-6.39.2.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Mikrotik-RouterOS-6.39.2.golden.json @@ -454,8 +454,8 @@ }, "related": { "ip": [ - "172.20.4.199", - "172.20.4.1" + "172.20.4.1", + "172.20.4.199" ] }, "source": { @@ -610,8 +610,8 @@ }, "related": { "ip": [ - "172.20.4.30", - "10.10.8.34" + "10.10.8.34", + "172.20.4.30" ] }, "source": { @@ -766,8 +766,8 @@ }, "related": { "ip": [ - "172.20.4.30", - "10.10.8.105" + "10.10.8.105", + "172.20.4.30" ] }, "source": { @@ -1078,8 +1078,8 @@ }, "related": { "ip": [ - "172.20.5.191", - "10.10.8.220" + "10.10.8.220", + "172.20.5.191" ] }, "source": { @@ -2190,6 +2190,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:401", + "locality": "internal", "port": 5678 }, "event": { @@ -2204,7 +2206,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "b7SlZfUSuVA", "locality": "internal" }, "netflow": { @@ -2233,7 +2235,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:jPPsu6xuLKidwts3HEFDcMotUV4=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2242,8 +2244,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:401" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:401", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2256,6 +2265,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:401", + "locality": "internal", "port": 5678 }, "event": { @@ -2270,7 +2281,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "b7SlZfUSuVA", "locality": "internal" }, "netflow": { @@ -2299,7 +2310,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:jPPsu6xuLKidwts3HEFDcMotUV4=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2308,8 +2319,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:401" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:401", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2322,6 +2340,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:501", + "locality": "internal", "port": 5678 }, "event": { @@ -2336,7 +2356,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "VSgWWLDT0B0", "locality": "internal" }, "netflow": { @@ -2365,7 +2385,7 @@ }, "network": { "bytes": 495, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:5591MHyJIXcwUkG4sl3Rs9ro+Ng=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2374,8 +2394,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:501" + ] + }, "source": { "bytes": 495, + "ip": "fe80::ff:fe00:501", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2388,6 +2415,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:501", + "locality": "internal", "port": 5678 }, "event": { @@ -2402,7 +2431,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "VSgWWLDT0B0", "locality": "internal" }, "netflow": { @@ -2431,7 +2460,7 @@ }, "network": { "bytes": 330, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:5591MHyJIXcwUkG4sl3Rs9ro+Ng=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2440,8 +2469,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:501" + ] + }, "source": { "bytes": 330, + "ip": "fe80::ff:fe00:501", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2454,6 +2490,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:601", + "locality": "internal", "port": 5678 }, "event": { @@ -2468,7 +2506,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "LZgYFJ0tL2g", "locality": "internal" }, "netflow": { @@ -2497,7 +2535,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:0uFiK83G7mZT66yRsishu3GrI+Y=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2506,8 +2544,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:601" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:601", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2520,6 +2565,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:601", + "locality": "internal", "port": 5678 }, "event": { @@ -2534,7 +2581,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "LZgYFJ0tL2g", "locality": "internal" }, "netflow": { @@ -2563,7 +2610,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:0uFiK83G7mZT66yRsishu3GrI+Y=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2572,8 +2619,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:601" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:601", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2586,6 +2640,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:701", + "locality": "internal", "port": 5678 }, "event": { @@ -2600,7 +2656,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "dmeH14jqz_U", "locality": "internal" }, "netflow": { @@ -2629,7 +2685,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:GHzTYB/S+swKAM+TWkXhIHekjME=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2638,8 +2694,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:701" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:701", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2652,6 +2715,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:701", + "locality": "internal", "port": 5678 }, "event": { @@ -2666,7 +2731,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "dmeH14jqz_U", "locality": "internal" }, "netflow": { @@ -2695,7 +2760,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:GHzTYB/S+swKAM+TWkXhIHekjME=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2704,8 +2769,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:701" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:701", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2718,6 +2790,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:801", + "locality": "internal", "port": 5678 }, "event": { @@ -2732,7 +2806,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "Il9O6oJGqRk", "locality": "internal" }, "netflow": { @@ -2761,7 +2835,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:Y0L0KaggvOgNiQSbjBDXSANtIRo=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2770,8 +2844,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:801" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:801", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2784,6 +2865,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:801", + "locality": "internal", "port": 5678 }, "event": { @@ -2798,7 +2881,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "Il9O6oJGqRk", "locality": "internal" }, "netflow": { @@ -2827,7 +2910,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:Y0L0KaggvOgNiQSbjBDXSANtIRo=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2836,8 +2919,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:801" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:801", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2850,6 +2940,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:901", + "locality": "internal", "port": 5678 }, "event": { @@ -2864,7 +2956,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "fA2V7HT45yo", "locality": "internal" }, "netflow": { @@ -2893,7 +2985,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:ckujBEtohW0WnvxDVLoLAfkwHeE=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -2902,8 +2994,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:901" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:901", + "locality": "internal", "packets": 3, "port": 5678 } @@ -2916,6 +3015,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:901", + "locality": "internal", "port": 5678 }, "event": { @@ -2930,7 +3031,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "fA2V7HT45yo", "locality": "internal" }, "netflow": { @@ -2959,7 +3060,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:ckujBEtohW0WnvxDVLoLAfkwHeE=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -2968,8 +3069,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:901" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:901", + "locality": "internal", "packets": 2, "port": 5678 } @@ -2982,6 +3090,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1001", + "locality": "internal", "port": 5678 }, "event": { @@ -2996,7 +3106,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "r9myTc0ZAtE", "locality": "internal" }, "netflow": { @@ -3025,7 +3135,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:3MYYQzFTLjghJ6R8FULtQ6M3TY4=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -3034,8 +3144,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1001" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:1001", + "locality": "internal", "packets": 3, "port": 5678 } @@ -3048,6 +3165,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1001", + "locality": "internal", "port": 5678 }, "event": { @@ -3062,7 +3181,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "r9myTc0ZAtE", "locality": "internal" }, "netflow": { @@ -3091,7 +3210,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:3MYYQzFTLjghJ6R8FULtQ6M3TY4=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -3100,8 +3219,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1001" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:1001", + "locality": "internal", "packets": 2, "port": 5678 } @@ -3114,6 +3240,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1101", + "locality": "internal", "port": 5678 }, "event": { @@ -3128,7 +3256,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "we4v-M4gTEo", "locality": "internal" }, "netflow": { @@ -3157,7 +3285,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:RCaNdj14AFbHfSM4MQquuPjYpgs=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -3166,8 +3294,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1101" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:1101", + "locality": "internal", "packets": 3, "port": 5678 } @@ -3180,6 +3315,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1101", + "locality": "internal", "port": 5678 }, "event": { @@ -3194,7 +3331,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "we4v-M4gTEo", "locality": "internal" }, "netflow": { @@ -3223,7 +3360,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:RCaNdj14AFbHfSM4MQquuPjYpgs=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -3232,8 +3369,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1101" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:1101", + "locality": "internal", "packets": 2, "port": 5678 } @@ -3246,6 +3390,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1201", + "locality": "internal", "port": 5678 }, "event": { @@ -3260,7 +3406,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "N9KUKy-eIwc", "locality": "internal" }, "netflow": { @@ -3289,7 +3435,7 @@ }, "network": { "bytes": 555, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:AL2CtUGKb1BgJM4KclloxlRQdRc=", "direction": "unknown", "iana_number": 17, "packets": 3, @@ -3298,8 +3444,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1201" + ] + }, "source": { "bytes": 555, + "ip": "fe80::ff:fe00:1201", + "locality": "internal", "packets": 3, "port": 5678 } @@ -3312,6 +3465,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "fe80::ff:fe00:1201", + "locality": "internal", "port": 5678 }, "event": { @@ -3326,7 +3481,7 @@ ] }, "flow": { - "id": "RlrAo_U1Y14", + "id": "N9KUKy-eIwc", "locality": "internal" }, "netflow": { @@ -3355,7 +3510,7 @@ }, "network": { "bytes": 370, - "community_id": "1:I4DlCbWgyxRiNPVj5ntu1L7Z0hw=", + "community_id": "1:AL2CtUGKb1BgJM4KclloxlRQdRc=", "direction": "unknown", "iana_number": 17, "packets": 2, @@ -3364,8 +3519,15 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::ff:fe00:1201" + ] + }, "source": { "bytes": 370, + "ip": "fe80::ff:fe00:1201", + "locality": "internal", "packets": 2, "port": 5678 } diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Netscaler-with-variable-length-fields.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Netscaler-with-variable-length-fields.golden.json index e27655fe1edb..9d0ddb6a2fd0 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Netscaler-with-variable-length-fields.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Netscaler-with-variable-length-fields.golden.json @@ -87,8 +87,8 @@ }, "related": { "ip": [ - "192.168.0.1", - "10.0.0.1" + "10.0.0.1", + "192.168.0.1" ] }, "source": { @@ -277,8 +277,8 @@ }, "related": { "ip": [ - "192.168.0.1", - "10.0.0.1" + "10.0.0.1", + "192.168.0.1" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Nokia-BRAS.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Nokia-BRAS.golden.json index f21438c20eef..3f50095a6c0f 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Nokia-BRAS.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Nokia-BRAS.golden.json @@ -57,8 +57,8 @@ }, "related": { "ip": [ - "10.0.1.228", - "10.0.0.34" + "10.0.0.34", + "10.0.1.228" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-OpenBSD-pflow.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-OpenBSD-pflow.golden.json index 4961f7d0a257..04c22e39df4a 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-OpenBSD-pflow.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-OpenBSD-pflow.golden.json @@ -60,8 +60,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -208,8 +208,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -356,8 +356,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -504,8 +504,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -652,8 +652,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -800,8 +800,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -948,8 +948,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1096,8 +1096,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1244,8 +1244,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1392,8 +1392,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1540,8 +1540,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1688,8 +1688,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { @@ -1836,8 +1836,8 @@ }, "related": { "ip": [ - "192.168.0.17", - "192.168.0.1" + "192.168.0.1", + "192.168.0.17" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Procera.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Procera.golden.json index 30acfdf29c56..4c2a0fa82534 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Procera.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-Procera.golden.json @@ -69,8 +69,8 @@ }, "related": { "ip": [ - "181.214.87.71", - "138.44.161.14" + "138.44.161.14", + "181.214.87.71" ] }, "source": { @@ -150,7 +150,6 @@ }, "related": { "ip": [ - "0.0.0.0", "0.0.0.0" ] }, @@ -312,8 +311,8 @@ }, "related": { "ip": [ - "206.117.25.89", - "138.44.161.14" + "138.44.161.14", + "206.117.25.89" ] }, "source": { @@ -393,7 +392,6 @@ }, "related": { "ip": [ - "0.0.0.0", "0.0.0.0" ] }, @@ -474,8 +472,8 @@ }, "related": { "ip": [ - "185.232.29.199", - "138.44.161.14" + "138.44.161.14", + "185.232.29.199" ] }, "source": { @@ -555,8 +553,8 @@ }, "related": { "ip": [ - "177.188.228.137", - "138.44.161.14" + "138.44.161.14", + "177.188.228.137" ] }, "source": { @@ -636,8 +634,8 @@ }, "related": { "ip": [ - "138.44.161.14", - "138.44.161.13" + "138.44.161.13", + "138.44.161.14" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-VMware-virtual-distributed-switch.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-VMware-virtual-distributed-switch.golden.json index dc8f538dfee7..3396c5ef7942 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-VMware-virtual-distributed-switch.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-VMware-virtual-distributed-switch.golden.json @@ -338,6 +338,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "ff02::1:3", + "locality": "internal", "port": 5355 }, "event": { @@ -352,7 +354,7 @@ ] }, "flow": { - "id": "y_Vml2vPNtw", + "id": "iOQ1bg2JOLM", "locality": "internal" }, "netflow": { @@ -388,7 +390,7 @@ }, "network": { "bytes": 144, - "community_id": "1:Nl0K3f1AqKrkGYEhoNHcgFAr/EY=", + "community_id": "1:pr+rxLjqBu9/jT6yJoAEy7/fgdY=", "direction": "outbound", "iana_number": 17, "packets": 2, @@ -397,8 +399,16 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::5187:5cd8:d750:cdc9", + "ff02::1:3" + ] + }, "source": { "bytes": 144, + "ip": "fe80::5187:5cd8:d750:cdc9", + "locality": "internal", "packets": 2, "port": 61329 } diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-YAF-basic-with-applabel.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-YAF-basic-with-applabel.golden.json index 5b2b4b01ac3b..6c77e7a0fa9f 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-YAF-basic-with-applabel.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-YAF-basic-with-applabel.golden.json @@ -70,8 +70,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.100" + "172.16.32.100", + "172.16.32.201" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-configured-with-include_flowset_id.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-configured-with-include_flowset_id.golden.json index 0c2dbd22d5e8..c3934c5e32b7 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-configured-with-include_flowset_id.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX-configured-with-include_flowset_id.golden.json @@ -87,8 +87,8 @@ }, "related": { "ip": [ - "192.168.0.1", - "10.0.0.1" + "10.0.0.1", + "192.168.0.1" ] }, "source": { @@ -277,8 +277,8 @@ }, "related": { "ip": [ - "192.168.0.1", - "10.0.0.1" + "10.0.0.1", + "192.168.0.1" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX.golden.json index 72dd4072ef9e..7ba0ecb0713b 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/IPFIX.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/IPFIX.golden.json @@ -180,8 +180,8 @@ }, "related": { "ip": [ - "192.168.253.128", - "192.168.253.1" + "192.168.253.1", + "192.168.253.128" ] }, "source": { @@ -336,8 +336,8 @@ }, "related": { "ip": [ - "192.168.253.132", - "192.168.253.2" + "192.168.253.2", + "192.168.253.132" ] }, "source": { @@ -492,8 +492,8 @@ }, "related": { "ip": [ - "192.168.253.132", - "54.214.9.161" + "54.214.9.161", + "192.168.253.132" ] }, "source": { @@ -570,8 +570,8 @@ }, "related": { "ip": [ - "192.168.253.130", - "10.4.36.64" + "10.4.36.64", + "192.168.253.130" ] }, "source": { @@ -726,8 +726,8 @@ }, "related": { "ip": [ - "192.168.253.128", - "192.168.253.1" + "192.168.253.1", + "192.168.253.128" ] }, "source": { @@ -882,8 +882,8 @@ }, "related": { "ip": [ - "192.168.253.128", - "192.168.253.1" + "192.168.253.1", + "192.168.253.128" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-1941-K9-release-15.1.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-1941-K9-release-15.1.golden.json index 448709e5c419..834efbc7df6b 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-1941-K9-release-15.1.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-1941-K9-release-15.1.golden.json @@ -63,8 +63,8 @@ }, "related": { "ip": [ - "192.168.0.111", - "62.217.193.1" + "62.217.193.1", + "192.168.0.111" ] }, "source": { @@ -141,8 +141,8 @@ }, "related": { "ip": [ - "192.168.0.111", - "62.217.193.65" + "62.217.193.65", + "192.168.0.111" ] }, "source": { @@ -219,8 +219,8 @@ }, "related": { "ip": [ - "192.168.0.111", - "62.217.193.1" + "62.217.193.1", + "192.168.0.111" ] }, "source": { @@ -297,8 +297,8 @@ }, "related": { "ip": [ - "192.168.0.111", - "62.217.193.65" + "62.217.193.65", + "192.168.0.111" ] }, "source": { @@ -531,8 +531,8 @@ }, "related": { "ip": [ - "216.58.212.195", - "192.168.0.88" + "192.168.0.88", + "216.58.212.195" ] }, "source": { @@ -687,8 +687,8 @@ }, "related": { "ip": [ - "216.58.201.106", - "192.168.1.201" + "192.168.1.201", + "216.58.201.106" ] }, "source": { @@ -843,8 +843,8 @@ }, "related": { "ip": [ - "192.168.3.34", - "52.216.130.237" + "52.216.130.237", + "192.168.3.34" ] }, "source": { @@ -921,8 +921,8 @@ }, "related": { "ip": [ - "209.197.3.19", - "192.168.3.34" + "192.168.3.34", + "209.197.3.19" ] }, "source": { @@ -1077,8 +1077,8 @@ }, "related": { "ip": [ - "192.168.0.157", - "172.217.23.232" + "172.217.23.232", + "192.168.0.157" ] }, "source": { @@ -1311,8 +1311,8 @@ }, "related": { "ip": [ - "192.168.3.178", - "107.21.232.174" + "107.21.232.174", + "192.168.3.178" ] }, "source": { @@ -1389,8 +1389,8 @@ }, "related": { "ip": [ - "192.168.2.118", - "95.0.145.242" + "95.0.145.242", + "192.168.2.118" ] }, "source": { @@ -1545,8 +1545,8 @@ }, "related": { "ip": [ - "192.168.0.79", - "23.5.100.66" + "23.5.100.66", + "192.168.0.79" ] }, "source": { @@ -1623,8 +1623,8 @@ }, "related": { "ip": [ - "192.168.0.79", - "23.5.100.66" + "23.5.100.66", + "192.168.0.79" ] }, "source": { @@ -1857,8 +1857,8 @@ }, "related": { "ip": [ - "192.168.0.61", - "170.251.180.15" + "170.251.180.15", + "192.168.0.61" ] }, "source": { @@ -1935,8 +1935,8 @@ }, "related": { "ip": [ - "192.168.3.34", - "74.119.119.84" + "74.119.119.84", + "192.168.3.34" ] }, "source": { @@ -2091,8 +2091,8 @@ }, "related": { "ip": [ - "192.168.3.200", - "185.60.218.15" + "185.60.218.15", + "192.168.3.200" ] }, "source": { @@ -2247,8 +2247,8 @@ }, "related": { "ip": [ - "192.168.0.95", - "169.45.214.246" + "169.45.214.246", + "192.168.0.95" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA.golden.json index 135aa56d0d4e..d8ebc7e8eaa5 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA.golden.json @@ -69,8 +69,8 @@ }, "related": { "ip": [ - "192.168.14.1", - "2.2.2.11" + "2.2.2.11", + "192.168.14.1" ] }, "source": { @@ -151,8 +151,8 @@ }, "related": { "ip": [ - "192.168.23.22", - "164.164.37.11" + "164.164.37.11", + "192.168.23.22" ] }, "source": { @@ -315,8 +315,8 @@ }, "related": { "ip": [ - "192.168.23.20", - "164.164.37.11" + "164.164.37.11", + "192.168.23.20" ] }, "source": { @@ -479,8 +479,8 @@ }, "related": { "ip": [ - "192.168.14.11", - "2.2.2.11" + "2.2.2.11", + "192.168.14.11" ] }, "source": { @@ -725,8 +725,8 @@ }, "related": { "ip": [ - "192.168.14.1", - "2.2.2.11" + "2.2.2.11", + "192.168.14.1" ] }, "source": { @@ -889,8 +889,8 @@ }, "related": { "ip": [ - "192.168.23.22", - "164.164.37.11" + "164.164.37.11", + "192.168.23.22" ] }, "source": { @@ -1053,8 +1053,8 @@ }, "related": { "ip": [ - "192.168.23.20", - "164.164.37.11" + "164.164.37.11", + "192.168.23.20" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR-9000-series-template-260.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR-9000-series-template-260.golden.json index 9922cc10d661..70cfcfdd14eb 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR-9000-series-template-260.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR-9000-series-template-260.golden.json @@ -421,8 +421,8 @@ }, "related": { "ip": [ - "10.0.34.71", - "10.0.20.242" + "10.0.20.242", + "10.0.34.71" ] }, "source": { @@ -595,8 +595,8 @@ }, "related": { "ip": [ - "10.0.37.29", - "10.0.6.24" + "10.0.6.24", + "10.0.37.29" ] }, "source": { @@ -682,8 +682,8 @@ }, "related": { "ip": [ - "10.0.32.176", - "10.0.11.113" + "10.0.11.113", + "10.0.32.176" ] }, "source": { @@ -856,8 +856,8 @@ }, "related": { "ip": [ - "10.0.4.212", - "10.0.3.110" + "10.0.3.110", + "10.0.4.212" ] }, "source": { @@ -943,8 +943,8 @@ }, "related": { "ip": [ - "10.0.33.122", - "10.0.1.136" + "10.0.1.136", + "10.0.33.122" ] }, "source": { @@ -1204,8 +1204,8 @@ }, "related": { "ip": [ - "10.0.25.59", - "10.0.2.18" + "10.0.2.18", + "10.0.25.59" ] }, "source": { @@ -1465,8 +1465,8 @@ }, "related": { "ip": [ - "10.0.28.150", - "10.0.24.13" + "10.0.24.13", + "10.0.28.150" ] }, "source": { @@ -1552,8 +1552,8 @@ }, "related": { "ip": [ - "10.0.26.188", - "10.0.21.200" + "10.0.21.200", + "10.0.26.188" ] }, "source": { @@ -1639,8 +1639,8 @@ }, "related": { "ip": [ - "10.0.29.34", - "10.0.15.38" + "10.0.15.38", + "10.0.29.34" ] }, "source": { @@ -1726,8 +1726,8 @@ }, "related": { "ip": [ - "10.0.8.200", - "10.0.5.224" + "10.0.5.224", + "10.0.8.200" ] }, "source": { @@ -1813,8 +1813,8 @@ }, "related": { "ip": [ - "10.0.29.46", - "10.0.15.38" + "10.0.15.38", + "10.0.29.46" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR1001--X.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR1001--X.golden.json index 9049d5513041..b548a68d5234 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR1001--X.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASR1001--X.golden.json @@ -63,8 +63,8 @@ }, "related": { "ip": [ - "10.111.111.242", - "10.12.100.13" + "10.12.100.13", + "10.111.111.242" ] }, "source": { @@ -294,8 +294,8 @@ }, "related": { "ip": [ - "10.12.104.239", - "10.10.11.21" + "10.10.11.21", + "10.12.104.239" ] }, "source": { @@ -448,8 +448,8 @@ }, "related": { "ip": [ - "10.100.101.45", - "10.15.131.98" + "10.15.131.98", + "10.100.101.45" ] }, "source": { @@ -525,8 +525,8 @@ }, "related": { "ip": [ - "10.100.101.43", - "10.12.105.23" + "10.12.105.23", + "10.100.101.43" ] }, "source": { @@ -602,8 +602,8 @@ }, "related": { "ip": [ - "31.13.71.7", - "10.11.31.108" + "10.11.31.108", + "31.13.71.7" ] }, "source": { @@ -833,8 +833,8 @@ }, "related": { "ip": [ - "10.100.105.86", - "10.11.21.60" + "10.11.21.60", + "10.100.105.86" ] }, "source": { @@ -987,8 +987,8 @@ }, "related": { "ip": [ - "10.12.106.83", - "10.10.11.21" + "10.10.11.21", + "10.12.106.83" ] }, "source": { @@ -1064,8 +1064,8 @@ }, "related": { "ip": [ - "172.217.11.5", - "10.12.92.102" + "10.12.92.102", + "172.217.11.5" ] }, "source": { @@ -1295,8 +1295,8 @@ }, "related": { "ip": [ - "10.14.121.98", - "10.12.100.13" + "10.12.100.13", + "10.14.121.98" ] }, "source": { @@ -1526,8 +1526,8 @@ }, "related": { "ip": [ - "10.12.102.125", - "10.10.11.21" + "10.10.11.21", + "10.12.102.125" ] }, "source": { @@ -1603,8 +1603,8 @@ }, "related": { "ip": [ - "10.100.105.86", - "10.11.21.60" + "10.11.21.60", + "10.100.105.86" ] }, "source": { @@ -1757,8 +1757,8 @@ }, "related": { "ip": [ - "10.100.105.85", - "10.10.4.151" + "10.10.4.151", + "10.100.105.85" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-5.2.1.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-5.2.1.golden.json index 8dc5747704ac..962a60d4efde 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-5.2.1.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-5.2.1.golden.json @@ -102,8 +102,8 @@ }, "related": { "ip": [ - "192.168.99.7", - "31.13.87.36" + "31.13.87.36", + "192.168.99.7" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-54x-appid.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-54x-appid.golden.json index dd90fa13b6d8..a6d193432dee 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-54x-appid.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Fortigate-FortiOS-54x-appid.golden.json @@ -71,8 +71,8 @@ }, "related": { "ip": [ - "192.168.100.151", - "182.50.136.239" + "182.50.136.239", + "192.168.100.151" ] }, "source": { @@ -156,8 +156,8 @@ }, "related": { "ip": [ - "208.100.17.187", - "192.168.100.151" + "192.168.100.151", + "208.100.17.187" ] }, "source": { @@ -326,8 +326,8 @@ }, "related": { "ip": [ - "208.100.17.189", - "192.168.100.151" + "192.168.100.151", + "208.100.17.189" ] }, "source": { @@ -581,8 +581,8 @@ }, "related": { "ip": [ - "192.168.100.151", - "178.255.83.1" + "178.255.83.1", + "192.168.100.151" ] }, "source": { @@ -751,8 +751,8 @@ }, "related": { "ip": [ - "192.168.100.151", - "178.255.83.1" + "178.255.83.1", + "192.168.100.151" ] }, "source": { @@ -913,8 +913,8 @@ }, "related": { "ip": [ - "192.168.100.150", - "192.168.100.111" + "192.168.100.111", + "192.168.100.150" ] }, "source": { @@ -1075,8 +1075,8 @@ }, "related": { "ip": [ - "192.168.100.150", - "192.168.100.111" + "192.168.100.111", + "192.168.100.150" ] }, "source": { @@ -1237,8 +1237,8 @@ }, "related": { "ip": [ - "192.168.100.150", - "192.168.100.111" + "192.168.100.111", + "192.168.100.150" ] }, "source": { @@ -1399,8 +1399,8 @@ }, "related": { "ip": [ - "192.168.100.150", - "192.168.100.111" + "192.168.100.111", + "192.168.100.150" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-H3C.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-H3C.golden.json index a69dbeea3865..b75a1c2ba3bf 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-H3C.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-H3C.golden.json @@ -76,8 +76,8 @@ }, "related": { "ip": [ - "10.22.166.30", - "10.22.163.21" + "10.22.163.21", + "10.22.166.30" ] }, "source": { @@ -166,8 +166,8 @@ }, "related": { "ip": [ - "10.22.166.12", - "10.21.3.172" + "10.21.3.172", + "10.22.166.12" ] }, "source": { @@ -346,8 +346,8 @@ }, "related": { "ip": [ - "10.22.166.35", - "10.20.100.253" + "10.20.100.253", + "10.22.166.35" ] }, "source": { @@ -436,8 +436,8 @@ }, "related": { "ip": [ - "10.22.166.36", - "10.20.136.36" + "10.20.136.36", + "10.22.166.36" ] }, "source": { @@ -526,8 +526,8 @@ }, "related": { "ip": [ - "10.22.166.36", - "10.20.147.28" + "10.20.147.28", + "10.22.166.36" ] }, "source": { @@ -616,8 +616,8 @@ }, "related": { "ip": [ - "10.22.166.28", - "10.20.141.16" + "10.20.141.16", + "10.22.166.28" ] }, "source": { @@ -706,8 +706,8 @@ }, "related": { "ip": [ - "10.22.166.35", - "10.20.162.17" + "10.20.162.17", + "10.22.166.35" ] }, "source": { @@ -796,8 +796,8 @@ }, "related": { "ip": [ - "10.22.166.15", - "10.20.171.36" + "10.20.171.36", + "10.22.166.15" ] }, "source": { @@ -1156,8 +1156,8 @@ }, "related": { "ip": [ - "10.22.166.25", - "10.20.166.26" + "10.20.166.26", + "10.22.166.25" ] }, "source": { @@ -1246,8 +1246,8 @@ }, "related": { "ip": [ - "10.22.166.12", - "10.21.3.117" + "10.21.3.117", + "10.22.166.12" ] }, "source": { @@ -1336,8 +1336,8 @@ }, "related": { "ip": [ - "10.22.166.17", - "10.22.145.26" + "10.22.145.26", + "10.22.166.17" ] }, "source": { @@ -1426,8 +1426,8 @@ }, "related": { "ip": [ - "10.22.166.36", - "10.21.75.38" + "10.21.75.38", + "10.22.166.36" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-IE150-IE151.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-IE150-IE151.golden.json index 3aed82dc6f9b..3db18648d082 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-IE150-IE151.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-IE150-IE151.golden.json @@ -63,8 +63,8 @@ }, "related": { "ip": [ - "192.168.0.3", - "192.168.0.2" + "192.168.0.2", + "192.168.0.3" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-1-flowset-in-large-zero-filled-packet.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-1-flowset-in-large-zero-filled-packet.golden.json index d0207ba3192b..60f97f064955 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-1-flowset-in-large-zero-filled-packet.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-1-flowset-in-large-zero-filled-packet.golden.json @@ -69,8 +69,8 @@ }, "related": { "ip": [ - "134.220.2.6", - "134.220.1.156" + "134.220.1.156", + "134.220.2.6" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-PAN--OS-with-app--id.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-PAN--OS-with-app--id.golden.json index 79e31dd7f6b7..98d496c0a7a1 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-PAN--OS-with-app--id.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Palo-Alto-PAN--OS-with-app--id.golden.json @@ -69,8 +69,8 @@ }, "related": { "ip": [ - "23.35.171.27", - "10.32.91.205" + "10.32.91.205", + "23.35.171.27" ] }, "source": { @@ -318,8 +318,8 @@ }, "related": { "ip": [ - "23.209.52.99", - "10.130.145.44" + "10.130.145.44", + "23.209.52.99" ] }, "source": { @@ -401,8 +401,8 @@ }, "related": { "ip": [ - "10.50.97.57", - "10.50.96.20" + "10.50.96.20", + "10.50.97.57" ] }, "source": { @@ -567,8 +567,8 @@ }, "related": { "ip": [ - "34.234.173.147", - "10.48.208.209" + "10.48.208.209", + "34.234.173.147" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Streamcore.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Streamcore.golden.json index 1319ba663cc1..ebfde635048e 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Streamcore.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Streamcore.golden.json @@ -64,8 +64,8 @@ }, "related": { "ip": [ - "100.78.40.201", - "10.231.128.150" + "10.231.128.150", + "100.78.40.201" ] }, "source": { @@ -220,8 +220,8 @@ }, "related": { "ip": [ - "100.78.40.201", - "10.27.8.20" + "10.27.8.20", + "100.78.40.201" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Ubiquiti-Edgerouter-with-MPLS-labels.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Ubiquiti-Edgerouter-with-MPLS-labels.golden.json index e6cb0fb4112b..fec0ac80498e 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Ubiquiti-Edgerouter-with-MPLS-labels.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Ubiquiti-Edgerouter-with-MPLS-labels.golden.json @@ -420,8 +420,8 @@ }, "related": { "ip": [ - "10.5.0.91", - "10.4.0.251" + "10.4.0.251", + "10.5.0.91" ] }, "source": { @@ -767,8 +767,8 @@ }, "related": { "ip": [ - "192.168.1.98", - "10.0.0.73" + "10.0.0.73", + "192.168.1.98" ] }, "source": { @@ -1362,8 +1362,8 @@ }, "related": { "ip": [ - "192.168.1.102", - "10.2.0.95" + "10.2.0.95", + "192.168.1.102" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-field-layer2segmentid.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-field-layer2segmentid.golden.json index 879714e24c07..73d4e4e7fdf2 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-field-layer2segmentid.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-field-layer2segmentid.golden.json @@ -68,8 +68,8 @@ }, "related": { "ip": [ - "192.168.200.136", - "80.82.237.40" + "80.82.237.40", + "192.168.200.136" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-ipt_netflow-reduced-size-encoding.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-ipt_netflow-reduced-size-encoding.golden.json index 2b7dded5bd6a..4e6b375574b1 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-ipt_netflow-reduced-size-encoding.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-ipt_netflow-reduced-size-encoding.golden.json @@ -333,8 +333,8 @@ }, "related": { "ip": [ - "193.151.192.46", - "10.236.8.4" + "10.236.8.4", + "193.151.192.46" ] }, "source": { @@ -942,8 +942,8 @@ }, "related": { "ip": [ - "23.43.139.27", - "10.232.8.45" + "10.232.8.45", + "23.43.139.27" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-macaddress.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-macaddress.golden.json index 7db570f5db18..e13854469032 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-macaddress.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-macaddress.golden.json @@ -157,8 +157,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.100" + "172.16.32.100", + "172.16.32.201" ] }, "source": { @@ -358,8 +358,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -492,8 +492,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -626,8 +626,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -760,8 +760,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -894,8 +894,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1028,8 +1028,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1162,8 +1162,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1296,8 +1296,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1430,8 +1430,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1564,8 +1564,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1698,8 +1698,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1832,8 +1832,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { @@ -1966,8 +1966,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-multiple-netflow-exporters.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-multiple-netflow-exporters.golden.json index 4238292f2505..f75a3893975d 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-multiple-netflow-exporters.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-multiple-netflow-exporters.golden.json @@ -180,8 +180,8 @@ }, "related": { "ip": [ - "172.16.32.248", - "172.16.32.100" + "172.16.32.100", + "172.16.32.248" ] }, "source": { @@ -338,8 +338,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.100" + "172.16.32.100", + "172.16.32.201" ] }, "source": { @@ -496,8 +496,8 @@ }, "related": { "ip": [ - "172.16.32.202", - "172.16.32.100" + "172.16.32.100", + "172.16.32.202" ] }, "source": { @@ -516,6 +516,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "ff02::1", + "locality": "internal", "port": 34304 }, "event": { @@ -533,7 +535,7 @@ ] }, "flow": { - "id": "tYpw8DU5u10", + "id": "hsSxbBU-M1o", "locality": "internal" }, "netflow": { @@ -562,7 +564,7 @@ }, "network": { "bytes": 672, - "community_id": "1:vK+Zeop1Y3GHxfFGVF2/COcNBWw=", + "community_id": "1:z1qoJyUMuKy3HX8rkIDvBK/vyL8=", "direction": "unknown", "iana_number": 58, "packets": 7, @@ -571,8 +573,16 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::20c:29ff:fe83:3b6e", + "ff02::1" + ] + }, "source": { "bytes": 672, + "ip": "fe80::20c:29ff:fe83:3b6e", + "locality": "internal", "packets": 7, "port": 0 } @@ -648,8 +658,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.1" + "172.16.32.1", + "172.16.32.201" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-nprobe-DPI-L7.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-nprobe-DPI-L7.golden.json index 3e6a1d037191..ddb22d837b5d 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-nprobe-DPI-L7.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-nprobe-DPI-L7.golden.json @@ -59,7 +59,6 @@ }, "related": { "ip": [ - "0.0.0.0", "0.0.0.0" ] }, diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-template-with-0-length-fields.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-template-with-0-length-fields.golden.json index 65a849e632af..64a7ea5e9482 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-template-with-0-length-fields.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-template-with-0-length-fields.golden.json @@ -69,8 +69,8 @@ }, "related": { "ip": [ - "239.255.255.250", - "192.168.1.80" + "192.168.1.80", + "239.255.255.250" ] }, "source": { @@ -235,8 +235,8 @@ }, "related": { "ip": [ - "239.255.255.250", - "192.168.1.95" + "192.168.1.95", + "239.255.255.250" ] }, "source": { @@ -401,8 +401,8 @@ }, "related": { "ip": [ - "239.255.255.250", - "192.168.1.95" + "192.168.1.95", + "239.255.255.250" ] }, "source": { @@ -567,8 +567,8 @@ }, "related": { "ip": [ - "239.255.255.250", - "192.168.1.33" + "192.168.1.33", + "239.255.255.250" ] }, "source": { @@ -733,8 +733,8 @@ }, "related": { "ip": [ - "239.255.255.250", - "192.168.1.33" + "192.168.1.33", + "239.255.255.250" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-valid-01.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-valid-01.golden.json index 20ea4e61d315..b65cc125f57e 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-valid-01.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-valid-01.golden.json @@ -144,8 +144,8 @@ }, "related": { "ip": [ - "172.16.32.248", - "172.16.32.100" + "172.16.32.100", + "172.16.32.248" ] }, "source": { @@ -302,8 +302,8 @@ }, "related": { "ip": [ - "172.16.32.201", - "172.16.32.100" + "172.16.32.100", + "172.16.32.201" ] }, "source": { @@ -460,8 +460,8 @@ }, "related": { "ip": [ - "172.16.32.202", - "172.16.32.100" + "172.16.32.100", + "172.16.32.202" ] }, "source": { @@ -480,6 +480,8 @@ "Meta": null, "Fields": { "destination": { + "ip": "ff02::1", + "locality": "internal", "port": 34304 }, "event": { @@ -497,7 +499,7 @@ ] }, "flow": { - "id": "tYpw8DU5u10", + "id": "hsSxbBU-M1o", "locality": "internal" }, "netflow": { @@ -526,7 +528,7 @@ }, "network": { "bytes": 672, - "community_id": "1:vK+Zeop1Y3GHxfFGVF2/COcNBWw=", + "community_id": "1:z1qoJyUMuKy3HX8rkIDvBK/vyL8=", "direction": "unknown", "iana_number": 58, "packets": 7, @@ -535,8 +537,16 @@ "observer": { "ip": "192.0.2.1" }, + "related": { + "ip": [ + "fe80::20c:29ff:fe83:3b6e", + "ff02::1" + ] + }, "source": { "bytes": 672, + "ip": "fe80::20c:29ff:fe83:3b6e", + "locality": "internal", "packets": 7, "port": 0 } diff --git a/x-pack/filebeat/input/netflow/testdata/golden/netflow9_e10s_4_7byte_pad.pcap.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/netflow9_e10s_4_7byte_pad.pcap.golden.json index 82a9efb87aac..869aefe8629f 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/netflow9_e10s_4_7byte_pad.pcap.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/netflow9_e10s_4_7byte_pad.pcap.golden.json @@ -61,8 +61,8 @@ }, "related": { "ip": [ - "10.127.32.11", - "10.36.236.100" + "10.36.236.100", + "10.127.32.11" ] }, "source": { @@ -286,8 +286,8 @@ }, "related": { "ip": [ - "52.206.251.4", - "10.36.236.100" + "10.36.236.100", + "52.206.251.4" ] }, "source": { @@ -436,8 +436,8 @@ }, "related": { "ip": [ - "10.36.237.22", - "10.36.228.103" + "10.36.228.103", + "10.36.237.22" ] }, "source": { diff --git a/x-pack/filebeat/input/netflow/testdata/golden/netflow9_ubiquiti_edgerouter.pcap.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/netflow9_ubiquiti_edgerouter.pcap.golden.json index ea23d1283ad0..48a368eed069 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/netflow9_ubiquiti_edgerouter.pcap.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/netflow9_ubiquiti_edgerouter.pcap.golden.json @@ -836,8 +836,8 @@ }, "related": { "ip": [ - "192.168.1.4", - "10.100.0.1" + "10.100.0.1", + "192.168.1.4" ] }, "source": { From 377f97b1f72dff2a41657f083fda2943ef1c67f7 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Mon, 13 Dec 2021 23:08:32 -0600 Subject: [PATCH 080/172] Move `fips_enabled` setting to AWS Common (#28899) --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/modules/aws.asciidoc | 18 +++++ .../docs/inputs/input-aws-s3.asciidoc | 4 +- x-pack/filebeat/filebeat.reference.yml | 42 ++++++++++ x-pack/filebeat/input/awscloudwatch/input.go | 3 +- x-pack/filebeat/input/awss3/config.go | 4 +- x-pack/filebeat/input/awss3/config_test.go | 1 - x-pack/filebeat/input/awss3/input.go | 13 +--- x-pack/filebeat/module/aws/_meta/config.yml | 36 +++++++++ .../module/aws/cloudtrail/config/aws-s3.yml | 4 + .../module/aws/cloudtrail/manifest.yml | 1 + .../module/aws/cloudwatch/config/aws-s3.yml | 4 + .../module/aws/cloudwatch/manifest.yml | 1 + .../filebeat/module/aws/ec2/config/aws-s3.yml | 4 + x-pack/filebeat/module/aws/ec2/manifest.yml | 1 + .../filebeat/module/aws/elb/config/aws-s3.yml | 4 + x-pack/filebeat/module/aws/elb/manifest.yml | 1 + .../module/aws/s3access/config/aws-s3.yml | 4 + .../filebeat/module/aws/s3access/manifest.yml | 1 + .../module/aws/vpcflow/config/input.yml | 4 + .../filebeat/module/aws/vpcflow/manifest.yml | 1 + .../module/awsfargate/_meta/config.yml | 6 ++ .../awsfargate/log/config/aws-cloudwatch.yml | 8 ++ .../module/awsfargate/log/manifest.yml | 2 + x-pack/filebeat/modules.d/aws.yml.disabled | 36 +++++++++ .../modules.d/awsfargate.yml.disabled | 6 ++ .../providers/aws/ec2/provider.go | 6 +- .../providers/aws/elb/provider.go | 6 +- x-pack/libbeat/common/aws/credentials.go | 64 +++++++++++----- x-pack/libbeat/common/aws/credentials_test.go | 76 +++++++++++++++++++ .../docs/aws-credentials-config.asciidoc | 2 + .../metricbeat/module/aws/_meta/docs.asciidoc | 18 +++++ x-pack/metricbeat/module/aws/aws.go | 16 +++- .../metricbeat/module/aws/billing/billing.go | 19 ++++- .../module/aws/cloudwatch/cloudwatch.go | 18 +++-- .../module/aws/cloudwatch/metadata.go | 8 +- .../module/aws/cloudwatch/metadata/ec2/ec2.go | 5 +- .../module/aws/cloudwatch/metadata/rds/rds.go | 5 +- .../module/aws/cloudwatch/metadata/sqs/sqs.go | 5 +- 39 files changed, 398 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 50cb3176b8f2..ba9d9007541f 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -229,6 +229,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] - Support self signed certificates on outputs {pull}29229[29229] - Update k8s library {pull}29394[29394] +- Add FIPS configuration option for all AWS API calls. {pull}[28899] *Auditbeat* diff --git a/metricbeat/docs/modules/aws.asciidoc b/metricbeat/docs/modules/aws.asciidoc index 75991b5bd098..e0fa06851e50 100644 --- a/metricbeat/docs/modules/aws.asciidoc +++ b/metricbeat/docs/modules/aws.asciidoc @@ -68,6 +68,24 @@ If endpoint is specified, `regions` config becomes required. For example: - ec2 ---- +* *fips_enabled* + +Enforces the use of FIPS service endpoints. See <> for more information. + +[source,yaml] +---- +- module: aws + period: 5m + fips_enabled: true + regions: + - us-east-1 + - us-east-2 + - us-west-1 + - us-west-2 + metricsets: + - ec2 +---- + The aws module comes with a predefined dashboard. For example: image::./images/metricbeat-aws-overview.png[] diff --git a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc index ec7a16cd67b3..e771258562cc 100644 --- a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc @@ -182,9 +182,7 @@ file_selectors: [float] ==== `fips_enabled` -Enabling this option changes the service name from `s3` to `s3-fips` for -connecting to the correct service endpoint. For example: -`s3-fips.us-gov-east-1.amazonaws.com`. +Moved to <>. [id="input-{type}-include_s3_metadata"] [float] diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 8a8fdeb360fe..d5df5da53ab5 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -160,6 +160,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + cloudwatch: enabled: false @@ -212,6 +218,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + ec2: enabled: false @@ -264,6 +276,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + elb: enabled: false @@ -316,6 +334,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + s3access: enabled: false @@ -368,6 +392,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + vpcflow: enabled: false @@ -420,6 +450,12 @@ filebeat.modules: # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + #----------------------------- AWS Fargate Module ----------------------------- - module: awsfargate log: @@ -476,6 +512,12 @@ filebeat.modules: # Default api_sleep is 200 ms #var.api_sleep: 200ms + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + #-------------------------------- Azure Module -------------------------------- - module: azure # All logs diff --git a/x-pack/filebeat/input/awscloudwatch/input.go b/x-pack/filebeat/input/awscloudwatch/input.go index 3001449378d2..22f9efe15c68 100644 --- a/x-pack/filebeat/input/awscloudwatch/input.go +++ b/x-pack/filebeat/input/awscloudwatch/input.go @@ -131,7 +131,8 @@ func NewInput(cfg *common.Config, connector channel.Connector, context input.Con // Run runs the input func (in *awsCloudWatchInput) Run() { // Please see https://docs.aws.amazon.com/general/latest/gr/cwl_region.html for more info on Amazon CloudWatch Logs endpoints. - cwConfig := awscommon.EnrichAWSConfigWithEndpoint(in.config.AwsConfig.Endpoint, "logs", in.config.RegionName, in.awsConfig) + logsServiceName := awscommon.CreateServiceName("logs", in.config.AwsConfig.FIPSEnabled, in.config.RegionName) + cwConfig := awscommon.EnrichAWSConfigWithEndpoint(in.config.AwsConfig.Endpoint, logsServiceName, in.config.RegionName, in.awsConfig) svc := cloudwatchlogs.New(cwConfig) var logGroupNames []string diff --git a/x-pack/filebeat/input/awss3/config.go b/x-pack/filebeat/input/awss3/config.go index d25b99a69bdf..cd26b57d0b19 100644 --- a/x-pack/filebeat/input/awss3/config.go +++ b/x-pack/filebeat/input/awss3/config.go @@ -25,7 +25,6 @@ type config struct { SQSWaitTime time.Duration `config:"sqs.wait_time"` // The max duration for which the SQS ReceiveMessage call waits for a message to arrive in the queue before returning. SQSMaxReceiveCount int `config:"sqs.max_receive_count"` // The max number of times a message should be received (retried) before deleting it. SQSScript *scriptConfig `config:"sqs.notification_parsing_script"` - FIPSEnabled bool `config:"fips_enabled"` MaxNumberOfMessages int `config:"max_number_of_messages"` QueueURL string `config:"queue_url"` BucketARN string `config:"bucket_arn"` @@ -48,7 +47,6 @@ func defaultConfig() config { BucketListPrefix: "", SQSWaitTime: 20 * time.Second, SQSMaxReceiveCount: 5, - FIPSEnabled: false, MaxNumberOfMessages: 5, PathStyle: false, } @@ -99,7 +97,7 @@ func (c *config) Validate() error { c.APITimeout, c.SQSWaitTime) } - if c.FIPSEnabled && c.NonAWSBucketName != "" { + if c.AWSConfig.FIPSEnabled && c.NonAWSBucketName != "" { return errors.New("fips_enabled cannot be used with a non-AWS S3 bucket.") } if c.PathStyle && c.NonAWSBucketName == "" { diff --git a/x-pack/filebeat/input/awss3/config_test.go b/x-pack/filebeat/input/awss3/config_test.go index 189ce447ff85..e465d5b1b012 100644 --- a/x-pack/filebeat/input/awss3/config_test.go +++ b/x-pack/filebeat/input/awss3/config_test.go @@ -38,7 +38,6 @@ func TestConfig(t *testing.T) { SQSWaitTime: 20 * time.Second, BucketListInterval: 120 * time.Second, BucketListPrefix: "", - FIPSEnabled: false, PathStyle: false, MaxNumberOfMessages: 5, ReaderConfig: readerConfig{ diff --git a/x-pack/filebeat/input/awss3/input.go b/x-pack/filebeat/input/awss3/input.go index bf3f8cf28b24..8d673cabbac4 100644 --- a/x-pack/filebeat/input/awss3/input.go +++ b/x-pack/filebeat/input/awss3/input.go @@ -155,13 +155,11 @@ func (in *s3Input) Run(inputContext v2.Context, pipeline beat.Pipeline) error { } func (in *s3Input) createSQSReceiver(ctx v2.Context, client beat.Client) (*sqsReader, error) { - s3ServiceName := "s3" - if in.config.FIPSEnabled { - s3ServiceName = "s3-fips" - } + s3ServiceName := awscommon.CreateServiceName("s3", in.config.AWSConfig.FIPSEnabled, in.awsConfig.Region) + sqsServiceName := awscommon.CreateServiceName("sqs", in.config.AWSConfig.FIPSEnabled, in.awsConfig.Region) sqsAPI := &awsSQSAPI{ - client: sqs.New(awscommon.EnrichAWSConfigWithEndpoint(in.config.AWSConfig.Endpoint, "sqs", in.awsConfig.Region, in.awsConfig)), + client: sqs.New(awscommon.EnrichAWSConfigWithEndpoint(in.config.AWSConfig.Endpoint, sqsServiceName, in.awsConfig.Region, in.awsConfig)), queueURL: in.config.QueueURL, apiTimeout: in.config.APITimeout, visibilityTimeout: in.config.VisibilityTimeout, @@ -198,10 +196,7 @@ func (in *s3Input) createSQSReceiver(ctx v2.Context, client beat.Client) (*sqsRe } func (in *s3Input) createS3Lister(ctx v2.Context, cancelCtx context.Context, client beat.Client, persistentStore *statestore.Store, states *states) (*s3Poller, error) { - s3ServiceName := "s3" - if in.config.FIPSEnabled { - s3ServiceName = "s3-fips" - } + s3ServiceName := awscommon.CreateServiceName("s3", in.config.AWSConfig.FIPSEnabled, in.awsConfig.Region) var bucketName string var bucketID string if in.config.NonAWSBucketName != "" { diff --git a/x-pack/filebeat/module/aws/_meta/config.yml b/x-pack/filebeat/module/aws/_meta/config.yml index 1b139779b84f..35d92a11bfe0 100644 --- a/x-pack/filebeat/module/aws/_meta/config.yml +++ b/x-pack/filebeat/module/aws/_meta/config.yml @@ -63,6 +63,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + cloudwatch: enabled: false @@ -115,6 +121,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + ec2: enabled: false @@ -167,6 +179,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + elb: enabled: false @@ -219,6 +237,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + s3access: enabled: false @@ -271,6 +295,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + vpcflow: enabled: false @@ -322,3 +352,9 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: diff --git a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml index c95abb1cdc2b..48f38574e711 100644 --- a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml @@ -81,6 +81,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/aws/cloudtrail/manifest.yml b/x-pack/filebeat/module/aws/cloudtrail/manifest.yml index c0715d7647c2..1eb9d949b014 100644 --- a/x-pack/filebeat/module/aws/cloudtrail/manifest.yml +++ b/x-pack/filebeat/module/aws/cloudtrail/manifest.yml @@ -28,6 +28,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml b/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml index 5b1fb24f5617..d972e73ee317 100644 --- a/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml @@ -66,6 +66,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/aws/cloudwatch/manifest.yml b/x-pack/filebeat/module/aws/cloudwatch/manifest.yml index 0223142a6a99..7ffff3514a0f 100644 --- a/x-pack/filebeat/module/aws/cloudwatch/manifest.yml +++ b/x-pack/filebeat/module/aws/cloudwatch/manifest.yml @@ -22,6 +22,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml b/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml index 5b1fb24f5617..d972e73ee317 100644 --- a/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml @@ -66,6 +66,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/aws/ec2/manifest.yml b/x-pack/filebeat/module/aws/ec2/manifest.yml index 0223142a6a99..7ffff3514a0f 100644 --- a/x-pack/filebeat/module/aws/ec2/manifest.yml +++ b/x-pack/filebeat/module/aws/ec2/manifest.yml @@ -22,6 +22,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/module/aws/elb/config/aws-s3.yml b/x-pack/filebeat/module/aws/elb/config/aws-s3.yml index 5b1fb24f5617..d972e73ee317 100644 --- a/x-pack/filebeat/module/aws/elb/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/elb/config/aws-s3.yml @@ -66,6 +66,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/aws/elb/manifest.yml b/x-pack/filebeat/module/aws/elb/manifest.yml index da22ed1b1cc5..5f0b2d16e3dd 100644 --- a/x-pack/filebeat/module/aws/elb/manifest.yml +++ b/x-pack/filebeat/module/aws/elb/manifest.yml @@ -22,6 +22,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml b/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml index 5b1fb24f5617..d972e73ee317 100644 --- a/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml @@ -66,6 +66,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} diff --git a/x-pack/filebeat/module/aws/s3access/manifest.yml b/x-pack/filebeat/module/aws/s3access/manifest.yml index 0223142a6a99..7ffff3514a0f 100644 --- a/x-pack/filebeat/module/aws/s3access/manifest.yml +++ b/x-pack/filebeat/module/aws/s3access/manifest.yml @@ -22,6 +22,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/module/aws/vpcflow/config/input.yml b/x-pack/filebeat/module/aws/vpcflow/config/input.yml index 51b649b1e2e5..6ac1ceccf669 100644 --- a/x-pack/filebeat/module/aws/vpcflow/config/input.yml +++ b/x-pack/filebeat/module/aws/vpcflow/config/input.yml @@ -68,6 +68,10 @@ max_number_of_messages: {{ .max_number_of_messages }} proxy_url: {{ .proxy_url }} {{ end }} +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + {{ else if eq .input "file" }} type: log diff --git a/x-pack/filebeat/module/aws/vpcflow/manifest.yml b/x-pack/filebeat/module/aws/vpcflow/manifest.yml index 8871cf1cffb4..be8642f06cb9 100644 --- a/x-pack/filebeat/module/aws/vpcflow/manifest.yml +++ b/x-pack/filebeat/module/aws/vpcflow/manifest.yml @@ -22,6 +22,7 @@ var: - name: fips_enabled - name: proxy_url - name: max_number_of_messages + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/input.yml diff --git a/x-pack/filebeat/module/awsfargate/_meta/config.yml b/x-pack/filebeat/module/awsfargate/_meta/config.yml index 2318b322e9a4..8d1b03f49dc3 100644 --- a/x-pack/filebeat/module/awsfargate/_meta/config.yml +++ b/x-pack/filebeat/module/awsfargate/_meta/config.yml @@ -52,3 +52,9 @@ # Time used to sleep between AWS FilterLogEvents API calls inside the same collection period # Default api_sleep is 200 ms #var.api_sleep: 200ms + + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: diff --git a/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml b/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml index f7f3199028c4..958228e74dac 100644 --- a/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml +++ b/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml @@ -56,6 +56,14 @@ session_token: {{ .session_token }} role_arn: {{ .role_arn }} {{ end }} +{{ if .proxy_url }} +proxy_url: {{ .proxy_url }} +{{ end }} + +{{ if .ssl }} +ssl: {{ .ssl | tojson }} +{{ end }} + processors: - add_fields: target: '' diff --git a/x-pack/filebeat/module/awsfargate/log/manifest.yml b/x-pack/filebeat/module/awsfargate/log/manifest.yml index ca5fb61d0561..47fbc7697d10 100644 --- a/x-pack/filebeat/module/awsfargate/log/manifest.yml +++ b/x-pack/filebeat/module/awsfargate/log/manifest.yml @@ -20,6 +20,8 @@ var: - name: scan_frequency - name: api_timeout - name: api_sleep + - name: proxy_url + - name: ssl ingest_pipeline: ingest/pipeline.yml input: config/{{.input}}.yml diff --git a/x-pack/filebeat/modules.d/aws.yml.disabled b/x-pack/filebeat/modules.d/aws.yml.disabled index 3d34116d225e..1cde529a6d3e 100644 --- a/x-pack/filebeat/modules.d/aws.yml.disabled +++ b/x-pack/filebeat/modules.d/aws.yml.disabled @@ -66,6 +66,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + cloudwatch: enabled: false @@ -118,6 +124,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + ec2: enabled: false @@ -170,6 +182,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + elb: enabled: false @@ -222,6 +240,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + s3access: enabled: false @@ -274,6 +298,12 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: + vpcflow: enabled: false @@ -325,3 +355,9 @@ # The maximum number of messages to return from SQS. Valid values: 1 to 10. #var.max_number_of_messages: 5 + + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: diff --git a/x-pack/filebeat/modules.d/awsfargate.yml.disabled b/x-pack/filebeat/modules.d/awsfargate.yml.disabled index 225892f7fbef..57a5e4191354 100644 --- a/x-pack/filebeat/modules.d/awsfargate.yml.disabled +++ b/x-pack/filebeat/modules.d/awsfargate.yml.disabled @@ -55,3 +55,9 @@ # Time used to sleep between AWS FilterLogEvents API calls inside the same collection period # Default api_sleep is 200 ms #var.api_sleep: 200ms + + # URL to proxy AWS API calls + #var.proxy_url: http://proxy:3128 + + # Configures the SSL settings, ie. set trusted CAs, ignore certificate verification.... + #var.ssl: diff --git a/x-pack/libbeat/autodiscover/providers/aws/ec2/provider.go b/x-pack/libbeat/autodiscover/providers/aws/ec2/provider.go index 19d8c8a9784f..3cab8c3ca289 100644 --- a/x-pack/libbeat/autodiscover/providers/aws/ec2/provider.go +++ b/x-pack/libbeat/autodiscover/providers/aws/ec2/provider.go @@ -64,8 +64,9 @@ func AutodiscoverBuilder( if config.Regions == nil { // set default region to make initial aws api call awsCfg.Region = "us-west-1" + ec2ServiceName := awscommon.CreateServiceName("ec2", config.AWSConfig.FIPSEnabled, awsCfg.Region) svcEC2 := ec2.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "ec2", awsCfg.Region, awsCfg)) + config.AWSConfig.Endpoint, ec2ServiceName, awsCfg.Region, awsCfg)) completeRegionsList, err := awsauto.GetRegions(svcEC2) if err != nil { @@ -81,8 +82,9 @@ func AutodiscoverBuilder( logp.Error(errors.Wrap(err, "error loading AWS config for aws_ec2 autodiscover provider")) } awsCfg.Region = region + ec2ServiceName := awscommon.CreateServiceName("ec2", config.AWSConfig.FIPSEnabled, region) clients = append(clients, ec2.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "ec2", region, awsCfg))) + config.AWSConfig.Endpoint, ec2ServiceName, region, awsCfg))) } return internalBuilder(uuid, bus, config, newAPIFetcher(clients), keystore) diff --git a/x-pack/libbeat/autodiscover/providers/aws/elb/provider.go b/x-pack/libbeat/autodiscover/providers/aws/elb/provider.go index 39313f368710..8f39ea10ce41 100644 --- a/x-pack/libbeat/autodiscover/providers/aws/elb/provider.go +++ b/x-pack/libbeat/autodiscover/providers/aws/elb/provider.go @@ -63,8 +63,9 @@ func AutodiscoverBuilder( // Construct MetricSet with a full regions list if there is no region specified. if config.Regions == nil { + ec2ServiceName := awscommon.CreateServiceName("ec2", config.AWSConfig.FIPSEnabled, awsCfg.Region) svcEC2 := ec2.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "ec2", awsCfg.Region, awsCfg)) + config.AWSConfig.Endpoint, ec2ServiceName, awsCfg.Region, awsCfg)) completeRegionsList, err := awsauto.GetRegions(svcEC2) if err != nil { @@ -86,8 +87,9 @@ func AutodiscoverBuilder( logp.Err("error loading AWS config for aws_elb autodiscover provider: %s", err) } awsCfg.Region = region + elbServiceName := awscommon.CreateServiceName("elasticloadbalancing", config.AWSConfig.FIPSEnabled, region) clients = append(clients, elasticloadbalancingv2.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "elasticloadbalancing", region, awsCfg))) + config.AWSConfig.Endpoint, elbServiceName, region, awsCfg))) } return internalBuilder(uuid, bus, config, newAPIFetcher(clients), keystore) diff --git a/x-pack/libbeat/common/aws/credentials.go b/x-pack/libbeat/common/aws/credentials.go index 08bcbe568759..9b6d80c95289 100644 --- a/x-pack/libbeat/common/aws/credentials.go +++ b/x-pack/libbeat/common/aws/credentials.go @@ -5,8 +5,10 @@ package aws import ( + "crypto/tls" "net/http" "net/url" + "strings" awssdk "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/defaults" @@ -16,36 +18,51 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" + "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/elastic/beats/v7/libbeat/logp" ) +// OptionalGovCloudFIPS is a list of services on AWS GovCloud that is not FIPS by default. +// These services follow the standard -fips..amazonaws.com format. +var OptionalGovCloudFIPS = map[string]bool{ + "s3": true, +} + // ConfigAWS is a structure defined for AWS credentials type ConfigAWS struct { - AccessKeyID string `config:"access_key_id"` - SecretAccessKey string `config:"secret_access_key"` - SessionToken string `config:"session_token"` - ProfileName string `config:"credential_profile_name"` - SharedCredentialFile string `config:"shared_credential_file"` - Endpoint string `config:"endpoint"` - RoleArn string `config:"role_arn"` - ProxyUrl string `config:"proxy_url"` + AccessKeyID string `config:"access_key_id"` + SecretAccessKey string `config:"secret_access_key"` + SessionToken string `config:"session_token"` + ProfileName string `config:"credential_profile_name"` + SharedCredentialFile string `config:"shared_credential_file"` + Endpoint string `config:"endpoint"` + RoleArn string `config:"role_arn"` + ProxyUrl string `config:"proxy_url"` + FIPSEnabled bool `config:"fips_enabled"` + TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty" json:"ssl,omitempty"` } // InitializeAWSConfig function creates the awssdk.Config object from the provided config func InitializeAWSConfig(config ConfigAWS) (awssdk.Config, error) { AWSConfig, _ := GetAWSCredentials(config) + var proxy func(*http.Request) (*url.URL, error) if config.ProxyUrl != "" { proxyUrl, err := httpcommon.NewProxyURIFromString(config.ProxyUrl) if err != nil { return AWSConfig, err } - - httpClient := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyURL(proxyUrl.URI()), - }, - } - AWSConfig.HTTPClient = httpClient + proxy = http.ProxyURL(proxyUrl.URI()) + } + var tlsConfig *tls.Config + if config.TLS != nil { + TLSConfig, _ := tlscommon.LoadTLSConfig(config.TLS) + tlsConfig = TLSConfig.ToConfig() + } + AWSConfig.HTTPClient = &http.Client{ + Transport: &http.Transport{ + Proxy: proxy, + TLSClientConfig: tlsConfig, + }, } return AWSConfig, nil } @@ -143,17 +160,30 @@ func getRoleArn(config ConfigAWS, awsConfig awssdk.Config) awssdk.Config { // EnrichAWSConfigWithEndpoint function enabled endpoint resolver for AWS // service clients when endpoint is given in config. func EnrichAWSConfigWithEndpoint(endpoint string, serviceName string, regionName string, awsConfig awssdk.Config) awssdk.Config { + var eurl string if endpoint != "" { parsedEndpoint, _ := url.Parse(endpoint) if parsedEndpoint.Scheme != "" { awsConfig.EndpointResolver = awssdk.ResolveWithEndpointURL(endpoint) } else { if regionName == "" { - awsConfig.EndpointResolver = awssdk.ResolveWithEndpointURL("https://" + serviceName + "." + endpoint) + eurl = "https://" + serviceName + "." + endpoint } else { - awsConfig.EndpointResolver = awssdk.ResolveWithEndpointURL("https://" + serviceName + "." + regionName + "." + endpoint) + eurl = "https://" + serviceName + "." + regionName + "." + endpoint } + awsConfig.EndpointResolver = awssdk.ResolveWithEndpointURL(eurl) } } return awsConfig } + +//Create AWS service name based on Region and FIPS +func CreateServiceName(serviceName string, fipsEnabled bool, region string) string { + if fipsEnabled { + _, found := OptionalGovCloudFIPS[serviceName] + if !strings.HasPrefix(region, "us-gov-") || found { + return serviceName + "-fips" + } + } + return serviceName +} diff --git a/x-pack/libbeat/common/aws/credentials_test.go b/x-pack/libbeat/common/aws/credentials_test.go index dde6a0665e20..e3c21875385a 100644 --- a/x-pack/libbeat/common/aws/credentials_test.go +++ b/x-pack/libbeat/common/aws/credentials_test.go @@ -6,12 +6,36 @@ package aws import ( "context" + "net/http" "testing" awssdk "github.com/aws/aws-sdk-go-v2/aws" "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) +func TestInitializeAWSConfig(t *testing.T) { + inputConfig := ConfigAWS{ + AccessKeyID: "123", + SecretAccessKey: "abc", + TLS: &tlscommon.Config{ + VerificationMode: 1, + }, + ProxyUrl: "http://proxy:3128", + } + awsConfig, err := InitializeAWSConfig(inputConfig) + assert.NoError(t, err) + + retrievedAWSConfig, err := awsConfig.Credentials.Retrieve(context.Background()) + assert.NoError(t, err) + + assert.Equal(t, inputConfig.AccessKeyID, retrievedAWSConfig.AccessKeyID) + assert.Equal(t, inputConfig.SecretAccessKey, retrievedAWSConfig.SecretAccessKey) + assert.Equal(t, true, awsConfig.HTTPClient.(*http.Client).Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify) + assert.NotNil(t, awsConfig.HTTPClient.(*http.Client).Transport.(*http.Transport).Proxy) +} + func TestGetAWSCredentials(t *testing.T) { inputConfig := ConfigAWS{ AccessKeyID: "123", @@ -86,3 +110,55 @@ func TestEnrichAWSConfigWithEndpoint(t *testing.T) { }) } } + +func TestCreateServiceName(t *testing.T) { + cases := []struct { + title string + serviceName string + fips_enabled bool + region string + expectedServiceName string + }{ + { + "S3 - non-fips - us-east-1", + "s3", + false, + "us-east-1", + "s3", + }, + { + "S3 - non-fips - us-gov-east-1", + "s3", + false, + "us-gov-east-1", + "s3", + }, + { + "S3 - fips - us-gov-east-1", + "s3", + true, + "us-gov-east-1", + "s3-fips", + }, + { + "EC2 - fips - us-gov-east-1", + "ec2", + true, + "us-gov-east-1", + "ec2", + }, + { + "EC2 - fips - us-east-1", + "ec2", + true, + "us-east-1", + "ec2-fips", + }, + } + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + serviceName := CreateServiceName(c.serviceName, c.fips_enabled, c.region) + assert.Equal(t, c.expectedServiceName, serviceName) + }) + } +} diff --git a/x-pack/libbeat/docs/aws-credentials-config.asciidoc b/x-pack/libbeat/docs/aws-credentials-config.asciidoc index d7223720ad4d..63a0a0cb6395 100644 --- a/x-pack/libbeat/docs/aws-credentials-config.asciidoc +++ b/x-pack/libbeat/docs/aws-credentials-config.asciidoc @@ -18,6 +18,8 @@ services do not include a region. In `aws` module, `endpoint` config is to set the `endpoint-code` part, such as `amazonaws.com`, `amazonaws.com.cn`, `c2s.ic.gov`, `sc2s.sgov.gov`. * *proxy_url*: URL of the proxy to use to connect to AWS web services. The syntax is `http(s)://:` +* *fips_enabled*: Enabling this option changes the service names from `s3` to `s3-fips` for connecting to the correct service endpoint. For example: `s3-fips.us-gov-east-1.amazonaws.com`. All services used by Beats are FIPS compatible except for `tagging` but only certain regions are FIPS compatible. See https://aws.amazon.com/compliance/fips/ or the appropriate service page, https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html, for a full list of FIPS endpoints and regions. +* *ssl*: This specifies SSL/TLS configuration. If the ssl section is missing, the host's CAs are used for HTTPS connections. See <> for more information. [float] ==== Supported Formats diff --git a/x-pack/metricbeat/module/aws/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/_meta/docs.asciidoc index c4ceae59eeef..9a9a58887f78 100644 --- a/x-pack/metricbeat/module/aws/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/_meta/docs.asciidoc @@ -58,6 +58,24 @@ If endpoint is specified, `regions` config becomes required. For example: - ec2 ---- +* *fips_enabled* + +Enforces the use of FIPS service endpoints. See <> for more information. + +[source,yaml] +---- +- module: aws + period: 5m + fips_enabled: true + regions: + - us-east-1 + - us-east-2 + - us-west-1 + - us-west-2 + metricsets: + - ec2 +---- + The aws module comes with a predefined dashboard. For example: image::./images/metricbeat-aws-overview.png[] diff --git a/x-pack/metricbeat/module/aws/aws.go b/x-pack/metricbeat/module/aws/aws.go index 0e04ad6f4fa3..e11b5a1126a7 100644 --- a/x-pack/metricbeat/module/aws/aws.go +++ b/x-pack/metricbeat/module/aws/aws.go @@ -7,6 +7,7 @@ package aws import ( "context" "fmt" + "strings" "time" awssdk "github.com/aws/aws-sdk-go-v2/aws" @@ -105,9 +106,12 @@ func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) { awsConfig.Region = config.Regions[0] } + stsServiceName := awscommon.CreateServiceName("sts", config.AWSConfig.FIPSEnabled, awsConfig.Region) + iamServiceName := awscommon.CreateServiceName("iam", config.AWSConfig.FIPSEnabled, awsConfig.Region) + // Get IAM account id svcSts := sts.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "sts", "", awsConfig)) + config.AWSConfig.Endpoint, stsServiceName, "", awsConfig)) reqIdentity := svcSts.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{}) outputIdentity, err := reqIdentity.Send(context.TODO()) if err != nil { @@ -116,16 +120,20 @@ func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) { metricSet.AccountID = *outputIdentity.Account base.Logger().Debug("AWS Credentials belong to account ID: ", metricSet.AccountID) } - + iamRegion := "" + if strings.HasPrefix(awsConfig.Region, "us-gov-") { + iamRegion = "us-gov" + } // Get account name/alias svcIam := iam.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "iam", "", awsConfig)) + config.AWSConfig.Endpoint, iamServiceName, iamRegion, awsConfig)) metricSet.AccountName = getAccountName(svcIam, base, metricSet) // Construct MetricSet with a full regions list if config.Regions == nil { + ec2ServiceName := awscommon.CreateServiceName("ec2", config.AWSConfig.FIPSEnabled, awsConfig.Region) svcEC2 := ec2.New(awscommon.EnrichAWSConfigWithEndpoint( - config.AWSConfig.Endpoint, "ec2", "", awsConfig)) + config.AWSConfig.Endpoint, ec2ServiceName, "", awsConfig)) completeRegionsList, err := getRegions(svcEC2) if err != nil { return nil, err diff --git a/x-pack/metricbeat/module/aws/billing/billing.go b/x-pack/metricbeat/module/aws/billing/billing.go index c1c66ac05294..b7da00495a76 100644 --- a/x-pack/metricbeat/module/aws/billing/billing.go +++ b/x-pack/metricbeat/module/aws/billing/billing.go @@ -114,6 +114,12 @@ func (c CostExplorerConfig) Validate() error { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { + var config aws.Config + err := m.Module().UnpackConfig(&config) + if err != nil { + return nil + } + monitoringServiceName := awscommon.CreateServiceName("monitoring", config.AWSConfig.FIPSEnabled, regionName) // Get startDate and endDate startDate, endDate := getStartDateEndDate(m.Period) @@ -123,11 +129,11 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) error { // get cost metrics from cost explorer awsConfig := m.MetricSet.AwsConfig.Copy() svcCostExplorer := costexplorer.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "monitoring", "", awsConfig)) + m.Endpoint, monitoringServiceName, "", awsConfig)) awsConfig.Region = regionName svcCloudwatch := cloudwatch.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "monitoring", regionName, awsConfig)) + m.Endpoint, monitoringServiceName, regionName, awsConfig)) timePeriod := costexplorer.DateInterval{ Start: awssdk.String(startDate), @@ -212,10 +218,17 @@ func (m *MetricSet) getCostGroupBy(svcCostExplorer costexploreriface.ClientAPI, // get linked account IDs and names accounts := map[string]string{} + var config aws.Config + err := m.Module().UnpackConfig(&config) + if err != nil { + return nil + } if ok, _ := aws.StringInSlice("LINKED_ACCOUNT", groupByDimKeys); ok { awsConfig := m.MetricSet.AwsConfig.Copy() + organizationsServiceName := awscommon.CreateServiceName("organizations", config.AWSConfig.FIPSEnabled, regionName) + svcOrg := organizations.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "organizations", regionName, awsConfig)) + m.Endpoint, organizationsServiceName, regionName, awsConfig)) accounts = m.getAccountName(svcOrg) } diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go index 1e67fceac700..9c2f24d87acf 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go @@ -140,18 +140,25 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) error { m.logger.Debugf("listMetricDetailTotal = %s", listMetricDetailTotal) m.logger.Debugf("namespaceDetailTotal = %s", namespaceDetailTotal) + var config aws.Config + err = m.Module().UnpackConfig(&config) + if err != nil { + return err + } + // Create events based on listMetricDetailTotal from configuration if len(listMetricDetailTotal.metricsWithStats) != 0 { for _, regionName := range m.MetricSet.RegionsList { m.logger.Debugf("Collecting metrics from AWS region %s", regionName) awsConfig := m.MetricSet.AwsConfig.Copy() awsConfig.Region = regionName + monitoringServiceName := awscommon.CreateServiceName("monitoring", config.AWSConfig.FIPSEnabled, regionName) svcCloudwatch := cloudwatch.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "monitoring", regionName, awsConfig)) + m.Endpoint, monitoringServiceName, regionName, awsConfig)) svcResourceAPI := resourcegroupstaggingapi.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "tagging", regionName, awsConfig)) + m.Endpoint, "tagging", regionName, awsConfig)) //Does not support FIPS eventsWithIdentifier, err := m.createEvents(svcCloudwatch, svcResourceAPI, listMetricDetailTotal.metricsWithStats, listMetricDetailTotal.resourceTypeFilters, regionName, startTime, endTime) if err != nil { @@ -173,11 +180,12 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) error { awsConfig := m.MetricSet.AwsConfig.Copy() awsConfig.Region = regionName + monitoringServiceName := awscommon.CreateServiceName("monitoring", config.AWSConfig.FIPSEnabled, regionName) svcCloudwatch := cloudwatch.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "monitoring", regionName, awsConfig)) + m.Endpoint, monitoringServiceName, regionName, awsConfig)) svcResourceAPI := resourcegroupstaggingapi.New(awscommon.EnrichAWSConfigWithEndpoint( - m.Endpoint, "tagging", regionName, awsConfig)) + m.Endpoint, "tagging", regionName, awsConfig)) //Does not support FIPS for namespace, namespaceDetails := range namespaceDetailTotal { m.logger.Debugf("Collected metrics from namespace %s", namespace) @@ -204,7 +212,7 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) error { m.logger.Debugf("Collected number of metrics = %d", len(eventsWithIdentifier)) - err = reportEvents(addMetadata(namespace, m.Endpoint, regionName, awsConfig, eventsWithIdentifier), report) + err = reportEvents(addMetadata(namespace, m.Endpoint, regionName, awsConfig, config.AWSConfig.FIPSEnabled, eventsWithIdentifier), report) if err != nil { return errors.Wrap(err, "reportEvents failed") } diff --git a/x-pack/metricbeat/module/aws/cloudwatch/metadata.go b/x-pack/metricbeat/module/aws/cloudwatch/metadata.go index 7c0a82aafdf4..be4b637cca7c 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/metadata.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/metadata.go @@ -21,14 +21,14 @@ const ( ) // addMetadata adds metadata to the given events map based on namespace -func addMetadata(namespace string, endpoint string, regionName string, awsConfig awssdk.Config, events map[string]mb.Event) map[string]mb.Event { +func addMetadata(namespace string, endpoint string, regionName string, awsConfig awssdk.Config, fips_enabled bool, events map[string]mb.Event) map[string]mb.Event { switch namespace { case namespaceEC2: - return ec2.AddMetadata(endpoint, regionName, awsConfig, events) + return ec2.AddMetadata(endpoint, regionName, awsConfig, fips_enabled, events) case namespaceRDS: - return rds.AddMetadata(endpoint, regionName, awsConfig, events) + return rds.AddMetadata(endpoint, regionName, awsConfig, fips_enabled, events) case namespaceSQS: - return sqs.AddMetadata(endpoint, regionName, awsConfig, events) + return sqs.AddMetadata(endpoint, regionName, awsConfig, fips_enabled, events) default: return events } diff --git a/x-pack/metricbeat/module/aws/cloudwatch/metadata/ec2/ec2.go b/x-pack/metricbeat/module/aws/cloudwatch/metadata/ec2/ec2.go index 8637afd8979a..0a60351e9078 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/metadata/ec2/ec2.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/metadata/ec2/ec2.go @@ -22,9 +22,10 @@ import ( const metadataPrefix = "aws.ec2.instance." // AddMetadata adds metadata for EC2 instances from a specific region -func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, events map[string]mb.Event) map[string]mb.Event { +func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, fips_enabled bool, events map[string]mb.Event) map[string]mb.Event { + ec2ServiceName := awscommon.CreateServiceName("ec2", fips_enabled, regionName) svcEC2 := ec2.New(awscommon.EnrichAWSConfigWithEndpoint( - endpoint, "ec2", regionName, awsConfig)) + endpoint, ec2ServiceName, regionName, awsConfig)) instancesOutputs, err := getInstancesPerRegion(svcEC2) if err != nil { diff --git a/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go b/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go index e732749d0162..3e64d3079cbd 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/metadata/rds/rds.go @@ -21,9 +21,10 @@ import ( const metadataPrefix = "aws.rds.db_instance." // AddMetadata adds metadata for RDS instances from a specific region -func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, events map[string]mb.Event) map[string]mb.Event { +func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, fips_enabled bool, events map[string]mb.Event) map[string]mb.Event { + rdsServiceName := awscommon.CreateServiceName("rds", fips_enabled, regionName) svc := rds.New(awscommon.EnrichAWSConfigWithEndpoint( - endpoint, "rds", regionName, awsConfig)) + endpoint, rdsServiceName, regionName, awsConfig)) // Get DBInstance IDs per region dbDetailsMap, err := getDBInstancesPerRegion(svc) diff --git a/x-pack/metricbeat/module/aws/cloudwatch/metadata/sqs/sqs.go b/x-pack/metricbeat/module/aws/cloudwatch/metadata/sqs/sqs.go index 674731f4d4bf..812b7d3a5c73 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/metadata/sqs/sqs.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/metadata/sqs/sqs.go @@ -22,9 +22,10 @@ import ( const metadataPrefix = "aws.sqs.queue" // AddMetadata adds metadata for SQS queues from a specific region -func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, events map[string]mb.Event) map[string]mb.Event { +func AddMetadata(endpoint string, regionName string, awsConfig awssdk.Config, fips_enabled bool, events map[string]mb.Event) map[string]mb.Event { + sqsServiceName := awscommon.CreateServiceName("sqs", fips_enabled, regionName) svc := sqs.New(awscommon.EnrichAWSConfigWithEndpoint( - endpoint, "sqs", regionName, awsConfig)) + endpoint, sqsServiceName, regionName, awsConfig)) // Get queueUrls for each region queueURLs, err := getQueueUrls(svc) From 2d875e257f5be7e975c83979f45278d5ff160cb5 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 14 Dec 2021 08:42:08 +0000 Subject: [PATCH 081/172] [mergify]: forwardport into the master branch (#29390) --- .mergify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index c76feb76e984..ade2822ada92 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,7 +6,7 @@ pull_request_rules: - name: forward-port patches to master branch conditions: - merged - - label=backport-v8.1.0 + - label=forwardport-master actions: backport: assignees: From 9b893e88cfe109e64638d65c58fd75c2ff695402 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 14 Dec 2021 15:41:56 +0200 Subject: [PATCH 082/172] Add option to skip older k8s events (#29396) --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/modules/kubernetes.asciidoc | 24 +++++++++++++++++-- metricbeat/metricbeat.reference.yml | 24 +++++++++++++++++-- .../kubernetes/_meta/config.reference.yml | 24 +++++++++++++++++-- metricbeat/module/kubernetes/_meta/config.yml | 19 ++++++++++++++- metricbeat/module/kubernetes/event/config.go | 2 ++ metricbeat/module/kubernetes/event/event.go | 6 +++-- metricbeat/modules.d/kubernetes.yml.disabled | 19 ++++++++++++++- x-pack/metricbeat/metricbeat.reference.yml | 24 +++++++++++++++++-- 9 files changed, 131 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ba9d9007541f..02d272b963c6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -282,6 +282,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove required for region/zone and make stackdriver a metricset in googlecloud. {issue}16785[16785] {pull}18398[18398] - Add memory metrics into compute googlecloud. {pull}18802[18802] - Preliminary AIX support {pull}27954[27954] +- Add option to skip older k8s events {pull}29396[29396] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] *Packetbeat* diff --git a/metricbeat/docs/modules/kubernetes.asciidoc b/metricbeat/docs/modules/kubernetes.asciidoc index 52f0b07a75fc..dd603e9f056e 100644 --- a/metricbeat/docs/modules/kubernetes.asciidoc +++ b/metricbeat/docs/modules/kubernetes.asciidoc @@ -281,6 +281,28 @@ metricbeat.modules: # qps: 5 # burst: 10 +# Kubernetes Events +- module: kubernetes + enabled: true + metricsets: + - event + period: 10s + # Skip events older than Metricbeat's statup time is enabled by default. + # Setting to false the skip_older setting will stop filtering older events. + # This setting is also useful went Event's timestamps are not populated properly. + #skip_older: false + # If kube_config is not set, KUBECONFIG environment variable will be checked + # and if not present it will fall back to InCluster + #kube_config: ~/.kube/config + # Set the namespace to watch for events + #namespace: staging + # Set the sync period of the watchers + #sync_period: 10m + # Kubernetes client QPS and burst can be configured additionally + #kube_client_options: + # qps: 5 + # burst: 10 + # Kubernetes API server # (when running metricbeat as a deployment) - module: kubernetes @@ -293,8 +315,6 @@ metricbeat.modules: - /var/run/secrets/kubernetes.io/serviceaccount/ca.crt period: 30s - - # Kubernetes proxy server # (when running metricbeat locally at hosts or as a daemonset + host network) - module: kubernetes diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 46adc5cfdb4f..d0ef9b6f6d3e 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -559,6 +559,28 @@ metricbeat.modules: # qps: 5 # burst: 10 +# Kubernetes Events +- module: kubernetes + enabled: true + metricsets: + - event + period: 10s + # Skip events older than Metricbeat's statup time is enabled by default. + # Setting to false the skip_older setting will stop filtering older events. + # This setting is also useful went Event's timestamps are not populated properly. + #skip_older: false + # If kube_config is not set, KUBECONFIG environment variable will be checked + # and if not present it will fall back to InCluster + #kube_config: ~/.kube/config + # Set the namespace to watch for events + #namespace: staging + # Set the sync period of the watchers + #sync_period: 10m + # Kubernetes client QPS and burst can be configured additionally + #kube_client_options: + # qps: 5 + # burst: 10 + # Kubernetes API server # (when running metricbeat as a deployment) - module: kubernetes @@ -571,8 +593,6 @@ metricbeat.modules: - /var/run/secrets/kubernetes.io/serviceaccount/ca.crt period: 30s - - # Kubernetes proxy server # (when running metricbeat locally at hosts or as a daemonset + host network) - module: kubernetes diff --git a/metricbeat/module/kubernetes/_meta/config.reference.yml b/metricbeat/module/kubernetes/_meta/config.reference.yml index 2a9f4601f869..3a6e22af69b9 100644 --- a/metricbeat/module/kubernetes/_meta/config.reference.yml +++ b/metricbeat/module/kubernetes/_meta/config.reference.yml @@ -82,6 +82,28 @@ # qps: 5 # burst: 10 +# Kubernetes Events +- module: kubernetes + enabled: true + metricsets: + - event + period: 10s + # Skip events older than Metricbeat's statup time is enabled by default. + # Setting to false the skip_older setting will stop filtering older events. + # This setting is also useful went Event's timestamps are not populated properly. + #skip_older: false + # If kube_config is not set, KUBECONFIG environment variable will be checked + # and if not present it will fall back to InCluster + #kube_config: ~/.kube/config + # Set the namespace to watch for events + #namespace: staging + # Set the sync period of the watchers + #sync_period: 10m + # Kubernetes client QPS and burst can be configured additionally + #kube_client_options: + # qps: 5 + # burst: 10 + # Kubernetes API server # (when running metricbeat as a deployment) - module: kubernetes @@ -94,8 +116,6 @@ - /var/run/secrets/kubernetes.io/serviceaccount/ca.crt period: 30s - - # Kubernetes proxy server # (when running metricbeat locally at hosts or as a daemonset + host network) - module: kubernetes diff --git a/metricbeat/module/kubernetes/_meta/config.yml b/metricbeat/module/kubernetes/_meta/config.yml index 94b0a00427fe..9e8eaee745cc 100644 --- a/metricbeat/module/kubernetes/_meta/config.yml +++ b/metricbeat/module/kubernetes/_meta/config.yml @@ -58,7 +58,24 @@ # hosts: ["kube-state-metrics:8080"] # add_metadata: true -# Kubernetes events +# Kubernetes Events #- module: kubernetes +# enabled: true # metricsets: # - event +# period: 10s +# # Skip events older than Metricbeat's statup time is enabled by default. +# # Setting to false the skip_older setting will stop filtering older events. +# # This setting is also useful went Event's timestamps are not populated properly. +# skip_older: false +# # If kube_config is not set, KUBECONFIG environment variable will be checked +# # and if not present it will fall back to InCluster +# kube_config: ~/.kube/config +# # Set the namespace to watch for events +# namespace: staging +# # Set the sync period of the watchers +# sync_period: 10m +# # Kubernetes client QPS and burst can be configured additionally +# kube_client_options: +# qps: 5 +# burst: 10 diff --git a/metricbeat/module/kubernetes/event/config.go b/metricbeat/module/kubernetes/event/config.go index 07e9e7da64e5..be9b0c21a157 100644 --- a/metricbeat/module/kubernetes/event/config.go +++ b/metricbeat/module/kubernetes/event/config.go @@ -30,6 +30,7 @@ type kubeEventsConfig struct { SyncPeriod time.Duration `config:"sync_period"` LabelsDedot bool `config:"labels.dedot"` AnnotationsDedot bool `config:"annotations.dedot"` + SkipOlder bool `config:"skip_older"` } type Enabled struct { @@ -41,5 +42,6 @@ func defaultKubernetesEventsConfig() kubeEventsConfig { SyncPeriod: 10 * time.Minute, LabelsDedot: true, AnnotationsDedot: true, + SkipOlder: true, } } diff --git a/metricbeat/module/kubernetes/event/event.go b/metricbeat/module/kubernetes/event/event.go index a1504b6ff059..723e1331e618 100644 --- a/metricbeat/module/kubernetes/event/event.go +++ b/metricbeat/module/kubernetes/event/event.go @@ -41,6 +41,7 @@ type MetricSet struct { watcher kubernetes.Watcher watchOptions kubernetes.WatchOptions dedotConfig dedotConfig + skipOlder bool } // dedotConfig defines LabelsDedot and AnnotationsDedot. @@ -87,6 +88,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { dedotConfig: dedotConfig, watcher: watcher, watchOptions: watchOptions, + skipOlder: config.SkipOlder, }, nil } @@ -104,10 +106,10 @@ func (m *MetricSet) Run(reporter mb.PushReporter) { DeleteFunc: nil, } m.watcher.AddEventHandler(kubernetes.FilteringResourceEventHandler{ - // skip events happened before watch FilterFunc: func(obj interface{}) bool { eve := obj.(*kubernetes.Event) - if kubernetes.Time(&eve.LastTimestamp).Before(now) { + // if skipOlder, skip events happened before watch + if m.skipOlder && kubernetes.Time(&eve.LastTimestamp).Before(now) { return false } return true diff --git a/metricbeat/modules.d/kubernetes.yml.disabled b/metricbeat/modules.d/kubernetes.yml.disabled index 144d13fb301b..fcfeec148758 100644 --- a/metricbeat/modules.d/kubernetes.yml.disabled +++ b/metricbeat/modules.d/kubernetes.yml.disabled @@ -61,7 +61,24 @@ # hosts: ["kube-state-metrics:8080"] # add_metadata: true -# Kubernetes events +# Kubernetes Events #- module: kubernetes +# enabled: true # metricsets: # - event +# period: 10s +# # Skip events older than Metricbeat's statup time is enabled by default. +# # Setting to false the skip_older setting will stop filtering older events. +# # This setting is also useful went Event's timestamps are not populated properly. +# skip_older: false +# # If kube_config is not set, KUBECONFIG environment variable will be checked +# # and if not present it will fall back to InCluster +# kube_config: ~/.kube/config +# # Set the namespace to watch for events +# namespace: staging +# # Set the sync period of the watchers +# sync_period: 10m +# # Kubernetes client QPS and burst can be configured additionally +# kube_client_options: +# qps: 5 +# burst: 10 diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index c89b9288c472..e09b1c7989b0 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -931,6 +931,28 @@ metricbeat.modules: # qps: 5 # burst: 10 +# Kubernetes Events +- module: kubernetes + enabled: true + metricsets: + - event + period: 10s + # Skip events older than Metricbeat's statup time is enabled by default. + # Setting to false the skip_older setting will stop filtering older events. + # This setting is also useful went Event's timestamps are not populated properly. + #skip_older: false + # If kube_config is not set, KUBECONFIG environment variable will be checked + # and if not present it will fall back to InCluster + #kube_config: ~/.kube/config + # Set the namespace to watch for events + #namespace: staging + # Set the sync period of the watchers + #sync_period: 10m + # Kubernetes client QPS and burst can be configured additionally + #kube_client_options: + # qps: 5 + # burst: 10 + # Kubernetes API server # (when running metricbeat as a deployment) - module: kubernetes @@ -943,8 +965,6 @@ metricbeat.modules: - /var/run/secrets/kubernetes.io/serviceaccount/ca.crt period: 30s - - # Kubernetes proxy server # (when running metricbeat locally at hosts or as a daemonset + host network) - module: kubernetes From fcb7b81faaece55703c443a32e26b94a1d1f6164 Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Tue, 14 Dec 2021 11:28:23 -0800 Subject: [PATCH 083/172] elastic-agent elasticsearch CA fingerprint support (#29128) * initial commit * Update Fingerprint method * Switch to using newly added CATrustedFingerprint attribute * rename flag * Fix broken flag * Add CHANGELOG * Add container support --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../elastic-agent/pkg/agent/cmd/container.go | 4 +++ x-pack/elastic-agent/pkg/agent/cmd/enroll.go | 8 ++++++ .../elastic-agent/pkg/agent/cmd/enroll_cmd.go | 17 +++++++++--- .../pkg/agent/cmd/setup_config.go | 26 ++++++++++--------- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index b75a405d4bba..e12cade2afb4 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -151,4 +151,5 @@ - Add diagnostics collect command to gather beat metadata, config, policy, and logs and bundle it into an archive. {pull}28461[28461] - Add `KIBANA_FLEET_SERVICE_TOKEN` to Elastic Agent container. {pull}28096[28096] - Allow pprof endpoints for elastic-agent or beats if enabled. {pull}28983[28983] {pull}29155[29155] +- Add --fleet-server-es-ca-trusted-fingerprint flag to allow agent/fleet-server to work with elasticsearch clusters using self signed certs. {pull}29128[29128] - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index e0f9f3dcfb70..d72b0128430e 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -96,6 +96,7 @@ The following actions are possible and grouped based on the actions. FLEET_SERVER_ELASTICSEARCH_USERNAME - elasticsearch username for Fleet Server [$ELASTICSEARCH_USERNAME] FLEET_SERVER_ELASTICSEARCH_PASSWORD - elasticsearch password for Fleet Server [$ELASTICSEARCH_PASSWORD] FLEET_SERVER_ELASTICSEARCH_CA - path to certificate authority to use with communicate with elasticsearch [$ELASTICSEARCH_CA] + FLEET_SERVER_ELASTICSEARCH_CA_TRUSTED_FINGERPRINT - The sha-256 fingerprint value of the certificate authority to trust FLEET_SERVER_ELASTICSEARCH_INSECURE - disables cert validation for communication with Elasticsearch FLEET_SERVER_SERVICE_TOKEN - service token to use for communication with elasticsearch FLEET_SERVER_POLICY_ID - policy ID for Fleet Server to use for itself ("Default Fleet Server policy" used when undefined) @@ -359,6 +360,9 @@ func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string, if cfg.FleetServer.Elasticsearch.CA != "" { args = append(args, "--fleet-server-es-ca", cfg.FleetServer.Elasticsearch.CA) } + if cfg.FleetServer.Elasticsearch.CATrustedFingerprint != "" { + args = append(args, "--fleet-server-es-ca-trusted-fingerprint", cfg.FleetServer.Elasticsearch.CATrustedFingerprint) + } if cfg.FleetServer.Host != "" { args = append(args, "--fleet-server-host", cfg.FleetServer.Host) } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go index 126161fa4c4a..6a66b4fdfc1c 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go @@ -53,6 +53,7 @@ func addEnrollFlags(cmd *cobra.Command) { cmd.Flags().StringP("enrollment-token", "t", "", "Enrollment token to use to enroll Agent into Fleet") cmd.Flags().StringP("fleet-server-es", "", "", "Start and run a Fleet Server along side this Elastic Agent connecting to the provided elasticsearch") cmd.Flags().StringP("fleet-server-es-ca", "", "", "Path to certificate authority to use with communicate with elasticsearch") + cmd.Flags().StringP("fleet-server-es-ca-trusted-fingerprint", "", "", "Elasticsearch certificate authority's SHA256 fingerprint") cmd.Flags().BoolP("fleet-server-es-insecure", "", false, "Disables validation of certificates") cmd.Flags().StringP("fleet-server-service-token", "", "", "Service token to use for communication with elasticsearch") cmd.Flags().StringP("fleet-server-policy", "", "", "Start and run a Fleet Server on this specific policy") @@ -103,6 +104,7 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string } fServer, _ := cmd.Flags().GetString("fleet-server-es") fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-es-ca") + fElasticSearchCASHA256, _ := cmd.Flags().GetString("fleet-server-es-ca-trusted-fingerprint") fElasticSearchInsecure, _ := cmd.Flags().GetBool("fleet-server-es-insecure") fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token") fPolicy, _ := cmd.Flags().GetString("fleet-server-policy") @@ -140,6 +142,10 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, "--fleet-server-es-ca") args = append(args, fElasticSearchCA) } + if fElasticSearchCASHA256 != "" { + args = append(args, "--fleet-server-es-ca-trusted-fingerprint") + args = append(args, fElasticSearchCASHA256) + } if fServiceToken != "" { args = append(args, "--fleet-server-service-token") args = append(args, fServiceToken) @@ -285,6 +291,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { enrollmentToken, _ := cmd.Flags().GetString("enrollment-token") fServer, _ := cmd.Flags().GetString("fleet-server-es") fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-es-ca") + fElasticSearchCASHA256, _ := cmd.Flags().GetString("fleet-server-es-ca-trusted-fingerprint") fElasticSearchInsecure, _ := cmd.Flags().GetBool("fleet-server-es-insecure") fHeaders, _ := cmd.Flags().GetStringSlice("header") fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token") @@ -326,6 +333,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { FleetServer: enrollCmdFleetServerOption{ ConnStr: fServer, ElasticsearchCA: fElasticSearchCA, + ElasticsearchCASHA256: fElasticSearchCASHA256, ElasticsearchInsecure: fElasticSearchInsecure, ServiceToken: fServiceToken, PolicyID: fPolicy, diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go index 25365c9afe92..0023d83fde0d 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go @@ -77,6 +77,7 @@ type enrollCmd struct { type enrollCmdFleetServerOption struct { ConnStr string ElasticsearchCA string + ElasticsearchCASHA256 string ElasticsearchInsecure bool ServiceToken string PolicyID string @@ -110,6 +111,7 @@ type enrollCmdOption struct { FleetServer enrollCmdFleetServerOption `yaml:"-"` } +// remoteConfig returns the configuration used to connect the agent to a fleet process. func (e *enrollCmdOption) remoteConfig() (remote.Config, error) { cfg, err := remote.NewConfigFromURL(e.URL) if err != nil { @@ -311,7 +313,7 @@ func (c *enrollCmd) fleetServerBootstrap(ctx context.Context, persistentConfig m c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, - c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, + c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.ElasticsearchCASHA256, c.options.FleetServer.Headers, c.options.ProxyURL, c.options.ProxyDisabled, @@ -517,7 +519,7 @@ func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]inte c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, - c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, + c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.ElasticsearchCASHA256, c.options.FleetServer.Headers, c.options.ProxyURL, c.options.ProxyDisabled, c.options.ProxyHeaders, c.options.FleetServer.ElasticsearchInsecure, @@ -853,7 +855,7 @@ func storeAgentInfo(s saver, reader io.Reader) error { func createFleetServerBootstrapConfig( connStr, serviceToken, policyID, host string, port uint16, internalPort uint16, - cert, key, esCA string, + cert, key, esCA, esCASHA256 string, headers map[string]string, proxyURL string, proxyDisabled bool, @@ -875,6 +877,15 @@ func createFleetServerBootstrapConfig( es.TLS.CAs = []string{esCA} } } + if esCASHA256 != "" { + if es.TLS == nil { + es.TLS = &tlscommon.Config{ + CATrustedFingerprint: esCASHA256, + } + } else { + es.TLS.CATrustedFingerprint = esCASHA256 + } + } if host == "" { host = defaultFleetServerHost } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go index 6b7e1edf8b3d..b33c0f8fa8ee 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go @@ -40,12 +40,13 @@ type fleetServerConfig struct { } type elasticsearchConfig struct { - CA string `config:"ca"` - Host string `config:"host"` - Username string `config:"username"` - Password string `config:"password"` - ServiceToken string `config:"service_token"` - Insecure bool `config:"insecure"` + CA string `config:"ca"` + CATrustedFingerprint string `config:"ca_trusted_fingerprint"` + Host string `config:"host"` + Username string `config:"username"` + Password string `config:"password"` + ServiceToken string `config:"service_token"` + Insecure bool `config:"insecure"` } type kibanaConfig struct { @@ -91,12 +92,13 @@ func defaultAccessConfig() (setupConfig, error) { Cert: envWithDefault("", "FLEET_SERVER_CERT"), CertKey: envWithDefault("", "FLEET_SERVER_CERT_KEY"), Elasticsearch: elasticsearchConfig{ - Host: envWithDefault("http://elasticsearch:9200", "FLEET_SERVER_ELASTICSEARCH_HOST", "ELASTICSEARCH_HOST"), - Username: envWithDefault("elastic", "FLEET_SERVER_ELASTICSEARCH_USERNAME", "ELASTICSEARCH_USERNAME"), - Password: envWithDefault("changeme", "FLEET_SERVER_ELASTICSEARCH_PASSWORD", "ELASTICSEARCH_PASSWORD"), - ServiceToken: envWithDefault("", "FLEET_SERVER_SERVICE_TOKEN"), - CA: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA", "ELASTICSEARCH_CA"), - Insecure: envBool("FLEET_SERVER_ELASTICSEARCH_INSECURE"), + Host: envWithDefault("http://elasticsearch:9200", "FLEET_SERVER_ELASTICSEARCH_HOST", "ELASTICSEARCH_HOST"), + Username: envWithDefault("elastic", "FLEET_SERVER_ELASTICSEARCH_USERNAME", "ELASTICSEARCH_USERNAME"), + Password: envWithDefault("changeme", "FLEET_SERVER_ELASTICSEARCH_PASSWORD", "ELASTICSEARCH_PASSWORD"), + ServiceToken: envWithDefault("", "FLEET_SERVER_SERVICE_TOKEN"), + CA: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA", "ELASTICSEARCH_CA"), + CATrustedFingerprint: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA_TRUSTED_FINGERPRINT"), + Insecure: envBool("FLEET_SERVER_ELASTICSEARCH_INSECURE"), }, Enable: envBool("FLEET_SERVER_ENABLE"), Host: envWithDefault("", "FLEET_SERVER_HOST"), From f5e0ec4445a7f9ba2860899e06ddaca16a96ceb0 Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Tue, 14 Dec 2021 12:00:58 -0800 Subject: [PATCH 084/172] elastic-agent diagnostics pprof (#28798) * Allow -httpprof to bind to sockets/pipes * Enable pprof debug endpoint on socket for agent and beats Force the elastic-agent and all beats that it starts to run the http/pprof listener on a local socket. * Add new Pprof command to control.proto * Add pprof option to diagnostics collect * Fix linting issues * Add diagonstics pprof command allow pprof to collect from agent * Revert debug socket changes * Cleanup timeout handling Change pprof timeouts from 2*pprofDur to 30s+pprofDur. Remove timeouts from the socket requester client as cancellations for long running requests will be handled by the passed ctx. * Fix linting issue add timeout flag Fix linting issues with new command. Add a timeout flag for when pprof info is gathered. Flag will let users specify the command timeout value. This value whould be greater then the pprof-duration as it needs to gather and process pprof data. * Add more command help text. * Add CHANGELOG * move spec collection for routes to fn * add monitoringCfg reference to control server * elastic-agent server only processes pprof requests when enabled * Fix error message fix commands only on elastic-agent * Add pprof fleet.yml, fix nil reference * Change pprof setting name to monitoring.pprof.enabled Chagne the setting in elastic agent from agent.monioring.pprof to agent.monitoring.pprof.enabled so that policy updates (such as the one that occurs when the agent is starting in fleet mode) do not use the default false value if the user has injected the ssetting into fleet.yml --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 2 + .../_meta/config/common.p2.yml.tmpl | 2 +- .../_meta/config/common.reference.p2.yml.tmpl | 2 +- .../config/elastic-agent.docker.yml.tmpl | 2 +- x-pack/elastic-agent/control.proto | 42 ++ x-pack/elastic-agent/elastic-agent.docker.yml | 2 +- .../elastic-agent/elastic-agent.reference.yml | 2 +- x-pack/elastic-agent/elastic-agent.yml | 2 +- .../handlers/handler_action_policy_change.go | 7 +- .../pkg/agent/cmd/diagnostics.go | 200 ++++++- x-pack/elastic-agent/pkg/agent/cmd/run.go | 3 +- .../pkg/agent/control/client/client.go | 36 ++ .../pkg/agent/control/proto/control.pb.go | 513 +++++++++++++++--- .../pkg/agent/control/server/server.go | 352 +++++++++--- .../core/monitoring/beats/beats_monitor.go | 6 +- .../pkg/core/monitoring/config/config.go | 10 +- 16 files changed, 1031 insertions(+), 152 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index e12cade2afb4..374c63acdb05 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -150,6 +150,8 @@ - Add diagnostics command to gather beat metadata. {pull}28265[28265] - Add diagnostics collect command to gather beat metadata, config, policy, and logs and bundle it into an archive. {pull}28461[28461] - Add `KIBANA_FLEET_SERVICE_TOKEN` to Elastic Agent container. {pull}28096[28096] +- Enable pprof endpoints for beats processes. Allow pprof endpoints for elastic-agent if enabled. {pull}28983[28983] +- Add `--pprof` flag to `elastic-agent diagnostics` and an `elastic-agent pprof` command to allow operators to gather pprof data from the agent and beats running under it. {pull}28798[28798] - Allow pprof endpoints for elastic-agent or beats if enabled. {pull}28983[28983] {pull}29155[29155] - Add --fleet-server-es-ca-trusted-fingerprint flag to allow agent/fleet-server to work with elasticsearch clusters using self signed certs. {pull}29128[29128] - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] diff --git a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl index de16df8ea7f7..e8f4c31e8e18 100644 --- a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl @@ -35,7 +35,7 @@ inputs: # metrics: true # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl index 43e484646306..8a3ef0773578 100644 --- a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl index 69a80678db87..17201aa6dcea 100644 --- a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/control.proto b/x-pack/elastic-agent/control.proto index 26b6552c395c..53168f872ba0 100644 --- a/x-pack/elastic-agent/control.proto +++ b/x-pack/elastic-agent/control.proto @@ -29,6 +29,19 @@ enum ActionStatus { FAILURE = 1; } +// pprof endpoint that can be requested. +enum PprofOption { + ALLOCS = 0; + BLOCK = 1; + CMDLINE = 2; + GOROUTINE = 3; + HEAP = 4; + MUTEX = 5; + PROFILE = 6; + THREADCREATE = 7; + TRACE = 8; +} + // Empty message. message Empty { } @@ -128,6 +141,32 @@ message ProcMetaResponse { repeated ProcMeta procs = 1; } +// PprofRequest is a request for pprof data from and http/pprof endpoint. +message PprofRequest { + // The profiles that are requested + repeated PprofOption pprofType = 1; + // A string representing a time.Duration to apply to trace, and profile options. + string traceDuration = 2; + // The application that will be profiled, if empty all applications are profiled. + string appName = 3; + // The route key to match for profiling, if empty all are profiled. + string routeKey = 4; +} + +// PprofResult is the result of a pprof request for a given application/route key. +message PprofResult { + string appName = 1; + string routeKey = 2; + PprofOption pprofType = 3; + bytes result = 4; + string error = 5; +} + +// PprofResponse is a wrapper to return all pprof responses. +message PprofResponse { + repeated PprofResult results = 1; +} + service ElasticAgentControl { // Fetches the currently running version of the Elastic Agent. rpc Version(Empty) returns (VersionResponse); @@ -143,4 +182,7 @@ service ElasticAgentControl { // Gather all running process metadata. rpc ProcMeta(Empty) returns (ProcMetaResponse); + + // Gather requested pprof data from specified applications. + rpc Pprof(PprofRequest) returns (PprofResponse); } diff --git a/x-pack/elastic-agent/elastic-agent.docker.yml b/x-pack/elastic-agent/elastic-agent.docker.yml index 9bf7307aacfd..b7d5ff2017ea 100644 --- a/x-pack/elastic-agent/elastic-agent.docker.yml +++ b/x-pack/elastic-agent/elastic-agent.docker.yml @@ -109,7 +109,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.reference.yml b/x-pack/elastic-agent/elastic-agent.reference.yml index 67922a1d89cc..da04df95ea81 100644 --- a/x-pack/elastic-agent/elastic-agent.reference.yml +++ b/x-pack/elastic-agent/elastic-agent.reference.yml @@ -115,7 +115,7 @@ inputs: # metrics: false # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/elastic-agent.yml b/x-pack/elastic-agent/elastic-agent.yml index d40b6518e8d5..802df992ba7c 100644 --- a/x-pack/elastic-agent/elastic-agent.yml +++ b/x-pack/elastic-agent/elastic-agent.yml @@ -41,7 +41,7 @@ inputs: # metrics: true # # exposes /debug/pprof/ endpoints # # recommended that these endpoints are only enabled if the monitoring endpoint is set to localhost -# pprof: false +# pprof.enabled: false # # exposes agent metrics using http, by default sockets and named pipes are used # http: # # enables http endpoint diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go index f14ec7aea81f..e00ccfc844ba 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go @@ -197,9 +197,10 @@ func fleetToReader(agentInfo *info.AgentInfo, cfg *configuration.Configuration) configToStore := map[string]interface{}{ "fleet": cfg.Fleet, "agent": map[string]interface{}{ - "id": agentInfo.AgentID(), - "logging.level": cfg.Settings.LoggingConfig.Level, - "monitoring.http": cfg.Settings.MonitoringConfig.HTTP, + "id": agentInfo.AgentID(), + "logging.level": cfg.Settings.LoggingConfig.Level, + "monitoring.http": cfg.Settings.MonitoringConfig.HTTP, + "monitoring.pprof": cfg.Settings.MonitoringConfig.Pprof, }, } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/diagnostics.go b/x-pack/elastic-agent/pkg/agent/cmd/diagnostics.go index e90e4ab13c15..b32edf6df2da 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/diagnostics.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/diagnostics.go @@ -25,6 +25,7 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/control/client" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/control/proto" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/cli" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config/operations" @@ -63,6 +64,7 @@ func newDiagnosticsCommand(s []string, streams *cli.IOStreams) *cobra.Command { cmd.Flags().String("output", "human", "Output the diagnostics information in either human, json, or yaml (default: human)") cmd.AddCommand(newDiagnosticsCollectCommandWithArgs(s, streams)) + cmd.AddCommand(newDiagnosticsPprofCommandWithArgs(s, streams)) return cmd } @@ -72,7 +74,7 @@ func newDiagnosticsCollectCommandWithArgs(_ []string, streams *cli.IOStreams) *c Use: "collect", Short: "Collect diagnostics information from the elastic-agent and write it to a zip archive.", Long: "Collect diagnostics information from the elastic-agent and write it to a zip archive.\nNote that any credentials will appear in plain text.", - Args: cobra.MaximumNArgs(1), + Args: cobra.MaximumNArgs(3), RunE: func(c *cobra.Command, args []string) error { file, _ := c.Flags().GetString("file") @@ -89,12 +91,58 @@ func newDiagnosticsCollectCommandWithArgs(_ []string, streams *cli.IOStreams) *c return fmt.Errorf("unsupported output: %s", output) } - return diagnosticsCollectCmd(streams, file, output) + pprof, _ := c.Flags().GetBool("pprof") + d, _ := c.Flags().GetDuration("pprof-duration") + // get the command timeout value only if one is set explicitly. + // otherwise a value of 30s + pprof-duration will be used. + var timeout time.Duration + if c.Flags().Changed("timeout") { + timeout, _ = c.Flags().GetDuration("timeout") + } + + return diagnosticsCollectCmd(streams, file, output, pprof, d, timeout) }, } cmd.Flags().StringP("file", "f", "", "name of the output diagnostics zip archive") cmd.Flags().String("output", "yaml", "Output the collected information in either json, or yaml (default: yaml)") // replace output flag with different options + cmd.Flags().Bool("pprof", false, "Collect all pprof data from all running applications.") + cmd.Flags().Duration("pprof-duration", time.Second*30, "The duration to collect trace and profiling data from the debug/pprof endpoints. (default: 30s)") + cmd.Flags().Duration("timeout", time.Second*30, "The timeout for the diagnostics collect command, will be either 30s or 30s+pprof-duration by default. Should be longer then pprof-duration when pprof is enabled as the command needs time to process/archive the response.") + + return cmd +} + +func newDiagnosticsPprofCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra.Command { + cmd := &cobra.Command{ + Use: "pprof", + Short: "Collect pprof information from a running process.", + Long: "Collect pprof information from the elastic-agent or one of its processes and write to stdout or a file.\nBy default it will gather a 30s profile of the elastic-agent and output on stdout.", + Args: cobra.MaximumNArgs(5), + RunE: func(c *cobra.Command, args []string) error { + file, _ := c.Flags().GetString("file") + pprofType, _ := c.Flags().GetString("pprof-type") + d, _ := c.Flags().GetDuration("pprof-duration") + // get the command timeout value only if one is set explicitly. + // otherwise a value of 30s + pprof-duration will be used. + var timeout time.Duration + if c.Flags().Changed("timeout") { + timeout, _ = c.Flags().GetDuration("timeout") + } + + pprofApp, _ := c.Flags().GetString("pprof-application") + pprofRK, _ := c.Flags().GetString("pprof-route-key") + + return diagnosticsPprofCmd(streams, d, timeout, file, pprofType, pprofApp, pprofRK) + }, + } + + cmd.Flags().StringP("file", "f", "", "name of the output file, stdout if unspecified.") + cmd.Flags().String("pprof-type", "profile", "Collect all pprof data from all running applications. Select one of [allocs, block, cmdline, goroutine, heap, mutex, profile, threadcreate, trace]") + cmd.Flags().Duration("pprof-duration", time.Second*30, "The duration to collect trace and profiling data from the debug/pprof endpoints. (default: 30s)") + cmd.Flags().Duration("timeout", time.Second*60, "The timeout for the pprof collect command, defaults to 30s+pprof-duration by default. Should be longer then pprof-duration as the command needs time to process the response.") + cmd.Flags().String("pprof-application", "elastic-agent", "Application name to collect pprof data from.") + cmd.Flags().String("pprof-route-key", "default", "Route key to collect pprof data from.") return cmd } @@ -127,14 +175,22 @@ func diagnosticCmd(streams *cli.IOStreams, cmd *cobra.Command, args []string) er return outputFunc(streams.Out, diag) } -func diagnosticsCollectCmd(streams *cli.IOStreams, fileName, outputFormat string) error { +func diagnosticsCollectCmd(streams *cli.IOStreams, fileName, outputFormat string, pprof bool, pprofDur, cmdTimeout time.Duration) error { err := tryContainerLoadPaths() if err != nil { return err } ctx := handleSignal(context.Background()) - innerCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + // set command timeout to 30s or 30s+pprofDur if no timeout is specified + if cmdTimeout == time.Duration(0) { + cmdTimeout = time.Second * 30 + if pprof { + cmdTimeout += pprofDur + } + + } + innerCtx, cancel := context.WithTimeout(ctx, cmdTimeout) defer cancel() diag, err := getDiagnostics(innerCtx) @@ -151,7 +207,15 @@ func diagnosticsCollectCmd(streams *cli.IOStreams, fileName, outputFormat string return fmt.Errorf("unable to gather config data: %w", err) } - err = createZip(fileName, outputFormat, diag, cfg) + var pprofData map[string][]client.ProcPProf = nil + if pprof { + pprofData, err = getAllPprof(innerCtx, pprofDur) + if err != nil { + return fmt.Errorf("unable to gather pprof data: %w", err) + } + } + + err = createZip(fileName, outputFormat, diag, cfg, pprofData) if err != nil { return fmt.Errorf("unable to create archive %q: %w", fileName, err) } @@ -160,6 +224,68 @@ func diagnosticsCollectCmd(streams *cli.IOStreams, fileName, outputFormat string return nil } +func diagnosticsPprofCmd(streams *cli.IOStreams, dur, cmdTimeout time.Duration, outFile, pType, appName, rk string) error { + pt, ok := proto.PprofOption_value[strings.ToUpper(pType)] + if !ok { + return fmt.Errorf("unknown pprof-type %q, select one of [allocs, block, cmdline, goroutine, heap, mutex, profile, threadcreate, trace]", pType) + } + + // the elastic-agent application does not have a route key + if appName == "elastic-agent" { + rk = "" + } + + ctx := handleSignal(context.Background()) + // set cmdTimeout to 30s+dur if not set. + if cmdTimeout == time.Duration(0) { + cmdTimeout = time.Second*30 + dur + } + innerCtx, cancel := context.WithTimeout(ctx, cmdTimeout) + defer cancel() + + daemon := client.New() + err := daemon.Connect(ctx) + if err != nil { + return err + } + + pprofData, err := daemon.Pprof(innerCtx, dur, []proto.PprofOption{proto.PprofOption(pt)}, appName, rk) + if err != nil { + return err + } + + // validate response + pArr, ok := pprofData[proto.PprofOption_name[pt]] + if !ok { + return fmt.Errorf("route key %q not found in response data (map length: %d)", rk, len(pprofData)) + } + if len(pArr) != 1 { + return fmt.Errorf("pprof type length 1 expected, recieved %d", len(pArr)) + } + res := pArr[0] + + if res.Error != "" { + return fmt.Errorf(res.Error) + } + + // handle result + if outFile != "" { + f, err := os.Create(outFile) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write(res.Result) + if err != nil { + return err + } + fmt.Fprintf(streams.Out, "pprof data written to %s\n", outFile) + return nil + } + _, err = streams.Out.Write(res.Result) + return err +} + func getDiagnostics(ctx context.Context) (DiagnosticsInfo, error) { daemon := client.New() diag := DiagnosticsInfo{} @@ -242,7 +368,7 @@ func gatherConfig() (AgentConfig, error) { // // The passed DiagnosticsInfo and AgentConfig data is written in the specified output format. // Any local log files are collected and copied into the archive. -func createZip(fileName, outputFormat string, diag DiagnosticsInfo, cfg AgentConfig) error { +func createZip(fileName, outputFormat string, diag DiagnosticsInfo, cfg AgentConfig, pprof map[string][]client.ProcPProf) error { f, err := os.Create(fileName) if err != nil { return err @@ -298,6 +424,13 @@ func createZip(fileName, outputFormat string, diag DiagnosticsInfo, cfg AgentCon return closeHandlers(err, zw, f) } + if pprof != nil { + err := zipProfs(zw, pprof) + if err != nil { + return closeHandlers(err, zw, f) + } + } + return closeHandlers(nil, zw, f) } @@ -371,3 +504,58 @@ func closeHandlers(err error, closers ...io.Closer) error { } return mErr.ErrorOrNil() } + +func getAllPprof(ctx context.Context, d time.Duration) (map[string][]client.ProcPProf, error) { + daemon := client.New() + err := daemon.Connect(ctx) + if err != nil { + return nil, err + } + pprofTypes := []proto.PprofOption{ + proto.PprofOption_ALLOCS, + proto.PprofOption_BLOCK, + proto.PprofOption_CMDLINE, + proto.PprofOption_GOROUTINE, + proto.PprofOption_HEAP, + proto.PprofOption_MUTEX, + proto.PprofOption_PROFILE, + proto.PprofOption_THREADCREATE, + proto.PprofOption_TRACE, + } + return daemon.Pprof(ctx, d, pprofTypes, "", "") +} + +func zipProfs(zw *zip.Writer, pprof map[string][]client.ProcPProf) error { + zf, err := zw.Create("pprof/") + if err != nil { + return err + } + for pType, profs := range pprof { + zf, err = zw.Create("pprof/" + pType + "/") + if err != nil { + return err + } + for _, p := range profs { + if p.Error != "" { + zf, err = zw.Create("pprof/" + pType + "/" + p.Name + "_" + p.RouteKey + "_error.txt") + if err != nil { + return err + } + _, err = zf.Write([]byte(p.Error)) + if err != nil { + return err + } + continue + } + zf, err = zw.Create("pprof/" + pType + "/" + p.Name + "_" + p.RouteKey + ".pprof") + if err != nil { + return err + } + _, err = zf.Write(p.Result) + if err != nil { + return err + } + } + } + return nil +} diff --git a/x-pack/elastic-agent/pkg/agent/cmd/run.go b/x-pack/elastic-agent/pkg/agent/cmd/run.go index ba37febd674f..7f10f9faa31d 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/run.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/run.go @@ -148,6 +148,7 @@ func run(streams *cli.IOStreams, override cfgOverrider) error { } control.SetRouteFn(app.Routes) + control.SetMonitoringCfg(cfg.Settings.MonitoringConfig) serverStopFn, err := setupMetrics(agentInfo, logger, cfg.Settings.DownloadConfig.OS(), cfg.Settings.MonitoringConfig, app) if err != nil { @@ -313,7 +314,7 @@ func setupMetrics(agentInfo *info.AgentInfo, logger *logger.Logger, operatingSys } s.Start() - if cfg.Pprof { + if cfg.Pprof != nil && cfg.Pprof.Enabled { s.AttachPprof() } diff --git a/x-pack/elastic-agent/pkg/agent/control/client/client.go b/x-pack/elastic-agent/pkg/agent/control/client/client.go index f7332b9896e7..900718bc6a69 100644 --- a/x-pack/elastic-agent/pkg/agent/control/client/client.go +++ b/x-pack/elastic-agent/pkg/agent/control/client/client.go @@ -72,6 +72,14 @@ type ProcMeta struct { Error string } +// ProcPProf returns pprof data for a process. +type ProcPProf struct { + Name string + RouteKey string + Result []byte + Error string +} + // AgentStatus is the current status of the Elastic Agent. type AgentStatus struct { Status Status @@ -95,6 +103,8 @@ type Client interface { Upgrade(ctx context.Context, version string, sourceURI string) (string, error) // ProcMeta gathers running process meta-data. ProcMeta(ctx context.Context) ([]ProcMeta, error) + // Pprof gathers data from the /debug/pprof/ endpoints specified. + Pprof(ctx context.Context, d time.Duration, pprofTypes []proto.PprofOption, appName, routeKey string) (map[string][]ProcPProf, error) } // client manages the state and communication to the Elastic Agent. @@ -247,3 +257,29 @@ func (c *client) ProcMeta(ctx context.Context) ([]ProcMeta, error) { } return procMeta, nil } + +// Pprof gathers /debug/pprof data and returns a map of pprof-type: ProcPProf data +func (c *client) Pprof(ctx context.Context, d time.Duration, pprofTypes []proto.PprofOption, appName, routeKey string) (map[string][]ProcPProf, error) { + resp, err := c.client.Pprof(ctx, &proto.PprofRequest{ + PprofType: pprofTypes, + TraceDuration: d.String(), + AppName: appName, + RouteKey: routeKey, + }) + if err != nil { + return nil, err + } + res := map[string][]ProcPProf{} + for _, pType := range pprofTypes { + res[pType.String()] = make([]ProcPProf, 0) + } + for _, r := range resp.Results { + res[r.PprofType.String()] = append(res[r.PprofType.String()], ProcPProf{ + Name: r.AppName, + RouteKey: r.RouteKey, + Result: r.Result, + Error: r.Error, + }) + } + return res, nil +} diff --git a/x-pack/elastic-agent/pkg/agent/control/proto/control.pb.go b/x-pack/elastic-agent/pkg/agent/control/proto/control.pb.go index 2cdec52cf65c..70c66acd4abd 100644 --- a/x-pack/elastic-agent/pkg/agent/control/proto/control.pb.go +++ b/x-pack/elastic-agent/pkg/agent/control/proto/control.pb.go @@ -143,6 +143,74 @@ func (ActionStatus) EnumDescriptor() ([]byte, []int) { return file_control_proto_rawDescGZIP(), []int{1} } +// pprof endpoint that can be requested. +type PprofOption int32 + +const ( + PprofOption_ALLOCS PprofOption = 0 + PprofOption_BLOCK PprofOption = 1 + PprofOption_CMDLINE PprofOption = 2 + PprofOption_GOROUTINE PprofOption = 3 + PprofOption_HEAP PprofOption = 4 + PprofOption_MUTEX PprofOption = 5 + PprofOption_PROFILE PprofOption = 6 + PprofOption_THREADCREATE PprofOption = 7 + PprofOption_TRACE PprofOption = 8 +) + +// Enum value maps for PprofOption. +var ( + PprofOption_name = map[int32]string{ + 0: "ALLOCS", + 1: "BLOCK", + 2: "CMDLINE", + 3: "GOROUTINE", + 4: "HEAP", + 5: "MUTEX", + 6: "PROFILE", + 7: "THREADCREATE", + 8: "TRACE", + } + PprofOption_value = map[string]int32{ + "ALLOCS": 0, + "BLOCK": 1, + "CMDLINE": 2, + "GOROUTINE": 3, + "HEAP": 4, + "MUTEX": 5, + "PROFILE": 6, + "THREADCREATE": 7, + "TRACE": 8, + } +) + +func (x PprofOption) Enum() *PprofOption { + p := new(PprofOption) + *p = x + return p +} + +func (x PprofOption) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PprofOption) Descriptor() protoreflect.EnumDescriptor { + return file_control_proto_enumTypes[2].Descriptor() +} + +func (PprofOption) Type() protoreflect.EnumType { + return &file_control_proto_enumTypes[2] +} + +func (x PprofOption) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PprofOption.Descriptor instead. +func (PprofOption) EnumDescriptor() ([]byte, []int) { + return file_control_proto_rawDescGZIP(), []int{2} +} + // Empty message. type Empty struct { state protoimpl.MessageState @@ -807,6 +875,210 @@ func (x *ProcMetaResponse) GetProcs() []*ProcMeta { return nil } +// PprofRequest is a request for pprof data from and http/pprof endpoint. +type PprofRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The profiles that are requested + PprofType []PprofOption `protobuf:"varint,1,rep,packed,name=pprofType,proto3,enum=proto.PprofOption" json:"pprofType,omitempty"` + // A string representing a time.Duration to apply to trace, and profile options. + TraceDuration string `protobuf:"bytes,2,opt,name=traceDuration,proto3" json:"traceDuration,omitempty"` + // The application that will be profiled, if empty all applications are profiled. + AppName string `protobuf:"bytes,3,opt,name=appName,proto3" json:"appName,omitempty"` + // The route key to match for profiling, if empty all are profiled. + RouteKey string `protobuf:"bytes,4,opt,name=routeKey,proto3" json:"routeKey,omitempty"` +} + +func (x *PprofRequest) Reset() { + *x = PprofRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_control_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofRequest) ProtoMessage() {} + +func (x *PprofRequest) ProtoReflect() protoreflect.Message { + mi := &file_control_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead. +func (*PprofRequest) Descriptor() ([]byte, []int) { + return file_control_proto_rawDescGZIP(), []int{9} +} + +func (x *PprofRequest) GetPprofType() []PprofOption { + if x != nil { + return x.PprofType + } + return nil +} + +func (x *PprofRequest) GetTraceDuration() string { + if x != nil { + return x.TraceDuration + } + return "" +} + +func (x *PprofRequest) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + +func (x *PprofRequest) GetRouteKey() string { + if x != nil { + return x.RouteKey + } + return "" +} + +// PprofResult is the result of a pprof request for a given application/route key. +type PprofResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppName string `protobuf:"bytes,1,opt,name=appName,proto3" json:"appName,omitempty"` + RouteKey string `protobuf:"bytes,2,opt,name=routeKey,proto3" json:"routeKey,omitempty"` + PprofType PprofOption `protobuf:"varint,3,opt,name=pprofType,proto3,enum=proto.PprofOption" json:"pprofType,omitempty"` + Result []byte `protobuf:"bytes,4,opt,name=result,proto3" json:"result,omitempty"` + Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *PprofResult) Reset() { + *x = PprofResult{} + if protoimpl.UnsafeEnabled { + mi := &file_control_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResult) ProtoMessage() {} + +func (x *PprofResult) ProtoReflect() protoreflect.Message { + mi := &file_control_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResult.ProtoReflect.Descriptor instead. +func (*PprofResult) Descriptor() ([]byte, []int) { + return file_control_proto_rawDescGZIP(), []int{10} +} + +func (x *PprofResult) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + +func (x *PprofResult) GetRouteKey() string { + if x != nil { + return x.RouteKey + } + return "" +} + +func (x *PprofResult) GetPprofType() PprofOption { + if x != nil { + return x.PprofType + } + return PprofOption_ALLOCS +} + +func (x *PprofResult) GetResult() []byte { + if x != nil { + return x.Result + } + return nil +} + +func (x *PprofResult) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +// PprofResponse is a wrapper to return all pprof responses. +type PprofResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Results []*PprofResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` +} + +func (x *PprofResponse) Reset() { + *x = PprofResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_control_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResponse) ProtoMessage() {} + +func (x *PprofResponse) ProtoReflect() protoreflect.Message { + mi := &file_control_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead. +func (*PprofResponse) Descriptor() ([]byte, []int) { + return file_control_proto_rawDescGZIP(), []int{11} +} + +func (x *PprofResponse) GetResults() []*PprofResult { + if x != nil { + return x.Results + } + return nil +} + var File_control_proto protoreflect.FileDescriptor var file_control_proto_rawDesc = []byte{ @@ -886,37 +1158,73 @@ var file_control_proto_rawDesc = []byte{ 0x10, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, - 0x61, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x63, 0x73, 0x2a, 0x79, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x00, - 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x49, 0x4e, 0x47, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, 0x12, 0x0c, - 0x0a, 0x08, 0x44, 0x45, 0x47, 0x52, 0x41, 0x44, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x4f, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, - 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, - 0x4b, 0x10, 0x07, 0x2a, 0x28, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x00, - 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x32, 0x93, 0x02, - 0x0a, 0x13, 0x45, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x2f, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x31, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x22, 0x5a, 0x1d, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x63, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x50, 0x70, 0x72, + 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x09, 0x70, 0x70, 0x72, + 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x09, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x70, 0x72, 0x6f, + 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, + 0x09, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x3d, 0x0a, + 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, + 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2a, 0x79, 0x0a, 0x06, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, + 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, + 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, + 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x47, 0x52, 0x41, 0x44, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, + 0x53, 0x54, 0x4f, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x50, + 0x47, 0x52, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, + 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x07, 0x2a, 0x28, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, + 0x01, 0x2a, 0x7f, 0x0a, 0x0b, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, + 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4d, 0x44, 0x4c, 0x49, + 0x4e, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x47, 0x4f, 0x52, 0x4f, 0x55, 0x54, 0x49, 0x4e, + 0x45, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x45, 0x41, 0x50, 0x10, 0x04, 0x12, 0x09, 0x0a, + 0x05, 0x4d, 0x55, 0x54, 0x45, 0x58, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x4f, 0x46, + 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, 0x43, + 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, + 0x10, 0x08, 0x32, 0xc7, 0x02, 0x0a, 0x13, 0x45, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x2f, 0x0a, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x52, 0x65, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x55, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, + 0x61, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, + 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x22, 0x5a, 0x1d, + 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0xf8, 0x01, 0x01, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -931,43 +1239,52 @@ func file_control_proto_rawDescGZIP() []byte { return file_control_proto_rawDescData } -var file_control_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_control_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_control_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_control_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_control_proto_goTypes = []interface{}{ (Status)(0), // 0: proto.Status (ActionStatus)(0), // 1: proto.ActionStatus - (*Empty)(nil), // 2: proto.Empty - (*VersionResponse)(nil), // 3: proto.VersionResponse - (*RestartResponse)(nil), // 4: proto.RestartResponse - (*UpgradeRequest)(nil), // 5: proto.UpgradeRequest - (*UpgradeResponse)(nil), // 6: proto.UpgradeResponse - (*ApplicationStatus)(nil), // 7: proto.ApplicationStatus - (*ProcMeta)(nil), // 8: proto.ProcMeta - (*StatusResponse)(nil), // 9: proto.StatusResponse - (*ProcMetaResponse)(nil), // 10: proto.ProcMetaResponse + (PprofOption)(0), // 2: proto.PprofOption + (*Empty)(nil), // 3: proto.Empty + (*VersionResponse)(nil), // 4: proto.VersionResponse + (*RestartResponse)(nil), // 5: proto.RestartResponse + (*UpgradeRequest)(nil), // 6: proto.UpgradeRequest + (*UpgradeResponse)(nil), // 7: proto.UpgradeResponse + (*ApplicationStatus)(nil), // 8: proto.ApplicationStatus + (*ProcMeta)(nil), // 9: proto.ProcMeta + (*StatusResponse)(nil), // 10: proto.StatusResponse + (*ProcMetaResponse)(nil), // 11: proto.ProcMetaResponse + (*PprofRequest)(nil), // 12: proto.PprofRequest + (*PprofResult)(nil), // 13: proto.PprofResult + (*PprofResponse)(nil), // 14: proto.PprofResponse } var file_control_proto_depIdxs = []int32{ 1, // 0: proto.RestartResponse.status:type_name -> proto.ActionStatus 1, // 1: proto.UpgradeResponse.status:type_name -> proto.ActionStatus 0, // 2: proto.ApplicationStatus.status:type_name -> proto.Status 0, // 3: proto.StatusResponse.status:type_name -> proto.Status - 7, // 4: proto.StatusResponse.applications:type_name -> proto.ApplicationStatus - 8, // 5: proto.ProcMetaResponse.procs:type_name -> proto.ProcMeta - 2, // 6: proto.ElasticAgentControl.Version:input_type -> proto.Empty - 2, // 7: proto.ElasticAgentControl.Status:input_type -> proto.Empty - 2, // 8: proto.ElasticAgentControl.Restart:input_type -> proto.Empty - 5, // 9: proto.ElasticAgentControl.Upgrade:input_type -> proto.UpgradeRequest - 2, // 10: proto.ElasticAgentControl.ProcMeta:input_type -> proto.Empty - 3, // 11: proto.ElasticAgentControl.Version:output_type -> proto.VersionResponse - 9, // 12: proto.ElasticAgentControl.Status:output_type -> proto.StatusResponse - 4, // 13: proto.ElasticAgentControl.Restart:output_type -> proto.RestartResponse - 6, // 14: proto.ElasticAgentControl.Upgrade:output_type -> proto.UpgradeResponse - 10, // 15: proto.ElasticAgentControl.ProcMeta:output_type -> proto.ProcMetaResponse - 11, // [11:16] is the sub-list for method output_type - 6, // [6:11] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 8, // 4: proto.StatusResponse.applications:type_name -> proto.ApplicationStatus + 9, // 5: proto.ProcMetaResponse.procs:type_name -> proto.ProcMeta + 2, // 6: proto.PprofRequest.pprofType:type_name -> proto.PprofOption + 2, // 7: proto.PprofResult.pprofType:type_name -> proto.PprofOption + 13, // 8: proto.PprofResponse.results:type_name -> proto.PprofResult + 3, // 9: proto.ElasticAgentControl.Version:input_type -> proto.Empty + 3, // 10: proto.ElasticAgentControl.Status:input_type -> proto.Empty + 3, // 11: proto.ElasticAgentControl.Restart:input_type -> proto.Empty + 6, // 12: proto.ElasticAgentControl.Upgrade:input_type -> proto.UpgradeRequest + 3, // 13: proto.ElasticAgentControl.ProcMeta:input_type -> proto.Empty + 12, // 14: proto.ElasticAgentControl.Pprof:input_type -> proto.PprofRequest + 4, // 15: proto.ElasticAgentControl.Version:output_type -> proto.VersionResponse + 10, // 16: proto.ElasticAgentControl.Status:output_type -> proto.StatusResponse + 5, // 17: proto.ElasticAgentControl.Restart:output_type -> proto.RestartResponse + 7, // 18: proto.ElasticAgentControl.Upgrade:output_type -> proto.UpgradeResponse + 11, // 19: proto.ElasticAgentControl.ProcMeta:output_type -> proto.ProcMetaResponse + 14, // 20: proto.ElasticAgentControl.Pprof:output_type -> proto.PprofResponse + 15, // [15:21] is the sub-list for method output_type + 9, // [9:15] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_control_proto_init() } @@ -1084,14 +1401,50 @@ func file_control_proto_init() { return nil } } + file_control_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_control_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_control_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_control_proto_rawDesc, - NumEnums: 2, - NumMessages: 9, + NumEnums: 3, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, @@ -1128,6 +1481,8 @@ type ElasticAgentControlClient interface { Upgrade(ctx context.Context, in *UpgradeRequest, opts ...grpc.CallOption) (*UpgradeResponse, error) // Gather all running process metadata. ProcMeta(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ProcMetaResponse, error) + // Gather requested pprof data from specified applications. + Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) } type elasticAgentControlClient struct { @@ -1183,6 +1538,15 @@ func (c *elasticAgentControlClient) ProcMeta(ctx context.Context, in *Empty, opt return out, nil } +func (c *elasticAgentControlClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) { + out := new(PprofResponse) + err := c.cc.Invoke(ctx, "/proto.ElasticAgentControl/Pprof", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ElasticAgentControlServer is the server API for ElasticAgentControl service. type ElasticAgentControlServer interface { // Fetches the currently running version of the Elastic Agent. @@ -1195,6 +1559,8 @@ type ElasticAgentControlServer interface { Upgrade(context.Context, *UpgradeRequest) (*UpgradeResponse, error) // Gather all running process metadata. ProcMeta(context.Context, *Empty) (*ProcMetaResponse, error) + // Gather requested pprof data from specified applications. + Pprof(context.Context, *PprofRequest) (*PprofResponse, error) } // UnimplementedElasticAgentControlServer can be embedded to have forward compatible implementations. @@ -1216,6 +1582,9 @@ func (*UnimplementedElasticAgentControlServer) Upgrade(context.Context, *Upgrade func (*UnimplementedElasticAgentControlServer) ProcMeta(context.Context, *Empty) (*ProcMetaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ProcMeta not implemented") } +func (*UnimplementedElasticAgentControlServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented") +} func RegisterElasticAgentControlServer(s *grpc.Server, srv ElasticAgentControlServer) { s.RegisterService(&_ElasticAgentControl_serviceDesc, srv) @@ -1311,6 +1680,24 @@ func _ElasticAgentControl_ProcMeta_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _ElasticAgentControl_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PprofRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ElasticAgentControlServer).Pprof(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.ElasticAgentControl/Pprof", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ElasticAgentControlServer).Pprof(ctx, req.(*PprofRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _ElasticAgentControl_serviceDesc = grpc.ServiceDesc{ ServiceName: "proto.ElasticAgentControl", HandlerType: (*ElasticAgentControlServer)(nil), @@ -1335,6 +1722,10 @@ var _ElasticAgentControl_serviceDesc = grpc.ServiceDesc{ MethodName: "ProcMeta", Handler: _ElasticAgentControl_ProcMeta_Handler, }, + { + MethodName: "Pprof", + Handler: _ElasticAgentControl_Pprof_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "control.proto", diff --git a/x-pack/elastic-agent/pkg/agent/control/server/server.go b/x-pack/elastic-agent/pkg/agent/control/server/server.go index 072b212a7718..12ed4650eedf 100644 --- a/x-pack/elastic-agent/pkg/agent/control/server/server.go +++ b/x-pack/elastic-agent/pkg/agent/control/server/server.go @@ -7,6 +7,8 @@ package server import ( "context" "encoding/json" + "fmt" + "io" "net" "net/http" "runtime" @@ -23,7 +25,9 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/beats" monitoring "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/beats" + monitoringCfg "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/config" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/socket" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/status" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi" @@ -33,20 +37,27 @@ import ( // Server is the daemon side of the control protocol. type Server struct { - logger *logger.Logger - rex reexec.ExecManager - statusCtrl status.Controller - up *upgrade.Upgrader - routeFn func() *sorted.Set - listener net.Listener - server *grpc.Server - lock sync.RWMutex + logger *logger.Logger + rex reexec.ExecManager + statusCtrl status.Controller + up *upgrade.Upgrader + routeFn func() *sorted.Set + monitoringCfg *monitoringCfg.MonitoringConfig + listener net.Listener + server *grpc.Server + lock sync.RWMutex } type specer interface { Specs() map[string]program.Spec } +type specInfo struct { + spec program.Spec + app string + rk string +} + // New creates a new control protocol server. func New(log *logger.Logger, rex reexec.ExecManager, statusCtrl status.Controller, up *upgrade.Upgrader) *Server { return &Server{ @@ -71,6 +82,14 @@ func (s *Server) SetRouteFn(routesFetchFn func() *sorted.Set) { s.routeFn = routesFetchFn } +// SetMonitoringCfg sets a reference to the monitoring config used by the running agent. +// the controller references this config to find out if pprof is enabled for the agent or not +func (s *Server) SetMonitoringCfg(cfg *monitoringCfg.MonitoringConfig) { + s.lock.Lock() + defer s.lock.Unlock() + s.monitoringCfg = cfg +} + // Start starts the GRPC endpoint and accepts new connections. func (s *Server) Start() error { if s.server != nil { @@ -194,84 +213,273 @@ func (s *Server) ProcMeta(ctx context.Context, _ *proto.Empty) (*proto.ProcMetaR Procs: []*proto.ProcMeta{}, } + // gather spec data for all rk/apps running + specs := s.getSpecInfo("", "") + for _, si := range specs { + endpoint := monitoring.MonitoringEndpoint(si.spec, runtime.GOOS, si.rk) + client := newSocketRequester(si.app, si.rk, endpoint) + + procMeta := client.procMeta(ctx) + resp.Procs = append(resp.Procs, procMeta) + } + + return resp, nil +} + +// Pprof returns /debug/pprof data for the requested applicaiont-route_key or all running applications. +func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) { + if s.monitoringCfg == nil || s.monitoringCfg.Pprof == nil || !s.monitoringCfg.Pprof.Enabled { + return nil, fmt.Errorf("agent.monitoring.pprof disabled") + } + + if s.routeFn == nil { + return nil, errors.New("route function is nil") + } + + dur, err := time.ParseDuration(req.TraceDuration) + if err != nil { + return nil, fmt.Errorf("unable to parse trace duration: %w", err) + } + + resp := &proto.PprofResponse{ + Results: []*proto.PprofResult{}, + } + + var wg sync.WaitGroup + ch := make(chan *proto.PprofResult, 1) + + // retrieve elastic-agent pprof data if requested or application is unspecified. + if req.AppName == "" || req.AppName == "elastic-agent" { + endpoint := beats.AgentMonitoringEndpoint(runtime.GOOS, s.monitoringCfg.HTTP) + c := newSocketRequester("elastic-agent", "", endpoint) + for _, opt := range req.PprofType { + wg.Add(1) + go func(opt proto.PprofOption) { + res := c.getPprof(ctx, opt, dur) + ch <- res + wg.Done() + }(opt) + } + } + + // get requested rk/appname spec or all specs + var specs []specInfo + if req.AppName != "elastic-agent" { + specs = s.getSpecInfo(req.RouteKey, req.AppName) + } + for _, si := range specs { + endpoint := monitoring.MonitoringEndpoint(si.spec, runtime.GOOS, si.rk) + c := newSocketRequester(si.app, si.rk, endpoint) + // Launch a concurrent goroutine to gather all pprof endpoints from a socket. + for _, opt := range req.PprofType { + wg.Add(1) + go func(opt proto.PprofOption) { + res := c.getPprof(ctx, opt, dur) + ch <- res + wg.Done() + }(opt) + } + } + + // wait for the waitgroup to be done and close the channel + go func() { + wg.Wait() + close(ch) + }() + + // gather all results from channel until closed. + for res := range ch { + resp.Results = append(resp.Results, res) + } + return resp, nil +} + +// getSpecs will return the specs for the program associated with the specified route key/app name, or all programs if no key(s) are specified. +// if matchRK or matchApp are empty all results will be returned. +func (s *Server) getSpecInfo(matchRK, matchApp string) []specInfo { routes := s.routeFn() + + // find specInfo for a specified rk/app + if matchRK != "" && matchApp != "" { + programs, ok := routes.Get(matchRK) + if !ok { + s.logger.With("route_key", matchRK).Debug("No matching route key found.") + return []specInfo{} + } + sp, ok := programs.(specer) + if !ok { + s.logger.With("route_key", matchRK, "route", programs).Warn("Unable to cast route as specer.") + return []specInfo{} + } + specs := sp.Specs() + + spec, ok := specs[matchApp] + if !ok { + s.logger.With("route_key", matchRK, "application_name", matchApp).Debug("No matching route key/application name found.") + return []specInfo{} + } + return []specInfo{specInfo{spec: spec, app: matchApp, rk: matchRK}} + } + + // gather specInfo for all rk/app values + res := make([]specInfo, 0) for _, rk := range routes.Keys() { programs, ok := routes.Get(rk) if !ok { + // we do not expect to ever hit this code path + // if this log message occurs then the agent is unable to access one of the keys that is returned by the route function + // might be a race condition if someone tries to update the policy to remove an output? s.logger.With("route_key", rk).Warn("Unable to retrieve route.") continue } - sp, ok := programs.(specer) if !ok { - s.logger.With("route_key", rk, "route", programs).Warn("Unable to cast route as specer.") + s.logger.With("route_key", matchRK, "route", programs).Warn("Unable to cast route as specer.") continue } - specs := sp.Specs() + for n, spec := range sp.Specs() { + res = append(res, specInfo{ + rk: rk, + app: n, + spec: spec, + }) + } + } + return res +} + +// socketRequester is a struct to gather (diagnostics) data from a socket opened by elastic-agent or one if it's processes +type socketRequester struct { + c http.Client + endpoint string + appName string + routeKey string +} - for n, spec := range specs { - procMeta := &proto.ProcMeta{ - Name: n, - RouteKey: rk, - } - - client := http.Client{ - Timeout: time.Second * 5, - } - endpoint := monitoring.MonitoringEndpoint(spec, runtime.GOOS, rk) - if strings.HasPrefix(endpoint, "unix://") { - client.Transport = &http.Transport{ - Proxy: nil, - DialContext: socket.DialContext(strings.TrimPrefix(endpoint, "unix://")), - } - endpoint = "unix" - } else if strings.HasPrefix(endpoint, "npipe://") { - client.Transport = &http.Transport{ - Proxy: nil, - DialContext: socket.DialContext(strings.TrimPrefix(endpoint, "npipe:///")), - } - endpoint = "npipe" - } - - res, err := client.Get("http://" + endpoint + "/") - if err != nil { - procMeta.Error = err.Error() - resp.Procs = append(resp.Procs, procMeta) - continue - } - if res.StatusCode != 200 { - procMeta.Error = "response status is: " + res.Status - resp.Procs = append(resp.Procs, procMeta) - continue - } - - bi := &BeatInfo{} - dec := json.NewDecoder(res.Body) - if err := dec.Decode(bi); err != nil { - res.Body.Close() - procMeta.Error = err.Error() - resp.Procs = append(resp.Procs, procMeta) - continue - } - res.Body.Close() - - procMeta.Process = bi.Beat - procMeta.Hostname = bi.Hostname - procMeta.Id = bi.ID - procMeta.EphemeralId = bi.EphemeralID - procMeta.Version = bi.Version - procMeta.BuildCommit = bi.Commit - procMeta.BuildTime = bi.Time - procMeta.Username = bi.Username - procMeta.UserId = bi.UserID - procMeta.UserGid = bi.GroupID - procMeta.Architecture = bi.BinaryArch - procMeta.ElasticLicensed = bi.ElasticLicensed - - resp.Procs = append(resp.Procs, procMeta) +func newSocketRequester(appName, routeKey, endpoint string) *socketRequester { + c := http.Client{} + if strings.HasPrefix(endpoint, "unix://") { + c.Transport = &http.Transport{ + Proxy: nil, + DialContext: socket.DialContext(strings.TrimPrefix(endpoint, "unix://")), + } + endpoint = "unix" + } else if strings.HasPrefix(endpoint, "npipe://") { + c.Transport = &http.Transport{ + Proxy: nil, + DialContext: socket.DialContext(strings.TrimPrefix(endpoint, "npipe:///")), } + endpoint = "npipe" } - return resp, nil + return &socketRequester{ + c: c, + appName: appName, + routeKey: routeKey, + endpoint: endpoint, + } +} + +// getPath creates a get request for the specified path. +// Will return an error if that status code is not 200. +func (r *socketRequester) getPath(ctx context.Context, path string) (*http.Response, error) { + req, err := http.NewRequest("GET", "http://"+r.endpoint+path, nil) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + res, err := r.c.Do(req) + if err != nil { + return nil, err + } + if res.StatusCode != 200 { + res.Body.Close() + return nil, fmt.Errorf("response status is %d", res.StatusCode) + } + return res, nil + +} + +// procMeta will return process metadata by querying the "/" path. +func (r *socketRequester) procMeta(ctx context.Context) *proto.ProcMeta { + pm := &proto.ProcMeta{ + Name: r.appName, + RouteKey: r.routeKey, + } + + res, err := r.getPath(ctx, "/") + if err != nil { + pm.Error = err.Error() + return pm + } + defer res.Body.Close() + + bi := &BeatInfo{} + dec := json.NewDecoder(res.Body) + if err := dec.Decode(bi); err != nil { + pm.Error = err.Error() + return pm + } + + pm.Process = bi.Beat + pm.Hostname = bi.Hostname + pm.Id = bi.ID + pm.EphemeralId = bi.EphemeralID + pm.Version = bi.Version + pm.BuildCommit = bi.Commit + pm.BuildTime = bi.Time + pm.Username = bi.Username + pm.UserId = bi.UserID + pm.UserGid = bi.GroupID + pm.Architecture = bi.BinaryArch + pm.ElasticLicensed = bi.ElasticLicensed + + return pm +} + +var pprofEndpoints = map[proto.PprofOption]string{ + proto.PprofOption_ALLOCS: "/debug/pprof/allocs", + proto.PprofOption_BLOCK: "/debug/pprof/block", + proto.PprofOption_CMDLINE: "/debug/pprof/cmdline", + proto.PprofOption_GOROUTINE: "/debug/pprof/goroutine", + proto.PprofOption_HEAP: "/debug/pprof/heap", + proto.PprofOption_MUTEX: "/debug/pprof/mutex", + proto.PprofOption_PROFILE: "/debug/pprof/profile", + proto.PprofOption_THREADCREATE: "/debug/pprof/threadcreate", + proto.PprofOption_TRACE: "/debug/pprof/trace", +} + +// getProf will gather pprof data specified by the option. +func (r *socketRequester) getPprof(ctx context.Context, opt proto.PprofOption, dur time.Duration) *proto.PprofResult { + res := &proto.PprofResult{ + AppName: r.appName, + RouteKey: r.routeKey, + PprofType: opt, + } + + path, ok := pprofEndpoints[opt] + if !ok { + res.Error = "unknown path for option" + return res + } + + if opt == proto.PprofOption_PROFILE || opt == proto.PprofOption_TRACE { + path += fmt.Sprintf("?seconds=%0.f", dur.Seconds()) + } + + resp, err := r.getPath(ctx, path) + if err != nil { + res.Error = err.Error() + return res + } + defer resp.Body.Close() + + p, err := io.ReadAll(resp.Body) + if err != nil { + res.Error = err.Error() + return res + } + res.Result = p + return res } type upgradeRequest struct { diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go index cb0519f98063..939aa89c99d5 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go @@ -35,6 +35,7 @@ type Monitor struct { func NewMonitor(downloadConfig *artifact.Config, monitoringCfg *monitoringConfig.MonitoringConfig, logMetrics bool) *Monitor { if monitoringCfg == nil { monitoringCfg = monitoringConfig.DefaultConfig() + monitoringCfg.Pprof = &monitoringConfig.PprofConfig{Enabled: false} } monitoringCfg.LogMetrics = logMetrics @@ -55,6 +56,9 @@ func (b *Monitor) Reload(rawConfig *config.Config) error { if cfg == nil || cfg.Settings == nil || cfg.Settings.MonitoringConfig == nil { b.config = monitoringConfig.DefaultConfig() } else { + if cfg.Settings.MonitoringConfig.Pprof == nil { + cfg.Settings.MonitoringConfig.Pprof = b.config.Pprof + } b.config = cfg.Settings.MonitoringConfig logMetrics := true if cfg.Settings.LoggingConfig != nil { @@ -123,7 +127,7 @@ func (b *Monitor) EnrichArgs(spec program.Spec, pipelineID string, args []string "-E", "http.enabled=true", "-E", "http.host="+endpoint, ) - if b.config.Pprof { + if b.config.Pprof != nil && b.config.Pprof.Enabled { appendix = append(appendix, "-E", "http.pprof.enabled=true", ) diff --git a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go index 10f220fcc5af..3004561bd862 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go @@ -15,7 +15,7 @@ type MonitoringConfig struct { LogMetrics bool `yaml:"-" config:"-"` HTTP *MonitoringHTTPConfig `yaml:"http" config:"http"` Namespace string `yaml:"namespace" config:"namespace"` - Pprof bool `yaml:"pprof" config:"pprof"` + Pprof *PprofConfig `yaml:"pprof" config:"pprof"` } // MonitoringHTTPConfig is a config defining HTTP endpoint published by agent @@ -27,6 +27,13 @@ type MonitoringHTTPConfig struct { Port int `yaml:"port" config:"port" validate:"min=0,max=65535,nonzero"` } +// PprofConfig is a struct for the pprof enablement flag. +// It is a nil struct by default to allow the agent to use the a value that the user has injected into fleet.yml as the source of truth that is passed to beats +// TODO get this value from Kibana? +type PprofConfig struct { + Enabled bool `yaml:"enabled" config:"enabled"` +} + // DefaultConfig creates a config with pre-set default values. func DefaultConfig() *MonitoringConfig { return &MonitoringConfig{ @@ -39,6 +46,5 @@ func DefaultConfig() *MonitoringConfig { Port: defaultPort, }, Namespace: defaultNamespace, - Pprof: false, } } From 3ab22929a54976ff0f8700a61f1821d5843624f5 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 15 Dec 2021 00:08:45 +0100 Subject: [PATCH 085/172] [Heartbeat] Add run_once mode in the scheduler (#29282) This PR fixes data stream mode while running heartbeat in run_once mode , before this if you would run heartbeat in run_once mode, it would still push documents to normal heartbeat indexes. This PR also fixes data like tags not being pushed as part of documents. --- heartbeat/README.md | 4 +- heartbeat/beater/heartbeat.go | 85 ++------------ heartbeat/monitors/factory.go | 10 +- heartbeat/monitors/factory_test.go | 9 +- heartbeat/monitors/monitor.go | 50 ++++++-- heartbeat/monitors/monitor_test.go | 12 +- heartbeat/monitors/task.go | 11 +- heartbeat/monitors/task_test.go | 6 +- heartbeat/scheduler/schedjob_test.go | 6 +- heartbeat/scheduler/scheduler.go | 107 ++++++++---------- heartbeat/scheduler/scheduler_test.go | 88 +++++++------- .../publisher/pipeline}/sync_client.go | 28 +++-- .../publisher/pipeline}/sync_client_test.go | 23 +++- .../function/beater/functionbeat.go | 7 +- .../function/provider/provider.go | 5 +- .../function/provider/provider_test.go | 10 +- .../function/provider/registry_test.go | 7 +- .../provider/aws/aws/api_gateway_proxy.go | 6 +- .../provider/aws/aws/cloudwatch_kinesis.go | 6 +- .../provider/aws/aws/cloudwatch_logs.go | 6 +- .../functionbeat/provider/aws/aws/kinesis.go | 6 +- x-pack/functionbeat/provider/aws/aws/sqs.go | 6 +- .../provider/local/local/local.go | 4 +- 23 files changed, 256 insertions(+), 246 deletions(-) rename {x-pack/functionbeat/function/core => libbeat/publisher/pipeline}/sync_client.go (75%) rename {x-pack/functionbeat/function/core => libbeat/publisher/pipeline}/sync_client_test.go (73%) diff --git a/heartbeat/README.md b/heartbeat/README.md index c7eb09fa52f8..dad0c6d2bc16 100644 --- a/heartbeat/README.md +++ b/heartbeat/README.md @@ -1,8 +1,8 @@ -# Heartbeat (Experimental) +# Heartbeat Welcome to Heartbeat. -This is a new EXPERIMENTAL beat for testing service availability using PING based on ICMP, TCP or higher level protocols. +This is a beat for testing service availability using PING based on ICMP, TCP or higher level protocols. Ensure that this folder is at the following location: `${GOPATH}/src/github.com/elastic/beats` diff --git a/heartbeat/beater/heartbeat.go b/heartbeat/beater/heartbeat.go index c019e37ea72a..0e499ce6f852 100644 --- a/heartbeat/beater/heartbeat.go +++ b/heartbeat/beater/heartbeat.go @@ -20,7 +20,6 @@ package beater import ( "errors" "fmt" - "sync" "syscall" "time" @@ -28,7 +27,6 @@ import ( "github.com/elastic/beats/v7/heartbeat/hbregistry" "github.com/elastic/beats/v7/heartbeat/monitors" "github.com/elastic/beats/v7/heartbeat/monitors/plugin" - "github.com/elastic/beats/v7/heartbeat/monitors/stdfields" "github.com/elastic/beats/v7/heartbeat/scheduler" "github.com/elastic/beats/v7/libbeat/autodiscover" "github.com/elastic/beats/v7/libbeat/beat" @@ -37,7 +35,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/reload" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/management" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" _ "github.com/elastic/beats/v7/heartbeat/security" _ "github.com/elastic/beats/v7/libbeat/processors/script" @@ -71,14 +68,14 @@ func New(b *beat.Beat, rawConfig *common.Config) (beat.Beater, error) { } jobConfig := parsedConfig.Jobs - scheduler := scheduler.NewWithLocation(limit, hbregistry.SchedulerRegistry, location, jobConfig) + scheduler := scheduler.Create(limit, hbregistry.SchedulerRegistry, location, jobConfig, parsedConfig.RunOnce) bt := &Heartbeat{ done: make(chan struct{}), config: parsedConfig, scheduler: scheduler, // dynamicFactory is the factory used for dynamic configs, e.g. autodiscover / reload - dynamicFactory: monitors.NewFactory(b.Info, scheduler, plugin.GlobalPluginsReg), + dynamicFactory: monitors.NewFactory(b.Info, scheduler.Add, plugin.GlobalPluginsReg, parsedConfig.RunOnce), } return bt, nil } @@ -89,20 +86,21 @@ func (bt *Heartbeat) Run(b *beat.Beat) error { groups, _ := syscall.Getgroups() logp.Info("Effective user/group ids: %d/%d, with groups: %v", syscall.Geteuid(), syscall.Getegid(), groups) - if bt.config.RunOnce { - err := bt.runRunOnce(b) - if err != nil { - return err - } - return nil - } - + // It is important this appear before we check for run once mode + // In run once mode we depend on these monitors being loaded, but not other more + // dynamic types. stopStaticMonitors, err := bt.RunStaticMonitors(b) if err != nil { return err } defer stopStaticMonitors() + if bt.config.RunOnce { + bt.scheduler.WaitForRunOnce() + logp.Info("Ending run_once run") + return nil + } + if b.Manager.Enabled() { bt.RunCentralMgmtMonitors(b) } @@ -127,9 +125,6 @@ func (bt *Heartbeat) Run(b *beat.Beat) error { defer bt.autodiscover.Stop() } - if err := bt.scheduler.Start(); err != nil { - return err - } defer bt.scheduler.Stop() <-bt.done @@ -138,64 +133,6 @@ func (bt *Heartbeat) Run(b *beat.Beat) error { return nil } -// runRunOnce runs the given config then exits immediately after any queued events have been sent to ES -func (bt *Heartbeat) runRunOnce(b *beat.Beat) error { - logp.Info("Starting run_once run. This is an experimental feature and may be changed or removed in the future!") - - publishClient, err := core.NewSyncClient(logp.NewLogger("run_once mode"), b.Publisher, beat.ClientConfig{}) - if err != nil { - return fmt.Errorf("could not create sync client: %w", err) - } - defer publishClient.Close() - - wg := &sync.WaitGroup{} - for _, cfg := range bt.config.Monitors { - err := runRunOnceSingleConfig(cfg, publishClient, wg) - if err != nil { - logp.Warn("error running run_once config: %s", err) - } - } - - wg.Wait() - publishClient.Wait() - - logp.Info("Ending run_once run") - - return nil -} - -func runRunOnceSingleConfig(cfg *common.Config, publishClient *core.SyncClient, wg *sync.WaitGroup) (err error) { - sf, err := stdfields.ConfigToStdMonitorFields(cfg) - if err != nil { - return fmt.Errorf("could not get stdmon fields: %w", err) - } - pluginFactory, exists := plugin.GlobalPluginsReg.Get(sf.Type) - if !exists { - return fmt.Errorf("no plugin for type: %s", sf.Type) - } - plugin, err := pluginFactory.Make(sf.Type, cfg) - if err != nil { - return err - } - - results := plugin.RunWrapped(sf) - - wg.Add(1) - go func() { - defer wg.Done() - defer plugin.Close() - for { - event := <-results - if event == nil { - break - } - publishClient.Publish(*event) - } - }() - - return nil -} - // RunStaticMonitors runs the `heartbeat.monitors` portion of the yaml config if present. func (bt *Heartbeat) RunStaticMonitors(b *beat.Beat) (stop func(), err error) { var runners []cfgfile.Runner diff --git a/heartbeat/monitors/factory.go b/heartbeat/monitors/factory.go index 7f660cbb087a..11a3b2d9ecdb 100644 --- a/heartbeat/monitors/factory.go +++ b/heartbeat/monitors/factory.go @@ -40,11 +40,12 @@ import ( // suitable for config reloading. type RunnerFactory struct { info beat.Info - sched *scheduler.Scheduler + addTask scheduler.AddTask byId map[string]*Monitor mtx *sync.Mutex pluginsReg *plugin.PluginsReg logger *logp.Logger + runOnce bool } type publishSettings struct { @@ -67,14 +68,15 @@ type publishSettings struct { } // NewFactory takes a scheduler and creates a RunnerFactory that can create cfgfile.Runner(Monitor) objects. -func NewFactory(info beat.Info, sched *scheduler.Scheduler, pluginsReg *plugin.PluginsReg) *RunnerFactory { +func NewFactory(info beat.Info, addTask scheduler.AddTask, pluginsReg *plugin.PluginsReg, runOnce bool) *RunnerFactory { return &RunnerFactory{ info: info, - sched: sched, + addTask: addTask, byId: map[string]*Monitor{}, mtx: &sync.Mutex{}, pluginsReg: pluginsReg, logger: logp.NewLogger("monitor-factory"), + runOnce: runOnce, } } @@ -116,7 +118,7 @@ func (f *RunnerFactory) Create(p beat.Pipeline, c *common.Config) (cfgfile.Runne } }() } - monitor, err := newMonitor(c, f.pluginsReg, p, f.sched, safeStop) + monitor, err := newMonitor(c, f.pluginsReg, p, f.addTask, safeStop, f.runOnce) if err != nil { return nil, err } diff --git a/heartbeat/monitors/factory_test.go b/heartbeat/monitors/factory_test.go index 4849529cec45..c395050aaa1e 100644 --- a/heartbeat/monitors/factory_test.go +++ b/heartbeat/monitors/factory_test.go @@ -20,6 +20,7 @@ package monitors import ( "regexp" "testing" + "time" "github.com/stretchr/testify/require" @@ -153,12 +154,10 @@ func TestDuplicateMonitorIDs(t *testing.T) { reg, built, closed := mockPluginsReg() pipelineConnector := &MockPipelineConnector{} - sched := scheduler.New(1, monitoring.NewRegistry()) - err := sched.Start() - require.NoError(t, err) + sched := scheduler.Create(1, monitoring.NewRegistry(), time.Local, nil, false) defer sched.Stop() - f := NewFactory(binfo, sched, reg) + f := NewFactory(binfo, sched.Add, reg, false) makeTestMon := func() (*Monitor, error) { mIface, err := f.Create(pipelineConnector, serverMonConf) if mIface == nil { @@ -169,7 +168,7 @@ func TestDuplicateMonitorIDs(t *testing.T) { } // Ensure that an error is returned on a bad config - _, m0Err := newMonitor(badConf, reg, pipelineConnector, sched, nil) + _, m0Err := newMonitor(badConf, reg, pipelineConnector, sched.Add, nil, false) require.Error(t, m0Err) // Would fail if the previous newMonitor didn't free the monitor.id diff --git a/heartbeat/monitors/monitor.go b/heartbeat/monitors/monitor.go index 9cdbb8ecfd68..669579e31aa0 100644 --- a/heartbeat/monitors/monitor.go +++ b/heartbeat/monitors/monitor.go @@ -32,6 +32,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" ) // ErrMonitorDisabled is returned when the monitor plugin is marked as disabled. @@ -43,13 +44,19 @@ const ( MON_STOPPED ) +type WrappedClient struct { + Publish func(event beat.Event) + Close func() error + wait func() +} + // Monitor represents a configured recurring monitoring configuredJob loaded from a config file. Starting it // will cause it to run with the given scheduler until Stop() is called. type Monitor struct { stdFields stdfields.StdMonitorFields pluginName string config *common.Config - scheduler *scheduler.Scheduler + addTask scheduler.AddTask configuredJobs []*configuredJob enabled bool state int @@ -65,6 +72,8 @@ type Monitor struct { // stats is the countersRecorder used to record lifecycle events // for global metrics + telemetry stats plugin.RegistryRecorder + + runOnce bool } // String prints a description of the monitor in a threadsafe way. It is important that this use threadsafe @@ -74,7 +83,7 @@ func (m *Monitor) String() string { } func checkMonitorConfig(config *common.Config, registrar *plugin.PluginsReg) error { - _, err := newMonitor(config, registrar, nil, nil, nil) + _, err := newMonitor(config, registrar, nil, nil, nil, false) return err } @@ -85,10 +94,11 @@ func newMonitor( config *common.Config, registrar *plugin.PluginsReg, pipelineConnector beat.PipelineConnector, - scheduler *scheduler.Scheduler, + taskAdder scheduler.AddTask, onStop func(*Monitor), + runOnce bool, ) (*Monitor, error) { - m, err := newMonitorUnsafe(config, registrar, pipelineConnector, scheduler, onStop) + m, err := newMonitorUnsafe(config, registrar, pipelineConnector, taskAdder, onStop, runOnce) if m != nil && err != nil { m.Stop() } @@ -101,8 +111,9 @@ func newMonitorUnsafe( config *common.Config, registrar *plugin.PluginsReg, pipelineConnector beat.PipelineConnector, - scheduler *scheduler.Scheduler, + addTask scheduler.AddTask, onStop func(*Monitor), + runOnce bool, ) (*Monitor, error) { // Extract just the Id, Type, and Enabled fields from the config // We'll parse things more precisely later once we know what exact type of @@ -124,13 +135,14 @@ func newMonitorUnsafe( m := &Monitor{ stdFields: standardFields, pluginName: pluginFactory.Name, - scheduler: scheduler, + addTask: addTask, configuredJobs: []*configuredJob{}, pipelineConnector: pipelineConnector, internalsMtx: sync.Mutex{}, config: config, stats: pluginFactory.Stats, state: MON_INIT, + runOnce: runOnce, } if m.stdFields.ID == "" { @@ -211,7 +223,31 @@ func (m *Monitor) Start() { defer m.internalsMtx.Unlock() for _, t := range m.configuredJobs { - t.Start() + if m.runOnce { + client, err := pipeline.NewSyncClient(logp.NewLogger("monitor_task"), t.monitor.pipelineConnector, beat.ClientConfig{}) + if err != nil { + logp.Err("could not start monitor: %v", err) + continue + } + t.Start(&WrappedClient{ + Publish: func(event beat.Event) { + client.Publish(event) + }, + Close: client.Close, + wait: client.Wait, + }) + } else { + client, err := m.pipelineConnector.Connect() + if err != nil { + logp.Err("could not start monitor: %v", err) + continue + } + t.Start(&WrappedClient{ + Publish: client.Publish, + Close: client.Close, + wait: func() {}, + }) + } } m.stats.StartMonitor(int64(m.endpoints)) diff --git a/heartbeat/monitors/monitor_test.go b/heartbeat/monitors/monitor_test.go index 9a0962ef8b27..bbcd5b9b74c5 100644 --- a/heartbeat/monitors/monitor_test.go +++ b/heartbeat/monitors/monitor_test.go @@ -34,12 +34,10 @@ func TestMonitor(t *testing.T) { reg, built, closed := mockPluginsReg() pipelineConnector := &MockPipelineConnector{} - sched := scheduler.New(1, monitoring.NewRegistry()) - err := sched.Start() - require.NoError(t, err) + sched := scheduler.Create(1, monitoring.NewRegistry(), time.Local, nil, false) defer sched.Stop() - mon, err := newMonitor(serverMonConf, reg, pipelineConnector, sched, nil) + mon, err := newMonitor(serverMonConf, reg, pipelineConnector, sched.Add, nil, false) require.NoError(t, err) mon.Start() @@ -83,12 +81,10 @@ func TestCheckInvalidConfig(t *testing.T) { reg, built, closed := mockPluginsReg() pipelineConnector := &MockPipelineConnector{} - sched := scheduler.New(1, monitoring.NewRegistry()) - err := sched.Start() - require.NoError(t, err) + sched := scheduler.Create(1, monitoring.NewRegistry(), time.Local, nil, false) defer sched.Stop() - m, err := newMonitor(serverMonConf, reg, pipelineConnector, sched, nil) + m, err := newMonitor(serverMonConf, reg, pipelineConnector, sched.Add, nil, false) require.Error(t, err) // This could change if we decide the contract for newMonitor should always return a monitor require.Nil(t, m, "For this test to work we need a nil value for the monitor.") diff --git a/heartbeat/monitors/task.go b/heartbeat/monitors/task.go index d9794da16d1c..11b013a98717 100644 --- a/heartbeat/monitors/task.go +++ b/heartbeat/monitors/task.go @@ -37,7 +37,7 @@ type configuredJob struct { config jobConfig monitor *Monitor cancelFn context.CancelFunc - client beat.Client + client *WrappedClient } func newConfiguredJob(job jobs.Job, config jobConfig, monitor *Monitor) (*configuredJob, error) { @@ -74,17 +74,18 @@ func (t *configuredJob) makeSchedulerTaskFunc() scheduler.TaskFunc { } // Start schedules this configuredJob for execution. -func (t *configuredJob) Start() { +func (t *configuredJob) Start(client *WrappedClient) { var err error - t.client, err = t.monitor.pipelineConnector.Connect() + t.client = client + if err != nil { logp.Err("could not start monitor: %v", err) return } tf := t.makeSchedulerTaskFunc() - t.cancelFn, err = t.monitor.scheduler.Add(t.config.Schedule, t.monitor.stdFields.ID, tf, t.config.Type) + t.cancelFn, err = t.monitor.addTask(t.config.Schedule, t.monitor.stdFields.ID, tf, t.config.Type, client.wait) if err != nil { logp.Err("could not start monitor: %v", err) } @@ -100,7 +101,7 @@ func (t *configuredJob) Stop() { } } -func runPublishJob(job jobs.Job, client beat.Client) []scheduler.TaskFunc { +func runPublishJob(job jobs.Job, client *WrappedClient) []scheduler.TaskFunc { event := &beat.Event{ Fields: common.MapStr{}, } diff --git a/heartbeat/monitors/task_test.go b/heartbeat/monitors/task_test.go index dc0aa7ab23c4..64e86b35b882 100644 --- a/heartbeat/monitors/task_test.go +++ b/heartbeat/monitors/task_test.go @@ -96,7 +96,11 @@ func Test_runPublishJob(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { client := &MockBeatClient{} - queue := runPublishJob(tc.job, client) + queue := runPublishJob(tc.job, &WrappedClient{ + Publish: client.Publish, + Close: client.Close, + wait: func() {}, + }) for { if len(queue) == 0 { break diff --git a/heartbeat/scheduler/schedjob_test.go b/heartbeat/scheduler/schedjob_test.go index 48f4bf5a18b6..4a6f5e892aff 100644 --- a/heartbeat/scheduler/schedjob_test.go +++ b/heartbeat/scheduler/schedjob_test.go @@ -63,7 +63,7 @@ func TestSchedJobRun(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { limit := int64(100) - s := NewWithLocation(limit, monitoring.NewRegistry(), tarawaTime(), nil) + s := Create(limit, monitoring.NewRegistry(), tarawaTime(), nil, false) if testCase.overLimit { s.limitSem.Acquire(context.Background(), limit) @@ -98,9 +98,9 @@ func TestSchedJobRun(t *testing.T) { // testRecursiveForkingJob tests that a schedJob that splits into multiple parallel pieces executes without error func TestRecursiveForkingJob(t *testing.T) { - s := NewWithLocation(1000, monitoring.NewRegistry(), tarawaTime(), map[string]config.JobLimit{ + s := Create(1000, monitoring.NewRegistry(), tarawaTime(), map[string]config.JobLimit{ "atype": {Limit: 1}, - }) + }, false) ran := batomic.NewInt(0) var terminalTf TaskFunc = func(ctx context.Context) []TaskFunc { diff --git a/heartbeat/scheduler/scheduler.go b/heartbeat/scheduler/scheduler.go index 3b6d34fa5795..8de2d5760d67 100644 --- a/heartbeat/scheduler/scheduler.go +++ b/heartbeat/scheduler/scheduler.go @@ -22,23 +22,17 @@ import ( "errors" "fmt" "math" + "sync" "time" "golang.org/x/sync/semaphore" "github.com/elastic/beats/v7/heartbeat/config" "github.com/elastic/beats/v7/heartbeat/scheduler/timerqueue" - "github.com/elastic/beats/v7/libbeat/common/atomic" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/monitoring" ) -const ( - statePreRunning int = iota + 1 - stateRunning - stateStopped -) - var debugf = logp.MakeDebug("scheduler") // ErrInvalidTransition is returned from start/stop when making an invalid state transition, say from preRunning to stopped @@ -48,20 +42,20 @@ var ErrInvalidTransition = fmt.Errorf("invalid state transition") type Scheduler struct { limit int64 limitSem *semaphore.Weighted - state atomic.Int location *time.Location timerQueue *timerqueue.TimerQueue ctx context.Context cancelCtx context.CancelFunc stats schedulerStats jobLimitSem map[string]*semaphore.Weighted + runOnce bool + runOnceWg *sync.WaitGroup } type schedulerStats struct { activeJobs *monitoring.Uint // gauge showing number of active jobs activeTasks *monitoring.Uint // gauge showing number of active tasks waitingTasks *monitoring.Uint // number of tasks waiting to run, but constrained by scheduler limit - jobsPerSecond *monitoring.Uint // rate of job processing computed over the past hour jobsMissedDeadline *monitoring.Uint // counter for number of jobs that missed start deadline } @@ -88,13 +82,8 @@ func getJobLimitSem(jobLimitByType map[string]config.JobLimit) map[string]*semap return jobLimitSem } -// New creates a new Scheduler -func New(limit int64, registry *monitoring.Registry) *Scheduler { - return NewWithLocation(limit, registry, time.Local, nil) -} - // NewWithLocation creates a new Scheduler using the given runAt zone. -func NewWithLocation(limit int64, registry *monitoring.Registry, location *time.Location, jobLimitByType map[string]config.JobLimit) *Scheduler { +func Create(limit int64, registry *monitoring.Registry, location *time.Location, jobLimitByType map[string]config.JobLimit, runOnce bool) *Scheduler { ctx, cancelCtx := context.WithCancel(context.Background()) if limit < 1 { @@ -109,12 +98,13 @@ func NewWithLocation(limit int64, registry *monitoring.Registry, location *time. sched := &Scheduler{ limit: limit, location: location, - state: atomic.MakeInt(statePreRunning), ctx: ctx, cancelCtx: cancelCtx, limitSem: semaphore.NewWeighted(limit), jobLimitSem: getJobLimitSem(jobLimitByType), timerQueue: timerqueue.NewTimerQueue(ctx), + runOnce: runOnce, + runOnceWg: &sync.WaitGroup{}, stats: schedulerStats{ activeJobs: activeJobsGauge, @@ -124,24 +114,10 @@ func NewWithLocation(limit int64, registry *monitoring.Registry, location *time. }, } - return sched -} - -// Start the scheduler. Starting a stopped scheduler returns an error. -func (s *Scheduler) Start() error { - if s.state.Load() == stateStopped { - return ErrInvalidTransition - } - if !s.state.CAS(statePreRunning, stateRunning) { - return nil // we already running, just exit - } - - s.timerQueue.Start() + sched.timerQueue.Start() + go sched.missedDeadlineReporter() - // Missed deadline reporter - go s.missedDeadlineReporter() - - return nil + return sched } func (s *Scheduler) missedDeadlineReporter() { @@ -160,7 +136,7 @@ func (s *Scheduler) missedDeadlineReporter() { missingNow := s.stats.jobsMissedDeadline.Get() missedDelta := missingNow - missedAtLastCheck if missedDelta > 0 { - logp.Warn("%d tasks have missed their schedule deadlines in the last %s.", missedDelta, interval) + logp.Warn("%d tasks have missed their schedule deadlines by more than 1 second in the last %s.", missedDelta, interval) } missedAtLastCheck = missingNow } @@ -168,25 +144,28 @@ func (s *Scheduler) missedDeadlineReporter() { } // Stop all executing tasks in the scheduler. Cannot be restarted after Stop. -func (s *Scheduler) Stop() error { - if s.state.CAS(stateRunning, stateStopped) { - s.cancelCtx() - return nil - } else if s.state.Load() == stateStopped { - return nil - } +func (s *Scheduler) Stop() { + s.cancelCtx() +} - return ErrInvalidTransition +// Wait until all tasks are done if run in runOnce mode. Will block forever +// if this scheduler does not have the runOnce option set. +// Adding new tasks after this method is invoked is not supported. +func (s *Scheduler) WaitForRunOnce() { + s.runOnceWg.Wait() + s.Stop() } // ErrAlreadyStopped is returned when an Add operation is attempted after the scheduler // has already stopped. var ErrAlreadyStopped = errors.New("attempted to add job to already stopped scheduler") +type AddTask func(sched Schedule, id string, entrypoint TaskFunc, jobType string, waitForPublish func()) (removeFn context.CancelFunc, err error) + // Add adds the given TaskFunc to the current scheduler. Will return an error if the scheduler // is done. -func (s *Scheduler) Add(sched Schedule, id string, entrypoint TaskFunc, jobType string) (removeFn context.CancelFunc, err error) { - if s.state.Load() == stateStopped { +func (s *Scheduler) Add(sched Schedule, id string, entrypoint TaskFunc, jobType string, waitForPublish func()) (removeFn context.CancelFunc, err error) { + if errors.Is(s.ctx.Err(), context.Canceled) { return nil, ErrAlreadyStopped } @@ -207,20 +186,31 @@ func (s *Scheduler) Add(sched Schedule, id string, entrypoint TaskFunc, jobType } s.stats.activeJobs.Inc() debugf("Job '%s' started", id) - lastRanAt := newSchedJob(jobCtx, s, id, jobType, entrypoint).run() + sj := newSchedJob(jobCtx, s, id, jobType, entrypoint) + + lastRanAt := sj.run() s.stats.activeJobs.Dec() - s.runOnce(sched.Next(lastRanAt), taskFn) + + if s.runOnce { + waitForPublish() + s.runOnceWg.Done() + } else { + // Schedule the next run + s.runTaskOnce(sched.Next(lastRanAt), taskFn, true) + } debugf("Job '%v' returned at %v", id, time.Now()) } - // We skip using the scheduler to execute the initial tasks for jobs that have RunOnInit returning true. - // You might think it'd be simpler to just invoke runOnce in either case with 0 as a lastRanAt value, - // however, that would caused the missed deadline stats to be incremented. Given that, it's easier - // and slightly more efficient to simply run these tasks immediately in a goroutine. - if sched.RunOnInit() { - go taskFn(time.Now()) + if s.runOnce { + s.runOnceWg.Add(1) + } + + // Run non-cron tasks immediately, or run all tasks immediately if we're + // in RunOnce mode + if s.runOnce || sched.RunOnInit() { + s.runTaskOnce(time.Now(), taskFn, false) } else { - s.runOnce(sched.Next(lastRanAt), taskFn) + s.runTaskOnce(sched.Next(lastRanAt), taskFn, true) } return func() { @@ -229,15 +219,18 @@ func (s *Scheduler) Add(sched Schedule, id string, entrypoint TaskFunc, jobType }, nil } -func (s *Scheduler) runOnce(runAt time.Time, taskFn timerqueue.TimerTaskFn) { +// runTaskOnce runs the given task exactly once at the given time. Set deadlineCheck +// to false if this is the first invocation of this, otherwise the deadline checker +// will complain about a missed task +func (s *Scheduler) runTaskOnce(runAt time.Time, taskFn timerqueue.TimerTaskFn, deadlineCheck bool) { now := time.Now().In(s.location) - if runAt.Before(now) { - // Our last invocation went long! + // Check if the task is more than 1 second late + if deadlineCheck && runAt.Sub(now) < time.Second { s.stats.jobsMissedDeadline.Inc() } // Schedule task to run sometime in the future. Wrap the task in a go-routine so it doesn't - // block the timer thread. + // blocks the timer thread. asyncTask := func(now time.Time) { go taskFn(now) } s.timerQueue.Push(runAt, asyncTask) } diff --git a/heartbeat/scheduler/scheduler_test.go b/heartbeat/scheduler/scheduler_test.go index 61c062184a40..371be5f69efd 100644 --- a/heartbeat/scheduler/scheduler_test.go +++ b/heartbeat/scheduler/scheduler_test.go @@ -44,14 +44,8 @@ func tarawaTime() *time.Location { return loc } -func TestNew(t *testing.T) { - scheduler := New(123, monitoring.NewRegistry()) - assert.Equal(t, int64(123), scheduler.limit) - assert.Equal(t, time.Local, scheduler.location) -} - func TestNewWithLocation(t *testing.T) { - scheduler := NewWithLocation(123, monitoring.NewRegistry(), tarawaTime(), nil) + scheduler := Create(123, monitoring.NewRegistry(), tarawaTime(), nil, false) assert.Equal(t, int64(123), scheduler.limit) assert.Equal(t, tarawaTime(), scheduler.location) } @@ -83,23 +77,23 @@ func testTaskTimes(limit uint32, fn TaskFunc) TaskFunc { } } -func TestScheduler_Start(t *testing.T) { +func TestSchedulerRun(t *testing.T) { // We use tarawa runAt because it could expose some weird runAt math if by accident some code // relied on the local TZ. - s := NewWithLocation(10, monitoring.NewRegistry(), tarawaTime(), nil) + s := Create(10, monitoring.NewRegistry(), tarawaTime(), nil, false) defer s.Stop() executed := make(chan string) - preAddEvents := uint32(10) - s.Add(testSchedule{0}, "preAdd", testTaskTimes(preAddEvents, func(_ context.Context) []TaskFunc { - executed <- "preAdd" + initialEvents := uint32(10) + s.Add(testSchedule{0}, "add", testTaskTimes(initialEvents, func(_ context.Context) []TaskFunc { + executed <- "initial" cont := func(_ context.Context) []TaskFunc { - executed <- "preAddCont" + executed <- "initialCont" return nil } return []TaskFunc{cont} - }), "http") + }), "http", nil) removedEvents := uint32(1) // This function will be removed after being invoked once @@ -114,28 +108,26 @@ func TestScheduler_Start(t *testing.T) { } // Attempt to execute this twice to see if remove() had any effect removeMtx.Lock() - remove, err := s.Add(testSchedule{}, "removed", testTaskTimes(removedEvents+1, testFn), "http") + remove, err := s.Add(testSchedule{}, "removed", testTaskTimes(removedEvents+1, testFn), "http", nil) require.NoError(t, err) require.NotNil(t, remove) removeMtx.Unlock() - s.Start() - - postAddEvents := uint32(10) - s.Add(testSchedule{}, "postAdd", testTaskTimes(postAddEvents, func(_ context.Context) []TaskFunc { - executed <- "postAdd" + postRemoveEvents := uint32(10) + s.Add(testSchedule{}, "postRemove", testTaskTimes(postRemoveEvents, func(_ context.Context) []TaskFunc { + executed <- "postRemove" cont := func(_ context.Context) []TaskFunc { - executed <- "postAddCont" + executed <- "postRemoveCont" return nil } return []TaskFunc{cont} - }), "http") + }), "http", nil) received := make([]string, 0) // We test for a good number of events in this loop because we want to ensure that the remove() took effect - // Otherwise, we might only do 1 preAdd and 1 postAdd event + // Otherwise, we might only do 1 preAdd and 1 postRemove event // We double the number of pre/post add events to account for their continuations - totalExpected := preAddEvents*2 + removedEvents + postAddEvents*2 + totalExpected := initialEvents*2 + removedEvents + postRemoveEvents*2 for uint32(len(received)) < totalExpected { select { case got := <-executed: @@ -147,31 +139,53 @@ func TestScheduler_Start(t *testing.T) { } // The removed callback should only have been executed once - counts := map[string]uint32{"preAdd": 0, "postAdd": 0, "preAddCont": 0, "postAddcont": 0, "removed": 0} + counts := map[string]uint32{"initial": 0, "initialCont": 0, "removed": 0, "postRemove": 0, "postRemoveCont": 0} for _, s := range received { counts[s]++ } // convert with int() because the printed output is nicer than hex - assert.Equal(t, int(preAddEvents), int(counts["preAdd"])) - assert.Equal(t, int(preAddEvents), int(counts["preAddCont"])) - assert.Equal(t, int(postAddEvents), int(counts["postAdd"])) - assert.Equal(t, int(postAddEvents), int(counts["postAddCont"])) + assert.Equal(t, int(initialEvents), int(counts["initial"])) + assert.Equal(t, int(initialEvents), int(counts["initialCont"])) assert.Equal(t, int(removedEvents), int(counts["removed"])) + assert.Equal(t, int(postRemoveEvents), int(counts["postRemove"])) + assert.Equal(t, int(postRemoveEvents), int(counts["postRemoveCont"])) +} + +func TestScheduler_WaitForRunOnce(t *testing.T) { + s := Create(10, monitoring.NewRegistry(), tarawaTime(), nil, true) + + defer s.Stop() + + executed := new(uint32) + waits := new(uint32) + + s.Add(testSchedule{0}, "runOnce", func(_ context.Context) []TaskFunc { + cont := func(_ context.Context) []TaskFunc { + // Make sure we actually wait for the task! + time.Sleep(time.Millisecond * 250) + atomic.AddUint32(executed, 1) + return nil + } + return []TaskFunc{cont} + }, "http", func() { atomic.AddUint32(waits, 1) }) + + s.WaitForRunOnce() + require.Equal(t, uint32(1), atomic.LoadUint32(executed)) + require.Equal(t, uint32(1), atomic.LoadUint32(waits)) } func TestScheduler_Stop(t *testing.T) { - s := NewWithLocation(10, monitoring.NewRegistry(), tarawaTime(), nil) + s := Create(10, monitoring.NewRegistry(), tarawaTime(), nil, false) executed := make(chan struct{}) - require.NoError(t, s.Start()) - require.NoError(t, s.Stop()) + s.Stop() _, err := s.Add(testSchedule{}, "testPostStop", testTaskTimes(1, func(_ context.Context) []TaskFunc { executed <- struct{}{} return nil - }), "http") + }), "http", nil) assert.Equal(t, ErrAlreadyStopped, err) } @@ -235,7 +249,7 @@ func TestSchedTaskLimits(t *testing.T) { jobType: {Limit: tt.limit}, } } - s := NewWithLocation(math.MaxInt64, monitoring.NewRegistry(), tarawaTime(), jobConfigByType) + s := Create(math.MaxInt64, monitoring.NewRegistry(), tarawaTime(), jobConfigByType, false) var taskArr []int wg := sync.WaitGroup{} wg.Add(tt.numJobs) @@ -257,7 +271,7 @@ func TestSchedTaskLimits(t *testing.T) { } func BenchmarkScheduler(b *testing.B) { - s := NewWithLocation(0, monitoring.NewRegistry(), tarawaTime(), nil) + s := Create(0, monitoring.NewRegistry(), tarawaTime(), nil, false) sched := testSchedule{0} @@ -266,13 +280,11 @@ func BenchmarkScheduler(b *testing.B) { _, err := s.Add(sched, "testPostStop", func(_ context.Context) []TaskFunc { executed <- struct{}{} return nil - }, "http") + }, "http", nil) assert.NoError(b, err) } - err := s.Start() defer s.Stop() - assert.NoError(b, err) count := 0 for count < b.N { diff --git a/x-pack/functionbeat/function/core/sync_client.go b/libbeat/publisher/pipeline/sync_client.go similarity index 75% rename from x-pack/functionbeat/function/core/sync_client.go rename to libbeat/publisher/pipeline/sync_client.go index cc1b0c37f570..464143b31493 100644 --- a/x-pack/functionbeat/function/core/sync_client.go +++ b/libbeat/publisher/pipeline/sync_client.go @@ -1,8 +1,21 @@ -// 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 core +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package pipeline import ( "sync" @@ -14,9 +27,8 @@ import ( ) // Client implements the interface used by all the functionbeat function, we only implement a synchronous -// client. This interface superseed the core beat.Client interface inside functionbeat because our publish -// and publishAll methods can return an error. -type Client interface { +// client. This interface superseed the core beat.Client interface and can return errors on publish. +type ISyncClient interface { // Publish accepts a unique events and will publish it to the pipeline. Publish(beat.Event) error diff --git a/x-pack/functionbeat/function/core/sync_client_test.go b/libbeat/publisher/pipeline/sync_client_test.go similarity index 73% rename from x-pack/functionbeat/function/core/sync_client_test.go rename to libbeat/publisher/pipeline/sync_client_test.go index 4d5284eeb5cb..69a42164e1c8 100644 --- a/x-pack/functionbeat/function/core/sync_client_test.go +++ b/libbeat/publisher/pipeline/sync_client_test.go @@ -1,8 +1,21 @@ -// 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 core +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package pipeline import ( "testing" diff --git a/x-pack/functionbeat/function/beater/functionbeat.go b/x-pack/functionbeat/function/beater/functionbeat.go index be8d59b9db5c..9118fe771653 100644 --- a/x-pack/functionbeat/function/beater/functionbeat.go +++ b/x-pack/functionbeat/function/beater/functionbeat.go @@ -13,6 +13,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/fmtstr" "github.com/elastic/beats/v7/libbeat/outputs/elasticsearch" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" @@ -152,11 +153,11 @@ type fnExtraConfig struct { Index fmtstr.EventFormatString `config:"index"` } -func makeClientFactory(log *logp.Logger, pipeline beat.Pipeline, beatInfo beat.Info) func(*common.Config) (core.Client, error) { +func makeClientFactory(log *logp.Logger, pipe beat.Pipeline, beatInfo beat.Info) func(*common.Config) (pipeline.ISyncClient, error) { // Each function has his own client to the publisher pipeline, // publish operation will block the calling thread, when the method unwrap we have received the // ACK for the batch. - return func(cfg *common.Config) (core.Client, error) { + return func(cfg *common.Config) (pipeline.ISyncClient, error) { c := fnExtraConfig{} if err := cfg.Unpack(&c); err != nil { @@ -168,7 +169,7 @@ func makeClientFactory(log *logp.Logger, pipeline beat.Pipeline, beatInfo beat.I return nil, err } - client, err := core.NewSyncClient(log, pipeline, beat.ClientConfig{ + client, err := pipeline.NewSyncClient(log, pipe, beat.ClientConfig{ PublishMode: beat.GuaranteedSend, Processing: beat.ProcessingConfig{ Processor: funcProcessors, diff --git a/x-pack/functionbeat/function/provider/provider.go b/x-pack/functionbeat/function/provider/provider.go index a2198251a07a..c08db30e1d49 100644 --- a/x-pack/functionbeat/function/provider/provider.go +++ b/x-pack/functionbeat/function/provider/provider.go @@ -13,16 +13,17 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" ) // Create a new pipeline client based on the function configuration. -type clientFactory func(*common.Config) (core.Client, error) +type clientFactory func(*common.Config) (pipeline.ISyncClient, error) // Function is temporary type Function interface { - Run(context.Context, core.Client, telemetry.T) error + Run(context.Context, pipeline.ISyncClient, telemetry.T) error Name() string } diff --git a/x-pack/functionbeat/function/provider/provider_test.go b/x-pack/functionbeat/function/provider/provider_test.go index e93d8bd55463..6e940ff302b2 100644 --- a/x-pack/functionbeat/function/provider/provider_test.go +++ b/x-pack/functionbeat/function/provider/provider_test.go @@ -14,7 +14,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" ) @@ -22,7 +22,7 @@ type simpleFunction struct { err error } -func (s *simpleFunction) Run(ctx context.Context, client core.Client, _ telemetry.T) error { +func (s *simpleFunction) Run(ctx context.Context, client pipeline.ISyncClient, _ telemetry.T) error { return s.err } @@ -42,7 +42,7 @@ func TestRunnable(t *testing.T) { err := errors.New("oops") runnable := Runnable{ config: common.NewConfig(), - makeClient: func(cfg *common.Config) (core.Client, error) { return nil, err }, + makeClient: func(cfg *common.Config) (pipeline.ISyncClient, error) { return nil, err }, function: &simpleFunction{err: nil}, } @@ -54,7 +54,7 @@ func TestRunnable(t *testing.T) { err := errors.New("function error") runnable := Runnable{ config: common.NewConfig(), - makeClient: func(cfg *common.Config) (core.Client, error) { return &mockClient{}, nil }, + makeClient: func(cfg *common.Config) (pipeline.ISyncClient, error) { return &mockClient{}, nil }, function: &simpleFunction{err: err}, } @@ -65,7 +65,7 @@ func TestRunnable(t *testing.T) { t.Run("when there is no error run and exit normaly", func(t *testing.T) { runnable := Runnable{ config: common.NewConfig(), - makeClient: func(cfg *common.Config) (core.Client, error) { return &mockClient{}, nil }, + makeClient: func(cfg *common.Config) (pipeline.ISyncClient, error) { return &mockClient{}, nil }, function: &simpleFunction{err: nil}, } diff --git a/x-pack/functionbeat/function/provider/registry_test.go b/x-pack/functionbeat/function/provider/registry_test.go index 3e05e43db69a..cb24e0f0ca49 100644 --- a/x-pack/functionbeat/function/provider/registry_test.go +++ b/x-pack/functionbeat/function/provider/registry_test.go @@ -15,6 +15,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" ) @@ -49,8 +50,10 @@ type mockFunction struct { name string } -func (mf *mockFunction) Run(ctx context.Context, client core.Client, t telemetry.T) error { return nil } -func (mf *mockFunction) Name() string { return mf.name } +func (mf *mockFunction) Run(ctx context.Context, client pipeline.ISyncClient, t telemetry.T) error { + return nil +} +func (mf *mockFunction) Name() string { return mf.name } func testProviderLookup(t *testing.T) { name := "myprovider" diff --git a/x-pack/functionbeat/provider/aws/aws/api_gateway_proxy.go b/x-pack/functionbeat/provider/aws/aws/api_gateway_proxy.go index 6d897b9c8931..c8ecfe8786cd 100644 --- a/x-pack/functionbeat/provider/aws/aws/api_gateway_proxy.go +++ b/x-pack/functionbeat/provider/aws/aws/api_gateway_proxy.go @@ -16,7 +16,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws/transformer" @@ -45,7 +45,7 @@ func APIGatewayProxyDetails() feature.Details { } // Run starts the lambda function and wait for web triggers. -func (a *APIGatewayProxy) Run(_ context.Context, client core.Client, telemetry telemetry.T) error { +func (a *APIGatewayProxy) Run(_ context.Context, client pipeline.ISyncClient, telemetry telemetry.T) error { telemetry.AddTriggeredFunction() lambda.Start(a.createHandler(client)) @@ -53,7 +53,7 @@ func (a *APIGatewayProxy) Run(_ context.Context, client core.Client, telemetry t } func (a *APIGatewayProxy) createHandler( - client core.Client, + client pipeline.ISyncClient, ) func(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { return func(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { a.log.Debugf("The handler receives a new event from the gateway (requestID: %s)", request.RequestContext.RequestID) diff --git a/x-pack/functionbeat/provider/aws/aws/cloudwatch_kinesis.go b/x-pack/functionbeat/provider/aws/aws/cloudwatch_kinesis.go index cb976702ea5c..247e239dd498 100644 --- a/x-pack/functionbeat/provider/aws/aws/cloudwatch_kinesis.go +++ b/x-pack/functionbeat/provider/aws/aws/cloudwatch_kinesis.go @@ -15,7 +15,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws/transformer" @@ -70,14 +70,14 @@ func CloudwatchKinesisDetails() feature.Details { } // Run starts the lambda function and wait for web triggers. -func (c *CloudwatchKinesis) Run(_ context.Context, client core.Client, t telemetry.T) error { +func (c *CloudwatchKinesis) Run(_ context.Context, client pipeline.ISyncClient, t telemetry.T) error { t.AddTriggeredFunction() lambdarunner.Start(c.createHandler(client)) return nil } -func (c *CloudwatchKinesis) createHandler(client core.Client) func(request events.KinesisEvent) error { +func (c *CloudwatchKinesis) createHandler(client pipeline.ISyncClient) func(request events.KinesisEvent) error { return func(request events.KinesisEvent) error { c.log.Debugf("The handler receives %d events", len(request.Records)) diff --git a/x-pack/functionbeat/provider/aws/aws/cloudwatch_logs.go b/x-pack/functionbeat/provider/aws/aws/cloudwatch_logs.go index ebe379dfe495..7cfaab4fcaf8 100644 --- a/x-pack/functionbeat/provider/aws/aws/cloudwatch_logs.go +++ b/x-pack/functionbeat/provider/aws/aws/cloudwatch_logs.go @@ -22,7 +22,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws/transformer" @@ -106,7 +106,7 @@ func CloudwatchLogsDetails() feature.Details { } // Run start the AWS lambda handles and will transform any events received to the pipeline. -func (c *CloudwatchLogs) Run(_ context.Context, client core.Client, t telemetry.T) error { +func (c *CloudwatchLogs) Run(_ context.Context, client pipeline.ISyncClient, t telemetry.T) error { t.AddTriggeredFunction() lambdarunner.Start(c.createHandler(client)) @@ -114,7 +114,7 @@ func (c *CloudwatchLogs) Run(_ context.Context, client core.Client, t telemetry. } func (c *CloudwatchLogs) createHandler( - client core.Client, + client pipeline.ISyncClient, ) func(request events.CloudwatchLogsEvent) error { return func(request events.CloudwatchLogsEvent) error { parsedEvent, err := request.AWSLogs.Parse() diff --git a/x-pack/functionbeat/provider/aws/aws/kinesis.go b/x-pack/functionbeat/provider/aws/aws/kinesis.go index 2cdc02d075e7..3ff7a6513cfb 100644 --- a/x-pack/functionbeat/provider/aws/aws/kinesis.go +++ b/x-pack/functionbeat/provider/aws/aws/kinesis.go @@ -20,7 +20,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws/transformer" @@ -135,14 +135,14 @@ func KinesisDetails() feature.Details { } // Run starts the lambda function and wait for web triggers. -func (k *Kinesis) Run(_ context.Context, client core.Client, t telemetry.T) error { +func (k *Kinesis) Run(_ context.Context, client pipeline.ISyncClient, t telemetry.T) error { t.AddTriggeredFunction() lambdarunner.Start(k.createHandler(client)) return nil } -func (k *Kinesis) createHandler(client core.Client) func(request events.KinesisEvent) error { +func (k *Kinesis) createHandler(client pipeline.ISyncClient) func(request events.KinesisEvent) error { return func(request events.KinesisEvent) error { k.log.Debugf("The handler receives %d events", len(request.Records)) diff --git a/x-pack/functionbeat/provider/aws/aws/sqs.go b/x-pack/functionbeat/provider/aws/aws/sqs.go index 4bc1b9593e61..859c726884bf 100644 --- a/x-pack/functionbeat/provider/aws/aws/sqs.go +++ b/x-pack/functionbeat/provider/aws/aws/sqs.go @@ -18,7 +18,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws/transformer" @@ -68,14 +68,14 @@ func SQSDetails() feature.Details { } // Run starts the lambda function and wait for web triggers. -func (s *SQS) Run(_ context.Context, client core.Client, t telemetry.T) error { +func (s *SQS) Run(_ context.Context, client pipeline.ISyncClient, t telemetry.T) error { t.AddTriggeredFunction() lambdarunner.Start(s.createHandler(client)) return nil } -func (s *SQS) createHandler(client core.Client) func(request events.SQSEvent) error { +func (s *SQS) createHandler(client pipeline.ISyncClient) func(request events.SQSEvent) error { return func(request events.SQSEvent) error { s.log.Debugf("The handler receives %d events", len(request.Records)) diff --git a/x-pack/functionbeat/provider/local/local/local.go b/x-pack/functionbeat/provider/local/local/local.go index d7b76824a945..d0d849688d0b 100644 --- a/x-pack/functionbeat/provider/local/local/local.go +++ b/x-pack/functionbeat/provider/local/local/local.go @@ -13,7 +13,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/feature" - "github.com/elastic/beats/v7/x-pack/functionbeat/function/core" + "github.com/elastic/beats/v7/libbeat/publisher/pipeline" "github.com/elastic/beats/v7/x-pack/functionbeat/function/provider" "github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry" ) @@ -44,7 +44,7 @@ func NewStdinFunction( // Run reads events from the STDIN and send them to the publisher pipeline, will stop reading by // either by an external signal to stop or by reaching EOF. When EOF is reached functionbeat will shutdown. -func (s *StdinFunction) Run(ctx context.Context, client core.Client, _ telemetry.T) error { +func (s *StdinFunction) Run(ctx context.Context, client pipeline.ISyncClient, _ telemetry.T) error { errChan := make(chan error) defer close(errChan) lineChan := make(chan string) From 81ed8f848aa04788cdcb73715bc776ceb081c464 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Wed, 15 Dec 2021 03:35:27 -0600 Subject: [PATCH 086/172] Add default region config to AWS (#29415) * Add default regon config to AWS * update changelog * Add tests --- CHANGELOG.next.asciidoc | 1 + filebeat/docs/modules/aws.asciidoc | 10 ++++++ x-pack/filebeat/filebeat.reference.yml | 18 ++++++++++ x-pack/filebeat/module/aws/_meta/config.yml | 18 ++++++++++ .../filebeat/module/aws/_meta/docs.asciidoc | 10 ++++++ .../module/aws/cloudtrail/config/aws-s3.yml | 4 +-- .../module/aws/cloudtrail/manifest.yml | 1 + .../module/aws/cloudwatch/config/aws-s3.yml | 4 +++ .../module/aws/cloudwatch/manifest.yml | 1 + .../filebeat/module/aws/ec2/config/aws-s3.yml | 4 +++ x-pack/filebeat/module/aws/ec2/manifest.yml | 1 + .../filebeat/module/aws/elb/config/aws-s3.yml | 4 +++ x-pack/filebeat/module/aws/elb/manifest.yml | 1 + .../module/aws/s3access/config/aws-s3.yml | 4 +++ .../filebeat/module/aws/s3access/manifest.yml | 1 + .../module/aws/vpcflow/config/input.yml | 4 +++ .../filebeat/module/aws/vpcflow/manifest.yml | 1 + .../awsfargate/log/config/aws-cloudwatch.yml | 4 +++ .../module/awsfargate/log/manifest.yml | 1 + x-pack/filebeat/modules.d/aws.yml.disabled | 18 ++++++++++ x-pack/libbeat/common/aws/credentials.go | 18 +++++----- x-pack/libbeat/common/aws/credentials_test.go | 33 +++++++++++++++++++ .../docs/aws-credentials-config.asciidoc | 1 + 23 files changed, 150 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 02d272b963c6..15434665d0bf 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -230,6 +230,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Support self signed certificates on outputs {pull}29229[29229] - Update k8s library {pull}29394[29394] - Add FIPS configuration option for all AWS API calls. {pull}[28899] +- Add `default_region` config to AWS common module. {pull}[29415] *Auditbeat* diff --git a/filebeat/docs/modules/aws.asciidoc b/filebeat/docs/modules/aws.asciidoc index 097e22a741c8..65bc668de051 100644 --- a/filebeat/docs/modules/aws.asciidoc +++ b/filebeat/docs/modules/aws.asciidoc @@ -61,6 +61,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -79,6 +80,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -97,6 +99,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -115,6 +118,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -133,6 +137,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -151,6 +156,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 ---- @@ -192,6 +198,10 @@ Prefix to apply for the list request to the S3 bucket. Default empty. Custom endpoint used to access AWS APIs. +*`var.default_region`*:: + +Default region to query if no other region is set. + *`var.shared_credential_file`*:: Filename of AWS credential file. diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index d5df5da53ab5..1abc29932d80 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -151,6 +151,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -209,6 +212,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -267,6 +273,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -325,6 +334,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -383,6 +395,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -441,6 +456,9 @@ filebeat.modules: # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb diff --git a/x-pack/filebeat/module/aws/_meta/config.yml b/x-pack/filebeat/module/aws/_meta/config.yml index 35d92a11bfe0..60213ba811a1 100644 --- a/x-pack/filebeat/module/aws/_meta/config.yml +++ b/x-pack/filebeat/module/aws/_meta/config.yml @@ -54,6 +54,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -112,6 +115,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -170,6 +176,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -228,6 +237,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -286,6 +298,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -344,6 +359,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb diff --git a/x-pack/filebeat/module/aws/_meta/docs.asciidoc b/x-pack/filebeat/module/aws/_meta/docs.asciidoc index 3fee84601612..b9afe334257d 100644 --- a/x-pack/filebeat/module/aws/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/aws/_meta/docs.asciidoc @@ -56,6 +56,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -74,6 +75,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -92,6 +94,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -110,6 +113,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -128,6 +132,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 @@ -146,6 +151,7 @@ Example config: #var.visibility_timeout: 300s #var.api_timeout: 120s #var.endpoint: amazonaws.com + #var.default_region: us-east-1 #var.role_arn: arn:aws:iam::123456789012:role/test-mb #var.proxy_url: http://proxy:8080 ---- @@ -187,6 +193,10 @@ Prefix to apply for the list request to the S3 bucket. Default empty. Custom endpoint used to access AWS APIs. +*`var.default_region`*:: + +Default region to query if no other region is set. + *`var.shared_credential_file`*:: Filename of AWS credential file. diff --git a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml index 48f38574e711..8c98bc31be6f 100644 --- a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml @@ -49,8 +49,8 @@ visibility_timeout: {{ .visibility_timeout }} api_timeout: {{ .api_timeout }} {{ end }} -{{ if .endpoint }} -endpoint: {{ .endpoint }} +{{ if .default_region }} +default_region: {{ .default_region }} {{ end }} {{ if .access_key_id }} diff --git a/x-pack/filebeat/module/aws/cloudtrail/manifest.yml b/x-pack/filebeat/module/aws/cloudtrail/manifest.yml index 1eb9d949b014..f19760eb6372 100644 --- a/x-pack/filebeat/module/aws/cloudtrail/manifest.yml +++ b/x-pack/filebeat/module/aws/cloudtrail/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml b/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml index d972e73ee317..8ce1970290d2 100644 --- a/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/cloudwatch/config/aws-s3.yml @@ -38,6 +38,10 @@ api_timeout: {{ .api_timeout }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/aws/cloudwatch/manifest.yml b/x-pack/filebeat/module/aws/cloudwatch/manifest.yml index 7ffff3514a0f..e52ba6737579 100644 --- a/x-pack/filebeat/module/aws/cloudwatch/manifest.yml +++ b/x-pack/filebeat/module/aws/cloudwatch/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml b/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml index d972e73ee317..8ce1970290d2 100644 --- a/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/ec2/config/aws-s3.yml @@ -38,6 +38,10 @@ api_timeout: {{ .api_timeout }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/aws/ec2/manifest.yml b/x-pack/filebeat/module/aws/ec2/manifest.yml index 7ffff3514a0f..e52ba6737579 100644 --- a/x-pack/filebeat/module/aws/ec2/manifest.yml +++ b/x-pack/filebeat/module/aws/ec2/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/aws/elb/config/aws-s3.yml b/x-pack/filebeat/module/aws/elb/config/aws-s3.yml index d972e73ee317..8ce1970290d2 100644 --- a/x-pack/filebeat/module/aws/elb/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/elb/config/aws-s3.yml @@ -38,6 +38,10 @@ api_timeout: {{ .api_timeout }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/aws/elb/manifest.yml b/x-pack/filebeat/module/aws/elb/manifest.yml index 5f0b2d16e3dd..4ab87c2b6868 100644 --- a/x-pack/filebeat/module/aws/elb/manifest.yml +++ b/x-pack/filebeat/module/aws/elb/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml b/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml index d972e73ee317..8ce1970290d2 100644 --- a/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/s3access/config/aws-s3.yml @@ -38,6 +38,10 @@ api_timeout: {{ .api_timeout }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/aws/s3access/manifest.yml b/x-pack/filebeat/module/aws/s3access/manifest.yml index 7ffff3514a0f..e52ba6737579 100644 --- a/x-pack/filebeat/module/aws/s3access/manifest.yml +++ b/x-pack/filebeat/module/aws/s3access/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/aws/vpcflow/config/input.yml b/x-pack/filebeat/module/aws/vpcflow/config/input.yml index 6ac1ceccf669..5c08c0e6e386 100644 --- a/x-pack/filebeat/module/aws/vpcflow/config/input.yml +++ b/x-pack/filebeat/module/aws/vpcflow/config/input.yml @@ -40,6 +40,10 @@ api_timeout: {{ .api_timeout }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/aws/vpcflow/manifest.yml b/x-pack/filebeat/module/aws/vpcflow/manifest.yml index be8642f06cb9..b329c7264f19 100644 --- a/x-pack/filebeat/module/aws/vpcflow/manifest.yml +++ b/x-pack/filebeat/module/aws/vpcflow/manifest.yml @@ -13,6 +13,7 @@ var: - name: visibility_timeout - name: api_timeout - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml b/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml index 958228e74dac..08b37cd3aef8 100644 --- a/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml +++ b/x-pack/filebeat/module/awsfargate/log/config/aws-cloudwatch.yml @@ -40,6 +40,10 @@ shared_credential_file: {{ .shared_credential_file }} endpoint: {{ .endpoint }} {{ end }} +{{ if .default_region }} +default_region: {{ .default_region }} +{{ end }} + {{ if .access_key_id }} access_key_id: {{ .access_key_id }} {{ end }} diff --git a/x-pack/filebeat/module/awsfargate/log/manifest.yml b/x-pack/filebeat/module/awsfargate/log/manifest.yml index 47fbc7697d10..9c724ff1a03e 100644 --- a/x-pack/filebeat/module/awsfargate/log/manifest.yml +++ b/x-pack/filebeat/module/awsfargate/log/manifest.yml @@ -6,6 +6,7 @@ var: - name: shared_credential_file - name: credential_profile_name - name: endpoint + - name: default_region - name: access_key_id - name: secret_access_key - name: session_token diff --git a/x-pack/filebeat/modules.d/aws.yml.disabled b/x-pack/filebeat/modules.d/aws.yml.disabled index 1cde529a6d3e..efca82457008 100644 --- a/x-pack/filebeat/modules.d/aws.yml.disabled +++ b/x-pack/filebeat/modules.d/aws.yml.disabled @@ -57,6 +57,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -115,6 +118,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -173,6 +179,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -231,6 +240,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -289,6 +301,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb @@ -347,6 +362,9 @@ # Custom endpoint used to access AWS APIs #var.endpoint: amazonaws.com + # Default region to query if no other region is set + #var.default_region: us-east-1 + # AWS IAM Role to assume #var.role_arn: arn:aws:iam::123456789012:role/test-mb diff --git a/x-pack/libbeat/common/aws/credentials.go b/x-pack/libbeat/common/aws/credentials.go index 9b6d80c95289..0b03155e0f1d 100644 --- a/x-pack/libbeat/common/aws/credentials.go +++ b/x-pack/libbeat/common/aws/credentials.go @@ -40,11 +40,19 @@ type ConfigAWS struct { ProxyUrl string `config:"proxy_url"` FIPSEnabled bool `config:"fips_enabled"` TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty" json:"ssl,omitempty"` + DefaultRegion string `config:"default_region"` } // InitializeAWSConfig function creates the awssdk.Config object from the provided config func InitializeAWSConfig(config ConfigAWS) (awssdk.Config, error) { AWSConfig, _ := GetAWSCredentials(config) + if AWSConfig.Region == "" { + if config.DefaultRegion != "" { + AWSConfig.Region = config.DefaultRegion + } else { + AWSConfig.Region = "us-east-1" + } + } var proxy func(*http.Request) (*url.URL, error) if config.ProxyUrl != "" { proxyUrl, err := httpcommon.NewProxyURIFromString(config.ProxyUrl) @@ -97,11 +105,6 @@ func getAccessKeys(config ConfigAWS) awssdk.Config { Value: awsCredentials, } - // Set default region if empty to make initial aws api call - if awsConfig.Region == "" { - awsConfig.Region = "us-east-1" - } - // Assume IAM role if iam_role config parameter is given if config.RoleArn != "" { logger.Debug("Using role arn and access keys for AWS credential") @@ -135,11 +138,6 @@ func getSharedCredentialProfile(config ConfigAWS) (awssdk.Config, error) { return awsConfig, errors.Wrap(err, "external.LoadDefaultAWSConfig failed with shared credential profile given") } - // Set default region if empty to make initial aws api call - if awsConfig.Region == "" { - awsConfig.Region = "us-east-1" - } - // Assume IAM role if iam_role config parameter is given if config.RoleArn != "" { logger.Debug("Using role arn and shared credential profile for AWS credential") diff --git a/x-pack/libbeat/common/aws/credentials_test.go b/x-pack/libbeat/common/aws/credentials_test.go index e3c21875385a..3b5c6233cfcf 100644 --- a/x-pack/libbeat/common/aws/credentials_test.go +++ b/x-pack/libbeat/common/aws/credentials_test.go @@ -162,3 +162,36 @@ func TestCreateServiceName(t *testing.T) { }) } } + +func TestDefaultRegion(t *testing.T) { + cases := []struct { + title string + region string + expectedRegion string + }{ + { + "No default region set", + "", + "us-east-1", + }, + { + "us-west-1 region set as default", + "us-west-1", + "us-west-1", + }, + } + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + inputConfig := ConfigAWS{ + AccessKeyID: "123", + SecretAccessKey: "abc", + } + if c.region != "" { + inputConfig.DefaultRegion = c.region + } + awsConfig, err := InitializeAWSConfig(inputConfig) + assert.NoError(t, err) + assert.Equal(t, c.expectedRegion, awsConfig.Region) + }) + } +} diff --git a/x-pack/libbeat/docs/aws-credentials-config.asciidoc b/x-pack/libbeat/docs/aws-credentials-config.asciidoc index 63a0a0cb6395..3ccfd09a84dd 100644 --- a/x-pack/libbeat/docs/aws-credentials-config.asciidoc +++ b/x-pack/libbeat/docs/aws-credentials-config.asciidoc @@ -20,6 +20,7 @@ the `endpoint-code` part, such as `amazonaws.com`, `amazonaws.com.cn`, `c2s.ic.g * *proxy_url*: URL of the proxy to use to connect to AWS web services. The syntax is `http(s)://:` * *fips_enabled*: Enabling this option changes the service names from `s3` to `s3-fips` for connecting to the correct service endpoint. For example: `s3-fips.us-gov-east-1.amazonaws.com`. All services used by Beats are FIPS compatible except for `tagging` but only certain regions are FIPS compatible. See https://aws.amazon.com/compliance/fips/ or the appropriate service page, https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html, for a full list of FIPS endpoints and regions. * *ssl*: This specifies SSL/TLS configuration. If the ssl section is missing, the host's CAs are used for HTTPS connections. See <> for more information. +* *default_region*: Default region to query if no other region is set. [float] ==== Supported Formats From d06ac626ffe65922b338630b1330b96fa2ee3a0b Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Wed, 15 Dec 2021 05:42:12 -0500 Subject: [PATCH 087/172] [Automation] Update go release version to 1.17.5 (#29384) Co-authored-by: apmmachine --- .go-version | 2 +- auditbeat/Dockerfile | 2 +- filebeat/Dockerfile | 2 +- heartbeat/Dockerfile | 2 +- libbeat/Dockerfile | 2 +- libbeat/docs/version.asciidoc | 2 +- metricbeat/Dockerfile | 2 +- packetbeat/Dockerfile | 2 +- x-pack/elastic-agent/Dockerfile | 2 +- x-pack/functionbeat/Dockerfile | 2 +- x-pack/libbeat/Dockerfile | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.go-version b/.go-version index 06fb41b6322f..ff278344b339 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.17.2 +1.17.5 diff --git a/auditbeat/Dockerfile b/auditbeat/Dockerfile index ceccec4026d8..061539b6dcf3 100644 --- a/auditbeat/Dockerfile +++ b/auditbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/filebeat/Dockerfile b/filebeat/Dockerfile index b4db21234568..763572e5a991 100644 --- a/filebeat/Dockerfile +++ b/filebeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/heartbeat/Dockerfile b/heartbeat/Dockerfile index 0108b788c354..355510ff31fa 100644 --- a/heartbeat/Dockerfile +++ b/heartbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/libbeat/Dockerfile b/libbeat/Dockerfile index e02f709d1912..3ff2e7a8ce43 100644 --- a/libbeat/Dockerfile +++ b/libbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/libbeat/docs/version.asciidoc b/libbeat/docs/version.asciidoc index 47386bc5ca1a..a09f29c66bf8 100644 --- a/libbeat/docs/version.asciidoc +++ b/libbeat/docs/version.asciidoc @@ -1,6 +1,6 @@ :stack-version: 8.0.0 :doc-branch: master -:go-version: 1.17.2 +:go-version: 1.17.5 :release-state: unreleased :python: 3.7 :docker: 1.12 diff --git a/metricbeat/Dockerfile b/metricbeat/Dockerfile index 0e9f1d08d14a..d9166f054f13 100644 --- a/metricbeat/Dockerfile +++ b/metricbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt update \ diff --git a/packetbeat/Dockerfile b/packetbeat/Dockerfile index d7d9ed89fe67..6223e3d70f0d 100644 --- a/packetbeat/Dockerfile +++ b/packetbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/x-pack/elastic-agent/Dockerfile b/x-pack/elastic-agent/Dockerfile index 5b2e9d845865..9c7dce7a435e 100644 --- a/x-pack/elastic-agent/Dockerfile +++ b/x-pack/elastic-agent/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_VERSION=1.17.2 +ARG GO_VERSION=1.17.5 FROM circleci/golang:${GO_VERSION} diff --git a/x-pack/functionbeat/Dockerfile b/x-pack/functionbeat/Dockerfile index 70d7f46a2cd6..f07760a84870 100644 --- a/x-pack/functionbeat/Dockerfile +++ b/x-pack/functionbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ diff --git a/x-pack/libbeat/Dockerfile b/x-pack/libbeat/Dockerfile index 2c51fb632b28..12ce0e092039 100644 --- a/x-pack/libbeat/Dockerfile +++ b/x-pack/libbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.2 +FROM golang:1.17.5 RUN \ apt-get update \ From 6c268f8f0ec1d8ad3f7590d387133412654ba839 Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Wed, 15 Dec 2021 15:22:24 +0100 Subject: [PATCH 088/172] CA trusted fingerprint tests (#29347) This commit adds tests to `trustRootCA` and `makeVerifyConnection`, the tests aim to cover the usage of `ssl.ca_tursted_fingerprint`. Some existing tests were refactored, `openTestCerts` receives a `testing.TB` and fail tests in case of an error --- .../transport/tlscommon/testdata/es-leaf.crt | 32 +++ .../tlscommon/testdata/es-root-ca-cert.crt | 31 +++ .../transport/tlscommon/tls_config_test.go | 196 ++++++++++++++++-- 3 files changed, 247 insertions(+), 12 deletions(-) create mode 100644 libbeat/common/transport/tlscommon/testdata/es-leaf.crt create mode 100644 libbeat/common/transport/tlscommon/testdata/es-root-ca-cert.crt diff --git a/libbeat/common/transport/tlscommon/testdata/es-leaf.crt b/libbeat/common/transport/tlscommon/testdata/es-leaf.crt new file mode 100644 index 000000000000..89d5087eb942 --- /dev/null +++ b/libbeat/common/transport/tlscommon/testdata/es-leaf.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFeDCCA2CgAwIBAgIUV7+XlHjcV++/ezqTkJrXSFc1dpAwDQYJKoZIhvcNAQEL +BQAwPDE6MDgGA1UEAxMxRWxhc3RpY3NlYXJjaCBzZWN1cml0eSBhdXRvLWNvbmZp +Z3VyYXRpb24gSFRUUCBDQTAeFw0yMTExMzAxMDMzNTdaFw0yMzExMzAxMDMzNTda +MBExDzANBgNVBAMTBngtd2luZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALL045X6ywAHg9tWuViNyXu30rHhJa/AI45ZwLWzQMEwnCWnMvV0Cy3FgUd6 +VKw4Rg55/SfBKShhTRjC4PmDIHDIBgpm4NWpREIW2+cZfeEU8B34ucK/ZHycTFQ1 +Guh8HfvFy5J3OYT+8Wfz94ZxvVLMOGROTSiWdL2foVk98tbHgL1K3qyv1v0rgIjt +smZ7G4tbl3sBCuYceUL7X/+0kavJGls2T/rtxxEIfj5dNz4h65KmABrrAJfrEx35 +y2jCdY2XQsBxxMvbHEXXJKhrjQ8pajMcWAlDBKweiNIDdgBDYWpodpr4f3A6ZJkM +Nplw7KyLna4s3BO/g7fd5/FyQGFuLPraFtFnTXGqH+LjX0td74bdSP22/uhU3cKY +3y64I3/HEaEY5JITgUArExcMVpXuKJKqXEb+LtjGmUbAiO8Z7QKL+PqmU+3tJJ0p +kXnS07m3F/MgrDir/VCnYGQcXeteBwEgmcOwPmxz98eOSBhtb0PrimycF2tQuT8b +mCU+evTPC+KQ+8XY5vBwdPGpf6YAaHuVhNtKqBQnYOpsadS7zw5DJ0Y1Kp9z0ZPL +ch4DxE40xqAFmxWnAfpy2scD8LGJ1zDII90tAtYdu+3Wlzj6uMqUdqPuJED7XD41 +mlF2OjB5ipTs/1Jjl3pEnGG94sw5bQmnS1xFQp/DO3mjlgFBAgMBAAGjgZwwgZkw +HQYDVR0OBBYEFJKNxskBHE5xQ9S24puXSKm6/bLKMB8GA1UdIwQYMBaAFHEdsBBS +VCiK0fDIVe2vNN8JvHmcMEwGA1UdEQRFMEOHEP6AAAAAAAAAtw+3JU5DX8mCCWxv +Y2FsaG9zdIcQAAAAAAAAAAAAAAAAAAAAAYcEfwAAAYcEwKgqtoIGeC13aW5nMAkG +A1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAF5JAIQ9cu2xroh2F85fBr/F0s8D +aRV6AJpkjSVKInMm7omn+GLB80TwQZ6NsGuXrbaq0rcM85khsBs4rWn5MqescYG/ +8A7gZ4EtYE3LIyeqiqBByrtIqszZeXm7ITDSF/lwn7X2swe7orkhVD4tVEvKH6L6 +Ql0oNe5UBN1Rm9NskDltMDzE2A25slkm99CAdPERDEjBpvd3eDcfbQdHeuAOPfUV +T8P2DAdW4SC955bxnc0GPTla5TKXWWLde3egow5a4LeJv6KVWPTC9chEXZyQKp4p +jvWZW1fTO/kC3oj97tfqoH/r35/+qyXmg38HNAFbEoVM3bsO0vqrI5CbkWTkB1Xb +7CY6jJxemyEprl2gmkgfA/MXBHFc3RoIL7JcX7Sk8ZWpnEVK3KyoyK1RJ5kY1Cz4 +SRw4KLJA4Cu6DE7vXy9pTlIeeQARgQOUxnrlRGYHpKRIwgjrhwEjVqc0CPwj7rWr +0VY4MW80FPFIePpqy3DjoJmORQU632iu/5zeUS4dZ11Ms7NTakqqnFHi7XczqeZn +4HqPW8ebQTXrqRXMF/X30x6gkK1R1tXHSbve7cTQWJEwJd+MS2aA5Npt7hGznjPn +Y1p4k9jEz5BnbLtZ2RbAj2FuL4Ee6iJoyZpFbi/SW+h+1ZaPCeUTnxUkDLEiXpdk +tN8H6/6dudhy6btm +-----END CERTIFICATE----- diff --git a/libbeat/common/transport/tlscommon/testdata/es-root-ca-cert.crt b/libbeat/common/transport/tlscommon/testdata/es-root-ca-cert.crt new file mode 100644 index 000000000000..6234774adc9f --- /dev/null +++ b/libbeat/common/transport/tlscommon/testdata/es-root-ca-cert.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIUAoPlJ3hVr921EyJfiT+9lVft3fcwDQYJKoZIhvcNAQEL +BQAwPDE6MDgGA1UEAxMxRWxhc3RpY3NlYXJjaCBzZWN1cml0eSBhdXRvLWNvbmZp +Z3VyYXRpb24gSFRUUCBDQTAeFw0yMTExMzAxMDMzNTdaFw0yNDExMjkxMDMzNTda +MDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25maWd1 +cmF0aW9uIEhUVFAgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2 +soq+heCJNHsMuyyyLndREhYmxYFav06XOLB5oC1bAt+0WMo3n7rxVB8dAhfvigof +DsTIytnCcK+Th8ll2k4Bs2weF16ZhvvC2FKbSkdUxNXnXfx7gdKDXZLbfref5FiL +ucwxa7CtVL28Lfws9J5dZTTAuxR2XxaX+TJbH6MbQgKUYR+DnK8T3jSfiDTQtiHs ++pd+C8hSdMgzKCynYP36VZbtz1ynWjvQ/0wxARO6q2OLZGBNh2ncoFEmosXgc0ir +Vh9NrVmozSI0H2f6W07imqL3oe1pe3bwW/OdfeahCBY3IvDLDn8q8wDl91gRta3n +EsMsiuBRSRRpT0grgoCFNy+wiIrETVLaI2HJ0UpVIpcoS7K5l2zN/wA+w+hAOdh0 +PoBt8AoC1aCCGM4osCTKqbgbOg957io2twuvWJ6ae3J2k5FFDMvIfMfL+5HhPSRp +nYiRDPOhapDhaXhHa4pEFONpdiJJgmqymLqjW4liZOGft28dSkISK3iiBL74p/gu +X/sBI7PZANycpyVjnLHK+FwPlRZPkrqCw2Gke4Oqm9uydwM08uRVZcNylVS7H0ip +9BEcxKlXJSaULnTqQXkiPGKGkCrrIIsNQTFjoaBIBP2o69NSZ0SozDf4aCnYy10v +U1dwI9yisOmMfDkakNcAPXfRfmuuJlstl1W1RraQswIDAQABo1MwUTAdBgNVHQ4E +FgQUcR2wEFJUKIrR8MhV7a803wm8eZwwHwYDVR0jBBgwFoAUcR2wEFJUKIrR8MhV +7a803wm8eZwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAiHrC +NxCNsyUYLFVivL9AsJ5Y3IrhAHUzYwofLBJiMYNFsaEi3P1VU3TNlo98kzi2QkdY +NPFtRYoOg6sEI0KPEBw54kLP/Q/FJK7jeJSyhJ9V/Z+NS081YHqrMP4YPK6mM4qa +XuM7hpx37vkLDdfrDPionbcLk7Zz+2t6bIThrwta0idMY6LKeFfW1EWeggK6inNc +Ub3n1qcTyOp1RfcLlHCdb17JhgY5hROmqVfhgLlbT0bx1NZS4pRWhw5CDKsflMUe +SyHbLE1BTH6yE0nNXbR6FgDKjQNUSSZBOBck0hdSaRArALavujjBojHmJYWt1jWO +bcBErzwKKwH/peUh7Wgnq1L/lqym9K9AniWUyhvKn8AbxGLnILDMYOSrvlPF2uU+ +uvp2EzhPUyOgYycC28H4fFUdDeoN5FVP+4sFFK+FIgfqLfVMTgDPmGAbkqA6WKlH +fgQ2fP4oB2ZkN0EPxivXkvZkhDVlIXeoisUkNCgAfVuwCjvOLnqz8u0tTnp/wXxq +XAXUPLcG71YFzABlkwuPdA5GhFAL1Rv8GQJEznhZ8mYz/yTtcg/z3pYEhDcM92Cb +161BormFYVRI1B80rSpzeQwJVfvgCwnWOTat+1joFHCzpl99nHu8tMxi6lkO1G9E +8vdk/J0zMMnhO52V2EMNdH2fTJUMZYixBm4BeEM= +-----END CERTIFICATE----- diff --git a/libbeat/common/transport/tlscommon/tls_config_test.go b/libbeat/common/transport/tlscommon/tls_config_test.go index 76dfa61497f0..2fd0b76e2a06 100644 --- a/libbeat/common/transport/tlscommon/tls_config_test.go +++ b/libbeat/common/transport/tlscommon/tls_config_test.go @@ -26,13 +26,11 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMakeVerifyServerConnection(t *testing.T) { - testCerts, err := openTestCerts() - if err != nil { - t.Fatalf("failed to open test certs: %+v", err) - } + testCerts := openTestCerts(t) testCA, errs := LoadCertificateAuthorities([]string{ filepath.Join("testdata", "ca.crt"), @@ -159,7 +157,6 @@ func TestMakeVerifyServerConnection(t *testing.T) { for name, test := range testcases { t.Run(name, func(t *testing.T) { - test := test cfg := &TLSConfig{ Verification: test.verificationMode, ClientAuth: test.clientAuth, @@ -177,16 +174,20 @@ func TestMakeVerifyServerConnection(t *testing.T) { ServerName: test.serverName, }) if test.expectedError == nil { - assert.Nil(t, err) + assert.NoError(t, err) } else { - assert.Error(t, test.expectedError, err) + require.Error(t, err) + // We want to ensure the error type/message are the expected ones + // so we compare the types and the message + assert.IsType(t, test.expectedError, err) + assert.Contains(t, err.Error(), test.expectedError.Error()) } }) } - } -func openTestCerts() (map[string]*x509.Certificate, error) { +func openTestCerts(t testing.TB) map[string]*x509.Certificate { + t.Helper() certs := make(map[string]*x509.Certificate, 0) for testcase, certname := range map[string]string{ @@ -194,19 +195,190 @@ func openTestCerts() (map[string]*x509.Certificate, error) { "unknown authority": "unsigned_tls.crt", "correct": "client1.crt", "wildcard": "server.crt", + "es-leaf": "es-leaf.crt", + "es-root-ca": "es-root-ca-cert.crt", } { certBytes, err := ioutil.ReadFile(filepath.Join("testdata", certname)) if err != nil { - return nil, err + t.Fatalf("reading file %q: %+v", certname, err) } block, _ := pem.Decode(certBytes) testCert, err := x509.ParseCertificate(block.Bytes) if err != nil { - return nil, err + t.Fatalf("parsing certificate %q: %+v", certname, err) } certs[testcase] = testCert } - return certs, nil + return certs +} + +func TestTrustRootCA(t *testing.T) { + certs := openTestCerts(t) + + nonEmptyCertPool := x509.NewCertPool() + nonEmptyCertPool.AddCert(certs["wildcard"]) + nonEmptyCertPool.AddCert(certs["unknown authority"]) + + testCases := []struct { + name string + rootCAs *x509.CertPool + caTrustedFingerprint string + peerCerts []*x509.Certificate + expectingError bool + expectedRootCAsLen int + }{ + { + name: "RootCA cert matches the fingerprint and is added to cfg.RootCAs", + caTrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + peerCerts: []*x509.Certificate{certs["es-leaf"], certs["es-root-ca"]}, + expectedRootCAsLen: 1, + }, + { + name: "RootCA cert doesn not matche the fingerprint and is not added to cfg.RootCAs", + caTrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + peerCerts: []*x509.Certificate{certs["es-leaf"], certs["es-root-ca"]}, + expectedRootCAsLen: 0, + }, + { + name: "non empty CertPool has the RootCA added", + rootCAs: nonEmptyCertPool, + caTrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + peerCerts: []*x509.Certificate{certs["es-leaf"], certs["es-root-ca"]}, + expectedRootCAsLen: 3, + }, + { + name: "invalis HEX encoding", + caTrustedFingerprint: "INVALID ENCODING", + expectedRootCAsLen: 0, + expectingError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cfg := TLSConfig{ + RootCAs: tc.rootCAs, + CATrustedFingerprint: tc.caTrustedFingerprint, + } + err := trustRootCA(&cfg, tc.peerCerts) + if tc.expectingError && err == nil { + t.Fatal("expecting an error when calling trustRootCA") + } + + if !tc.expectingError && err != nil { + t.Fatalf("did not expect an error calling trustRootCA: %v", err) + } + + if tc.expectedRootCAsLen != 0 { + if cfg.RootCAs == nil { + t.Fatal("cfg.RootCAs cannot be nil") + } + + // we want to know the number of certificates in the CertPool (RootCAs), as it is not + // directly available, we use this workaround of reading the number of subjects in the pool. + if got, expected := len(cfg.RootCAs.Subjects()), tc.expectedRootCAsLen; got != expected { + t.Fatalf("expecting cfg.RootCAs to have %d element, got %d instead", expected, got) + } + } + }) + } +} + +func TestMakeVerifyConnectionUsesCATrustedFingerprint(t *testing.T) { + testCerts := openTestCerts(t) + + testcases := map[string]struct { + verificationMode TLSVerificationMode + peerCerts []*x509.Certificate + serverName string + expectedCallback bool + expectingError bool + CATrustedFingerprint string + CASHA256 []string + }{ + "CATrustedFingerprint and verification mode:VerifyFull": { + verificationMode: VerifyFull, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + }, + "CATrustedFingerprint and verification mode:VerifyCertificate": { + verificationMode: VerifyCertificate, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + }, + "CATrustedFingerprint and verification mode:VerifyStrict": { + verificationMode: VerifyStrict, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "e83171aa133b2b507e057fe091e296a7e58e9653c2b88d203b64a47eef6ec62b", + CASHA256: []string{Fingerprint(testCerts["es-leaf"])}, + }, + "CATrustedFingerprint and verification mode:VerifyNone": { + verificationMode: VerifyNone, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: false, + }, + "invalid CATrustedFingerprint and verification mode:VerifyFull returns error": { + verificationMode: VerifyFull, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "INVALID HEX ENCODING", + expectingError: true, + }, + "invalid CATrustedFingerprint and verification mode:VerifyCertificate returns error": { + verificationMode: VerifyCertificate, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "INVALID HEX ENCODING", + expectingError: true, + }, + "invalid CATrustedFingerprint and verification mode:VerifyStrict returns error": { + verificationMode: VerifyStrict, + peerCerts: []*x509.Certificate{testCerts["es-leaf"], testCerts["es-root-ca"]}, + serverName: "localhost", + expectedCallback: true, + CATrustedFingerprint: "INVALID HEX ENCODING", + expectingError: true, + CASHA256: []string{Fingerprint(testCerts["es-leaf"])}, + }, + } + + for name, test := range testcases { + t.Run(name, func(t *testing.T) { + cfg := &TLSConfig{ + Verification: test.verificationMode, + CATrustedFingerprint: test.CATrustedFingerprint, + CASha256: test.CASHA256, + } + + verifier := makeVerifyConnection(cfg) + if test.expectedCallback { + require.NotNil(t, verifier, "makeVerifyConnection returned a nil verifier") + } else { + require.Nil(t, verifier) + return + } + + err := verifier(tls.ConnectionState{ + PeerCertificates: test.peerCerts, + ServerName: test.serverName, + VerifiedChains: [][]*x509.Certificate{test.peerCerts}, + }) + if test.expectingError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } } From 533eefb74f773cfa34a15a9cdd74c8365db2f355 Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Thu, 16 Dec 2021 02:24:18 -0500 Subject: [PATCH 089/172] [Automation] Update elastic stack version to 8.1.0-d8a3a806 for testing (#29463) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index 7ca185c80fe2..ce828d0f5ab3 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b6e7e1f3-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-d8a3a806-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-b6e7e1f3-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-d8a3a806-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-b6e7e1f3-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-d8a3a806-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 4cf5ba1db37e..2ef97dfeebd7 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b6e7e1f3-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-d8a3a806-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-b6e7e1f3-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-d8a3a806-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 9201a929eb90e7e76af89841e43c727d98186bfa Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Thu, 16 Dec 2021 09:04:32 -0600 Subject: [PATCH 090/172] [Filebeat] Enable dynamic inputs (TCP) for Cisco syslog modules (#26159) - Add tcp option to asa, ftd & ios filesets - Add SSL option Closes #28821 Co-authored-by: Lee E. Hinman --- CHANGELOG.next.asciidoc | 1 + x-pack/filebeat/filebeat.reference.yml | 37 ++++++++++++++----- x-pack/filebeat/module/cisco/_meta/config.yml | 37 ++++++++++++++----- .../module/cisco/asa/config/input.yml | 14 +++---- x-pack/filebeat/module/cisco/asa/manifest.yml | 3 +- .../module/cisco/ftd/config/input.yml | 13 ++++--- x-pack/filebeat/module/cisco/ftd/manifest.yml | 3 +- .../module/cisco/ios/config/input.yml | 14 +++---- x-pack/filebeat/module/cisco/ios/manifest.yml | 2 + x-pack/filebeat/modules.d/cisco.yml.disabled | 37 ++++++++++++++----- 10 files changed, 109 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 15434665d0bf..cef220be926f 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -267,6 +267,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support for parsers on journald input {pull}29070[29070] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] +- Update Cisco module to enable TCP input. {issue}26118[26118] {issue}28821[28821] {pull}26159[26159] *Heartbeat* diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 1abc29932d80..796d69340463 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -685,16 +685,23 @@ filebeat.modules: asa: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to udp or tcp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9001. + # The port to listen for udp or tcp syslog traffic. Defaults to 9001. #var.syslog_port: 9001 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/asa/syslog/b_syslog/syslogs-sev-level.html @@ -711,16 +718,23 @@ filebeat.modules: ftd: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to tcp or udp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9003. + # The UDP port to listen for tcp or udp syslog traffic. Defaults to 9003. #var.syslog_port: 9003 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/firepower/Syslogs/b_fptd_syslog_guide/syslogs-sev-level.html @@ -740,13 +754,16 @@ filebeat.modules: # Set which input to use between syslog (default) or file. #var.input: syslog - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9002. + # The port to listen on for syslog traffic. Defaults to 9002. #var.syslog_port: 9002 + # Set which protocol to use between udp (default) or tcp. + #var.syslog_protocol: udp + # Set custom paths for the log files when using file input. If left empty, # Filebeat will choose the paths depending on your OS. #var.paths: diff --git a/x-pack/filebeat/module/cisco/_meta/config.yml b/x-pack/filebeat/module/cisco/_meta/config.yml index 3fd735c050db..1b2940129bf5 100644 --- a/x-pack/filebeat/module/cisco/_meta/config.yml +++ b/x-pack/filebeat/module/cisco/_meta/config.yml @@ -2,16 +2,23 @@ asa: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to udp or tcp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9001. + # The port to listen for udp or tcp syslog traffic. Defaults to 9001. #var.syslog_port: 9001 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/asa/syslog/b_syslog/syslogs-sev-level.html @@ -28,16 +35,23 @@ ftd: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to tcp or udp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9003. + # The UDP port to listen for tcp or udp syslog traffic. Defaults to 9003. #var.syslog_port: 9003 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/firepower/Syslogs/b_fptd_syslog_guide/syslogs-sev-level.html @@ -57,13 +71,16 @@ # Set which input to use between syslog (default) or file. #var.input: syslog - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9002. + # The port to listen on for syslog traffic. Defaults to 9002. #var.syslog_port: 9002 + # Set which protocol to use between udp (default) or tcp. + #var.syslog_protocol: udp + # Set custom paths for the log files when using file input. If left empty, # Filebeat will choose the paths depending on your OS. #var.paths: diff --git a/x-pack/filebeat/module/cisco/asa/config/input.yml b/x-pack/filebeat/module/cisco/asa/config/input.yml index 4237b4d9ae21..cb9df5bd6ec4 100644 --- a/x-pack/filebeat/module/cisco/asa/config/input.yml +++ b/x-pack/filebeat/module/cisco/asa/config/input.yml @@ -1,10 +1,4 @@ -{{ if eq .input "syslog" }} - -type: udp -udp: -host: "{{.syslog_host}}:{{.syslog_port}}" - -{{ else if eq .input "file" }} +{{ if eq .input "file" }} type: log paths: @@ -13,6 +7,12 @@ paths: {{ end }} exclude_files: [".gz$"] +{{ else }} + +type: {{.input}} +host: "{{.syslog_host}}:{{.syslog_port}}" +ssl: {{ .ssl | tojson }} + {{ end }} tags: {{.tags | tojson}} diff --git a/x-pack/filebeat/module/cisco/asa/manifest.yml b/x-pack/filebeat/module/cisco/asa/manifest.yml index 3c185f7980c2..184df5404adb 100644 --- a/x-pack/filebeat/module/cisco/asa/manifest.yml +++ b/x-pack/filebeat/module/cisco/asa/manifest.yml @@ -11,7 +11,8 @@ var: - name: syslog_port default: 9001 - name: input - default: syslog + default: udp + - name: ssl - name: log_level default: 7 # if ES < 6.1.0, this flag switches to false automatically when evaluating the diff --git a/x-pack/filebeat/module/cisco/ftd/config/input.yml b/x-pack/filebeat/module/cisco/ftd/config/input.yml index b29aa4c725f7..cb9df5bd6ec4 100644 --- a/x-pack/filebeat/module/cisco/ftd/config/input.yml +++ b/x-pack/filebeat/module/cisco/ftd/config/input.yml @@ -1,9 +1,4 @@ -{{ if eq .input "syslog" }} - -type: udp -host: "{{.syslog_host}}:{{.syslog_port}}" - -{{ else if eq .input "file" }} +{{ if eq .input "file" }} type: log paths: @@ -12,6 +7,12 @@ paths: {{ end }} exclude_files: [".gz$"] +{{ else }} + +type: {{.input}} +host: "{{.syslog_host}}:{{.syslog_port}}" +ssl: {{ .ssl | tojson }} + {{ end }} tags: {{.tags | tojson}} diff --git a/x-pack/filebeat/module/cisco/ftd/manifest.yml b/x-pack/filebeat/module/cisco/ftd/manifest.yml index 31eb9659a6b8..d681ff4d323f 100644 --- a/x-pack/filebeat/module/cisco/ftd/manifest.yml +++ b/x-pack/filebeat/module/cisco/ftd/manifest.yml @@ -11,7 +11,8 @@ var: - name: syslog_port default: 9003 - name: input - default: syslog + default: udp + - name: ssl - name: log_level default: 7 # if ES < 6.1.0, this flag switches to false automatically when evaluating the diff --git a/x-pack/filebeat/module/cisco/ios/config/input.yml b/x-pack/filebeat/module/cisco/ios/config/input.yml index d911aa3ed9e2..979f9cf380b6 100644 --- a/x-pack/filebeat/module/cisco/ios/config/input.yml +++ b/x-pack/filebeat/module/cisco/ios/config/input.yml @@ -1,10 +1,4 @@ -{{ if eq .input "syslog" }} - -type: syslog -protocol.udp: - host: "{{.syslog_host}}:{{.syslog_port}}" - -{{ else if eq .input "file" }} +{{ if eq .input "file" }} type: log paths: @@ -13,6 +7,12 @@ paths: {{ end }} exclude_files: [".gz$"] +{{ else if eq .input "syslog" }} + +type: syslog +protocol.{{.syslog_protocol}}: + host: "{{.syslog_host}}:{{.syslog_port}}" + {{ end }} tags: {{.tags | tojson}} diff --git a/x-pack/filebeat/module/cisco/ios/manifest.yml b/x-pack/filebeat/module/cisco/ios/manifest.yml index e67f5c2f729b..169e909fd89a 100644 --- a/x-pack/filebeat/module/cisco/ios/manifest.yml +++ b/x-pack/filebeat/module/cisco/ios/manifest.yml @@ -10,6 +10,8 @@ var: default: localhost - name: syslog_port default: 9002 + - name: syslog_protocol + default: udp - name: input default: syslog diff --git a/x-pack/filebeat/modules.d/cisco.yml.disabled b/x-pack/filebeat/modules.d/cisco.yml.disabled index 3ad2d76a875f..2d267c68a69e 100644 --- a/x-pack/filebeat/modules.d/cisco.yml.disabled +++ b/x-pack/filebeat/modules.d/cisco.yml.disabled @@ -5,16 +5,23 @@ asa: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to udp or tcp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9001. + # The port to listen for udp or tcp syslog traffic. Defaults to 9001. #var.syslog_port: 9001 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/asa/syslog/b_syslog/syslogs-sev-level.html @@ -31,16 +38,23 @@ ftd: enabled: false - # Set which input to use between syslog (default) or file. - #var.input: syslog + # Set which input to use between udp (default), tcp or file. + #var.input: udp - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to tcp or udp syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9003. + # The UDP port to listen for tcp or udp syslog traffic. Defaults to 9003. #var.syslog_port: 9003 + # With tcp input, set the optional tls configuration: + #var.ssl: + # enabled: true + # certificate: /path/to/cert.pem + # key: /path/to/privatekey.pem + # key_passphrase: 'password for my key' + # Set the log level from 1 (alerts only) to 7 (include all messages). # Messages with a log level higher than the specified will be dropped. # See https://www.cisco.com/c/en/us/td/docs/security/firepower/Syslogs/b_fptd_syslog_guide/syslogs-sev-level.html @@ -60,13 +74,16 @@ # Set which input to use between syslog (default) or file. #var.input: syslog - # The interface to listen to UDP based syslog traffic. Defaults to + # The interface to listen to syslog traffic. Defaults to # localhost. Set to 0.0.0.0 to bind to all available interfaces. #var.syslog_host: localhost - # The UDP port to listen for syslog traffic. Defaults to 9002. + # The port to listen on for syslog traffic. Defaults to 9002. #var.syslog_port: 9002 + # Set which protocol to use between udp (default) or tcp. + #var.syslog_protocol: udp + # Set custom paths for the log files when using file input. If left empty, # Filebeat will choose the paths depending on your OS. #var.paths: From b5e94143d774f2434432a578f7ef5bbd71002bca Mon Sep 17 00:00:00 2001 From: Taylor Swanson <90622908+taylor-swanson@users.noreply.github.com> Date: Thu, 16 Dec 2021 09:13:07 -0600 Subject: [PATCH 091/172] [Winlogbeat] Add support for custom XML queries (#29330) - Added new configuration field (xml_query) to support custom XML queries - This new configuration item will conflict with existing simple query configuration items (ignore_older, event_id, level, provider) - Validator has been updated to check for key conflicts and XML syntax, but does not check for correctness of XML schema. - Added unit tests for config validation - Added unit/system test for XML query runner --- CHANGELOG.next.asciidoc | 1 + winlogbeat/_meta/config/header.yml.tmpl | 8 +- winlogbeat/docs/winlogbeat-options.asciidoc | 58 ++++++- winlogbeat/eventlog/factory.go | 6 +- winlogbeat/eventlog/wineventlog.go | 74 ++++++--- .../eventlog/wineventlog_experimental.go | 60 ++++--- winlogbeat/eventlog/wineventlog_test.go | 147 +++++++++++++++++- winlogbeat/winlogbeat.reference.yml | 8 +- winlogbeat/winlogbeat.yml | 8 +- x-pack/winlogbeat/winlogbeat.reference.yml | 8 +- x-pack/winlogbeat/winlogbeat.yml | 8 +- 11 files changed, 323 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index cef220be926f..bcc93aa56368 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -296,6 +296,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add more DNS error codes to the Sysmon module. {issue}15685[15685] - Add configuration option for registry file flush timeout {issue}29001[29001] {pull}29053[29053] +- Add support for custom XML queries {issue}1054[1054] {pull}29330[29330] *Elastic Log Driver* diff --git a/winlogbeat/_meta/config/header.yml.tmpl b/winlogbeat/_meta/config/header.yml.tmpl index ec53124d5f3e..7d966b365242 100644 --- a/winlogbeat/_meta/config/header.yml.tmpl +++ b/winlogbeat/_meta/config/header.yml.tmpl @@ -26,7 +26,9 @@ # accompanying options. The YAML data type of event_logs is a list of # dictionaries. # -# The supported keys are name (required), tags, fields, fields_under_root, -# forwarded, ignore_older, level, event_id, provider, and include_xml. Please -# visit the documentation for the complete details of each option. +# The supported keys are name, id, xml_query, tags, fields, fields_under_root, +# forwarded, ignore_older, level, event_id, provider, and include_xml. +# The xml_query key requires an id and must not be used with the name, +# ignore_older, level, event_id, or provider keys. Please visit the +# documentation for the complete details of each option. # https://go.es.io/WinlogbeatConfig diff --git a/winlogbeat/docs/winlogbeat-options.asciidoc b/winlogbeat/docs/winlogbeat-options.asciidoc index dd2353eb7291..23e63803089b 100644 --- a/winlogbeat/docs/winlogbeat-options.asciidoc +++ b/winlogbeat/docs/winlogbeat-options.asciidoc @@ -87,7 +87,6 @@ winlogbeat.shutdown_timeout: 30s A list of entries (called 'dictionaries' in YAML) that specify which event logs to monitor. Each entry in the list defines an event log to monitor as well as any information to be associated with the event log (filter, tags, and so on). -The `name` field is the only required field for each event log. [source,yaml] -------------------------------------------------------------------------------- @@ -113,9 +112,9 @@ reading additional event log records. ==== `event_logs.name` The name of the event log to monitor. Each dictionary under `event_logs` must -have a `name` field. You can get a list of available event logs by running -`Get-EventLog *` in PowerShell. Here is a sample of the output from the -command: +have a `name` field, except for those which use a custom XML query. You can +get a list of available event logs by running `Get-EventLog *` in PowerShell. +Here is a sample of the output from the command: [source,sh] -------------------------------------------------------------------------------- @@ -173,6 +172,28 @@ winlogbeat.event_logs: - name: 'C:\backup\sysmon-2019.08.evtx' -------------------------------------------------------------------------------- +The name key must not be used with custom XML queries. + +[float] +==== `event_logs.id` + +A unique identifier for the event log. This key is required when using a custom +XML query. + +It is used to uniquely identify the event log reader in the registry file. This is +useful if multiple event logs are being set up to watch the same channel or file. If an +ID is not given, the `event_logs.name` value will be used. + +This value must be unique. + +[source,yaml] +-------------------------------------------------------------------------------- +winlogbeat.event_logs: + - name: Application + id: application-logs + ignore_older: 168h +-------------------------------------------------------------------------------- + [float] ==== `event_logs.ignore_older` @@ -335,6 +356,35 @@ Microsoft-Windows-Security-Auditing Microsoft-Windows-Eventlog -------------------------------------------------------------------------------- +[float] +==== `event_logs.xml_query` + +Provide a custom XML query. This option is mutually exclusive with the `name`, `event_id`, +`ignore_older`, `level`, and `provider` options. These options should be included in +the XML query directly. Furthermore, an `id` must be provided. Custom XML queries +provide more flexibility and advanced options than the simpler query options in {beatname_uc}. +*{vista_and_newer}* + +Here is a configuration which will collect DHCP server events from multiple channels: + +[source,yaml] +-------------------------------------------------------------------------------- +winlogbeat.event_logs: + - id: dhcp-server-logs + xml_query: > + + + + + + + +-------------------------------------------------------------------------------- + +XML queries may also be created in Windows Event Viewer using custom views. The query +can be created using a graphical interface and the corresponding XML can be +retrieved from the XML tab. + [float] ==== `event_logs.include_xml` diff --git a/winlogbeat/eventlog/factory.go b/winlogbeat/eventlog/factory.go index 9ee8e0d144f2..bb07c07ba1e0 100644 --- a/winlogbeat/eventlog/factory.go +++ b/winlogbeat/eventlog/factory.go @@ -29,8 +29,10 @@ import ( // EventLog. Each implementation is free to support additional configuration // options. type ConfigCommon struct { - API string `config:"api"` // Name of the API to use. Optional. - Name string `config:"name"` // Name of the event log or channel or file. + API string `config:"api"` // Name of the API to use. Optional. + Name string `config:"name"` // Name of the event log or channel or file. + ID string `config:"id"` // Identifier for the event log. + XMLQuery string `config:"xml_query"` // Custom query XML. Must not be used with the keys from eventlog.query. } type validator interface { diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go index 9e52cf2bdaac..7ec830f220a5 100644 --- a/winlogbeat/eventlog/wineventlog.go +++ b/winlogbeat/eventlog/wineventlog.go @@ -21,6 +21,7 @@ package eventlog import ( + "encoding/xml" "fmt" "io" "path/filepath" @@ -113,7 +114,30 @@ type query struct { // any problems or nil. func (c *winEventLogConfig) Validate() error { var errs multierror.Errors - if c.Name == "" { + + if c.XMLQuery != "" { + if c.ID == "" { + errs = append(errs, fmt.Errorf("event log is missing an 'id'")) + } + + // Check for XML syntax errors. This does not check the validity of the query itself. + if err := xml.Unmarshal([]byte(c.XMLQuery), &struct{}{}); err != nil { + errs = append(errs, fmt.Errorf("invalid xml_query: %w", err)) + } + + switch { + case c.Name != "": + errs = append(errs, fmt.Errorf("xml_query cannot be used with 'name'")) + case c.SimpleQuery.IgnoreOlder != 0: + errs = append(errs, fmt.Errorf("xml_query cannot be used with 'ignore_older'")) + case c.SimpleQuery.Level != "": + errs = append(errs, fmt.Errorf("xml_query cannot be used with 'level'")) + case c.SimpleQuery.EventID != "": + errs = append(errs, fmt.Errorf("xml_query cannot be used with 'event_id'")) + case len(c.SimpleQuery.Provider) != 0: + errs = append(errs, fmt.Errorf("xml_query cannot be used with 'provider'")) + } + } else if c.Name == "" { errs = append(errs, fmt.Errorf("event log is missing a 'name'")) } @@ -128,6 +152,7 @@ var _ EventLog = &winEventLog{} type winEventLog struct { config winEventLogConfig query string + id string // Identifier of this event log. channelName string // Name of the channel from which to read. file bool // Reading from file rather than channel. subscription win.EvtHandle // Handle to the subscription. @@ -144,7 +169,7 @@ type winEventLog struct { // Name returns the name of the event log (i.e. Application, Security, etc.). func (l *winEventLog) Name() string { - return l.channelName + return l.id } func (l *winEventLog) Open(state checkpoint.EventLogState) error { @@ -152,7 +177,7 @@ func (l *winEventLog) Open(state checkpoint.EventLogState) error { var err error if len(state.Bookmark) > 0 { bookmark, err = win.CreateBookmarkFromXML(state.Bookmark) - } else if state.RecordNumber > 0 { + } else if state.RecordNumber > 0 && l.channelName != "" { bookmark, err = win.CreateBookmarkFromRecordID(l.channelName, state.RecordNumber) } if err != nil { @@ -267,7 +292,7 @@ func (l *winEventLog) Read() ([]Record, error) { r, _ := l.buildRecordFromXML(l.outputBuf.Bytes(), err) r.Offset = checkpoint.EventLogState{ - Name: l.channelName, + Name: l.id, RecordNumber: r.RecordID, Timestamp: r.TimeCreated.SystemTime, } @@ -356,7 +381,7 @@ func (l *winEventLog) buildRecordFromXML(x []byte, recoveredErr error) (Record, } if l.file { - r.File = l.channelName + r.File = l.id } if includeXML { @@ -374,20 +399,32 @@ func newEventLogging(options *common.Config) (EventLog, error) { // newWinEventLog creates and returns a new EventLog for reading event logs // using the Windows Event Log. func newWinEventLog(options *common.Config) (EventLog, error) { + var xmlQuery string + var err error + c := defaultWinEventLogConfig - if err := readConfig(options, &c); err != nil { + if err = readConfig(options, &c); err != nil { return nil, err } - query, err := win.Query{ - Log: c.Name, - IgnoreOlder: c.SimpleQuery.IgnoreOlder, - Level: c.SimpleQuery.Level, - EventID: c.SimpleQuery.EventID, - Provider: c.SimpleQuery.Provider, - }.Build() - if err != nil { - return nil, err + id := c.ID + if id == "" { + id = c.Name + } + + if c.XMLQuery != "" { + xmlQuery = c.XMLQuery + } else { + xmlQuery, err = win.Query{ + Log: c.Name, + IgnoreOlder: c.SimpleQuery.IgnoreOlder, + Level: c.SimpleQuery.Level, + EventID: c.SimpleQuery.EventID, + Provider: c.SimpleQuery.Provider, + }.Build() + if err != nil { + return nil, err + } } eventMetadataHandle := func(providerName, sourceName string) sys.MessageFiles { @@ -411,15 +448,16 @@ func newWinEventLog(options *common.Config) (EventLog, error) { } l := &winEventLog{ + id: id, config: c, - query: query, + query: xmlQuery, channelName: c.Name, file: filepath.IsAbs(c.Name), maxRead: c.BatchReadSize, renderBuf: make([]byte, renderBufferSize), outputBuf: sys.NewByteBuffer(renderBufferSize), - cache: newMessageFilesCache(c.Name, eventMetadataHandle, freeHandle), - logPrefix: fmt.Sprintf("WinEventLog[%s]", c.Name), + cache: newMessageFilesCache(id, eventMetadataHandle, freeHandle), + logPrefix: fmt.Sprintf("WinEventLog[%s]", id), } // Forwarded events should be rendered using RenderEventXML. It is more diff --git a/winlogbeat/eventlog/wineventlog_experimental.go b/winlogbeat/eventlog/wineventlog_experimental.go index 3a3ae1826867..87eb4b328026 100644 --- a/winlogbeat/eventlog/wineventlog_experimental.go +++ b/winlogbeat/eventlog/wineventlog_experimental.go @@ -47,6 +47,7 @@ const ( type winEventLogExp struct { config winEventLogConfig query string + id string // Identifier of this event log. channelName string // Name of the channel from which to read. file bool // Reading from file rather than channel. maxRead int // Maximum number returned in one Read. @@ -59,7 +60,7 @@ type winEventLogExp struct { // Name returns the name of the event log (i.e. Application, Security, etc.). func (l *winEventLogExp) Name() string { - return l.channelName + return l.id } func (l *winEventLogExp) Open(state checkpoint.EventLogState) error { @@ -205,11 +206,11 @@ func (l *winEventLogExp) processHandle(h win.EvtHandle) (*Record, error) { } if l.file { - r.File = l.channelName + r.File = l.id } r.Offset = checkpoint.EventLogState{ - Name: l.channelName, + Name: l.id, RecordNumber: r.RecordID, Timestamp: r.TimeCreated.SystemTime, } @@ -241,6 +242,11 @@ func (l *winEventLogExp) Close() error { // newWinEventLogExp creates and returns a new EventLog for reading event logs // using the Windows Event Log. func newWinEventLogExp(options *common.Config) (EventLog, error) { + var xmlQuery string + var err error + var isFile bool + var log *logp.Logger + cfgwarn.Experimental("The %s event log reader is experimental.", winEventLogExpAPIName) c := winEventLogConfig{BatchReadSize: 512} @@ -248,30 +254,39 @@ func newWinEventLogExp(options *common.Config) (EventLog, error) { return nil, err } - queryLog := c.Name - isFile := false - if info, err := os.Stat(c.Name); err == nil && info.Mode().IsRegular() { - path, err := filepath.Abs(c.Name) + id := c.ID + if id == "" { + id = c.Name + } + + if c.XMLQuery != "" { + xmlQuery = c.XMLQuery + log = logp.NewLogger("wineventlog").With("id", id) + } else { + queryLog := c.Name + if info, err := os.Stat(c.Name); err == nil && info.Mode().IsRegular() { + path, err := filepath.Abs(c.Name) + if err != nil { + return nil, err + } + isFile = true + queryLog = "file://" + path + } + + xmlQuery, err = win.Query{ + Log: queryLog, + IgnoreOlder: c.SimpleQuery.IgnoreOlder, + Level: c.SimpleQuery.Level, + EventID: c.SimpleQuery.EventID, + Provider: c.SimpleQuery.Provider, + }.Build() if err != nil { return nil, err } - isFile = true - queryLog = "file://" + path - } - query, err := win.Query{ - Log: queryLog, - IgnoreOlder: c.SimpleQuery.IgnoreOlder, - Level: c.SimpleQuery.Level, - EventID: c.SimpleQuery.EventID, - Provider: c.SimpleQuery.Provider, - }.Build() - if err != nil { - return nil, err + log = logp.NewLogger("wineventlog").With("id", id).With("channel", c.Name) } - log := logp.NewLogger("wineventlog").With("channel", c.Name) - renderer, err := win.NewRenderer(win.NilHandle, log) if err != nil { return nil, err @@ -279,7 +294,8 @@ func newWinEventLogExp(options *common.Config) (EventLog, error) { l := &winEventLogExp{ config: c, - query: query, + query: xmlQuery, + id: id, channelName: c.Name, file: isFile, maxRead: c.BatchReadSize, diff --git a/winlogbeat/eventlog/wineventlog_test.go b/winlogbeat/eventlog/wineventlog_test.go index d6ddddcdd8ba..c5d92ce18739 100644 --- a/winlogbeat/eventlog/wineventlog_test.go +++ b/winlogbeat/eventlog/wineventlog_test.go @@ -39,8 +39,13 @@ import ( const ( // Names that are registered by the test for logging events. - providerName = "WinlogbeatTestGo" - sourceName = "Integration Test" + providerName = "WinlogbeatTestGo" + sourceName = "Integration Test" + customXMLQuery = ` + + + +` // Event message files used when logging events. @@ -54,6 +59,116 @@ const ( netEventMsgFile = "%SystemRoot%\\System32\\netevent.dll" ) +func TestWinEventLogConfig_Validate(t *testing.T) { + tests := []struct { + In winEventLogConfig + WantErr bool + Desc string + }{ + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery, + }, + }, + WantErr: false, + Desc: "xml query: all good", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery[:len(customXMLQuery)-4], // Malformed XML by truncation. + }, + }, + WantErr: true, + Desc: "xml query: malformed XML", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + XMLQuery: customXMLQuery, + }, + }, + WantErr: true, + Desc: "xml query: missing ID", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + Name: "test", + XMLQuery: customXMLQuery, + }, + }, + WantErr: true, + Desc: "xml query: conflicting keys (xml query and name)", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery, + }, + SimpleQuery: query{IgnoreOlder: 1}, + }, + WantErr: true, + Desc: "xml query: conflicting keys (xml query and ignore_older)", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery, + }, + SimpleQuery: query{Level: "error"}, + }, + WantErr: true, + Desc: "xml query: conflicting keys (xml query and level)", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery, + }, + SimpleQuery: query{EventID: "1000"}, + }, + WantErr: true, + Desc: "xml query: conflicting keys (xml query and event_id)", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{ + ID: "test", + XMLQuery: customXMLQuery, + }, + SimpleQuery: query{Provider: []string{providerName}}, + }, + WantErr: true, + Desc: "xml query: conflicting keys (xml query and provider)", + }, + { + In: winEventLogConfig{ + ConfigCommon: ConfigCommon{}, + }, + WantErr: true, + Desc: "missing name", + }, + } + + for _, tc := range tests { + gotErr := tc.In.Validate() + + if tc.WantErr { + assert.NotNil(t, gotErr, tc.Desc) + } else { + assert.Nil(t, gotErr, "%q got unexpected err: %v", tc.Desc, gotErr) + } + } +} + func TestWindowsEventLogAPI(t *testing.T) { testWindowsEventLog(t, winEventLogAPIName) } @@ -79,6 +194,34 @@ func testWindowsEventLog(t *testing.T, api string) { return openLog(t, api, nil, config) } + // Test reading from an event log using a custom XML query. + t.Run("custom_xml_query", func(t *testing.T) { + cfg := map[string]interface{}{ + "id": "custom-xml-query", + "xml_query": customXMLQuery, + } + + log := openLog(t, cfg) + defer log.Close() + + var eventCount int + + for eventCount < totalEvents { + records, err := log.Read() + if err != nil { + t.Fatal("read error", err) + } + if len(records) == 0 { + t.Fatal("read returned 0 records") + } + + t.Logf("Read() returned %d events.", len(records)) + eventCount += len(records) + } + + assert.Equal(t, totalEvents, eventCount) + }) + t.Run("batch_read_size_config", func(t *testing.T) { const batchReadSize = 2 diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index afa6ec97eb39..11a5ac82351c 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -24,9 +24,11 @@ # accompanying options. The YAML data type of event_logs is a list of # dictionaries. # -# The supported keys are name (required), tags, fields, fields_under_root, -# forwarded, ignore_older, level, event_id, provider, and include_xml. Please -# visit the documentation for the complete details of each option. +# The supported keys are name, id, xml_query, tags, fields, fields_under_root, +# forwarded, ignore_older, level, event_id, provider, and include_xml. +# The xml_query key requires an id and must not be used with the name, +# ignore_older, level, event_id, or provider keys. Please visit the +# documentation for the complete details of each option. # https://go.es.io/WinlogbeatConfig winlogbeat.event_logs: diff --git a/winlogbeat/winlogbeat.yml b/winlogbeat/winlogbeat.yml index 614b28172258..bdb1f706fa66 100644 --- a/winlogbeat/winlogbeat.yml +++ b/winlogbeat/winlogbeat.yml @@ -13,9 +13,11 @@ # accompanying options. The YAML data type of event_logs is a list of # dictionaries. # -# The supported keys are name (required), tags, fields, fields_under_root, -# forwarded, ignore_older, level, event_id, provider, and include_xml. Please -# visit the documentation for the complete details of each option. +# The supported keys are name, id, xml_query, tags, fields, fields_under_root, +# forwarded, ignore_older, level, event_id, provider, and include_xml. +# The xml_query key requires an id and must not be used with the name, +# ignore_older, level, event_id, or provider keys. Please visit the +# documentation for the complete details of each option. # https://go.es.io/WinlogbeatConfig winlogbeat.event_logs: diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 8d9d4ef25669..940cd6125a02 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -24,9 +24,11 @@ # accompanying options. The YAML data type of event_logs is a list of # dictionaries. # -# The supported keys are name (required), tags, fields, fields_under_root, -# forwarded, ignore_older, level, event_id, provider, and include_xml. Please -# visit the documentation for the complete details of each option. +# The supported keys are name, id, xml_query, tags, fields, fields_under_root, +# forwarded, ignore_older, level, event_id, provider, and include_xml. +# The xml_query key requires an id and must not be used with the name, +# ignore_older, level, event_id, or provider keys. Please visit the +# documentation for the complete details of each option. # https://go.es.io/WinlogbeatConfig winlogbeat.event_logs: diff --git a/x-pack/winlogbeat/winlogbeat.yml b/x-pack/winlogbeat/winlogbeat.yml index c0c01d2ceeab..15c1e10fdcc3 100644 --- a/x-pack/winlogbeat/winlogbeat.yml +++ b/x-pack/winlogbeat/winlogbeat.yml @@ -13,9 +13,11 @@ # accompanying options. The YAML data type of event_logs is a list of # dictionaries. # -# The supported keys are name (required), tags, fields, fields_under_root, -# forwarded, ignore_older, level, event_id, provider, and include_xml. Please -# visit the documentation for the complete details of each option. +# The supported keys are name, id, xml_query, tags, fields, fields_under_root, +# forwarded, ignore_older, level, event_id, provider, and include_xml. +# The xml_query key requires an id and must not be used with the name, +# ignore_older, level, event_id, or provider keys. Please visit the +# documentation for the complete details of each option. # https://go.es.io/WinlogbeatConfig winlogbeat.event_logs: From d4016812b8ae0be884fef6d56e404db6f5438a9f Mon Sep 17 00:00:00 2001 From: Denis Rechkunov Date: Thu, 16 Dec 2021 21:03:03 +0100 Subject: [PATCH 092/172] Drop event batch when get HTTP status 413 from ES (#29368) To prevent infinite loops when having `http.max_content_length` set too low or `bulk_max_size` too high we now handle this status code separately and drop the whole event batch producing a detailed error message on the console. --- CHANGELOG-developer.next.asciidoc | 1 + libbeat/outputs/elasticsearch/client.go | 14 ++- libbeat/outputs/elasticsearch/client_test.go | 97 ++++++++++++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-developer.next.asciidoc b/CHANGELOG-developer.next.asciidoc index e640b5a0334d..dcb2a5665f49 100644 --- a/CHANGELOG-developer.next.asciidoc +++ b/CHANGELOG-developer.next.asciidoc @@ -68,6 +68,7 @@ The list below covers the major changes between 7.0.0-rc2 and master only. - Remove `event.dataset` (ECS) annotion from `libbeat.logp`. {issue}27404[27404] - Errors should be thrown as errors. Metricsets inside Metricbeat will now throw errors as the `error` log level. {pull}27804[27804] - Avoid panicking in `add_fields` processor when input event.Fields is a nil map. {pull}28219[28219] +- Drop event batch when get HTTP status 413 from Elasticsearch to avoid infinite loop {issue}14350[14350] {pull}29368[29368] ==== Added diff --git a/libbeat/outputs/elasticsearch/client.go b/libbeat/outputs/elasticsearch/client.go index deab29c3dcd8..0d9d619b9f50 100644 --- a/libbeat/outputs/elasticsearch/client.go +++ b/libbeat/outputs/elasticsearch/client.go @@ -38,6 +38,8 @@ import ( "github.com/elastic/beats/v7/libbeat/testing" ) +var errPayloadTooLarge = errors.New("the bulk payload is too large for the server. Consider to adjust `http.max_content_length` parameter in Elasticsearch or `bulk_max_size` in the beat. The batch has been dropped") + // Client is an elasticsearch client. type Client struct { conn eslegclient.Connection @@ -180,9 +182,13 @@ func (client *Client) Clone() *Client { func (client *Client) Publish(ctx context.Context, batch publisher.Batch) error { events := batch.Events() rest, err := client.publishEvents(ctx, events) - if len(rest) == 0 { + + switch { + case err == errPayloadTooLarge: + batch.Drop() + case len(rest) == 0: batch.ACK() - } else { + default: batch.RetryEvents(rest) } return err @@ -220,7 +226,11 @@ func (client *Client) publishEvents(ctx context.Context, data []publisher.Event) } status, result, sendErr := client.conn.Bulk(ctx, "", "", nil, bulkItems) + if sendErr != nil { + if status == http.StatusRequestEntityTooLarge { + sendErr = errPayloadTooLarge + } err := apm.CaptureError(ctx, fmt.Errorf("failed to perform any bulk index operations: %w", sendErr)) err.Send() client.log.Error(err) diff --git a/libbeat/outputs/elasticsearch/client_test.go b/libbeat/outputs/elasticsearch/client_test.go index 2a03d10481dd..0a2ca672a7c5 100644 --- a/libbeat/outputs/elasticsearch/client_test.go +++ b/libbeat/outputs/elasticsearch/client_test.go @@ -44,6 +44,103 @@ import ( "github.com/elastic/beats/v7/libbeat/version" ) +type testIndexSelector struct{} + +func (testIndexSelector) Select(event *beat.Event) (string, error) { + return "test", nil +} + +type batchMock struct { + // we embed the interface so we are able to implement the interface partially, + // only functions needed for tests are implemented + // if you use a function that is not implemented in the mock it will panic + publisher.Batch + events []publisher.Event + ack bool + drop bool + retryEvents []publisher.Event +} + +func (bm batchMock) Events() []publisher.Event { + return bm.events +} +func (bm *batchMock) ACK() { + bm.ack = true +} +func (bm *batchMock) Drop() { + bm.drop = true +} +func (bm *batchMock) RetryEvents(events []publisher.Event) { + bm.retryEvents = events +} + +func TestPublishStatusCode(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + event := publisher.Event{Content: beat.Event{Fields: common.MapStr{"field": 1}}} + events := []publisher.Event{event} + + t.Run("returns pre-defined error and drops batch when 413", func(t *testing.T) { + esMock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusRequestEntityTooLarge) + w.Write([]byte("Request failed to get to the server (status code: 413)")) // actual response from ES + })) + defer esMock.Close() + + client, err := NewClient( + ClientSettings{ + ConnectionSettings: eslegclient.ConnectionSettings{ + URL: esMock.URL, + }, + Index: testIndexSelector{}, + }, + nil, + ) + assert.NoError(t, err) + + event := publisher.Event{Content: beat.Event{Fields: common.MapStr{"field": 1}}} + events := []publisher.Event{event} + batch := &batchMock{ + events: events, + } + + err = client.Publish(ctx, batch) + + assert.Error(t, err) + assert.Equal(t, errPayloadTooLarge, err, "should be a pre-defined error") + assert.True(t, batch.drop, "should must be dropped") + }) + + t.Run("retries the batch if bad HTTP status", func(t *testing.T) { + esMock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + defer esMock.Close() + + client, err := NewClient( + ClientSettings{ + ConnectionSettings: eslegclient.ConnectionSettings{ + URL: esMock.URL, + }, + Index: testIndexSelector{}, + }, + nil, + ) + assert.NoError(t, err) + + batch := &batchMock{ + events: events, + } + + err = client.Publish(ctx, batch) + + assert.Error(t, err) + assert.False(t, batch.ack, "should not be acknowledged") + assert.Len(t, batch.retryEvents, len(events), "all events should be in retry") + }) +} + func TestCollectPublishFailsNone(t *testing.T) { client, err := NewClient( ClientSettings{ From 43ae3c9cbd5e02bf64aed8422501ac5f0ab0eac3 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 16 Dec 2021 22:06:44 +0200 Subject: [PATCH 093/172] Enhance filter check in k8s event metricset (#29470) --- CHANGELOG.next.asciidoc | 1 + libbeat/common/kubernetes/types.go | 5 +++++ metricbeat/module/kubernetes/event/event.go | 10 +++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index bcc93aa56368..4a69cc017580 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -187,6 +187,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Groups same timestamp metric values to one event in the app_insights metricset. {pull}20403[20403] - Use xpack.enabled on SM modules to write into .monitoring indices when using Metricbeat standalone {pull}28365[28365] - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] +- Enhance filter check in kubernetes event metricset. {pull}29470[29470] *Packetbeat* diff --git a/libbeat/common/kubernetes/types.go b/libbeat/common/kubernetes/types.go index 9f50e99b3058..c3d1fefb01ed 100644 --- a/libbeat/common/kubernetes/types.go +++ b/libbeat/common/kubernetes/types.go @@ -94,6 +94,11 @@ func Time(t *metav1.Time) time.Time { return t.Time } +// MicroTime extracts time from k8s.MicroTime type +func MicroTime(t *metav1.MicroTime) time.Time { + return t.Time +} + // ContainerID parses the container ID to get the actual ID string func ContainerID(s PodContainerStatus) string { cID, _ := ContainerIDWithRuntime(s) diff --git a/metricbeat/module/kubernetes/event/event.go b/metricbeat/module/kubernetes/event/event.go index 723e1331e618..9c844be950cc 100644 --- a/metricbeat/module/kubernetes/event/event.go +++ b/metricbeat/module/kubernetes/event/event.go @@ -108,8 +108,16 @@ func (m *MetricSet) Run(reporter mb.PushReporter) { m.watcher.AddEventHandler(kubernetes.FilteringResourceEventHandler{ FilterFunc: func(obj interface{}) bool { eve := obj.(*kubernetes.Event) + // if fields are null they are decoded to `0001-01-01 00:00:00 +0000 UTC` + // so we need to check if they are valid first + lastTimestampValid := !kubernetes.Time(&eve.LastTimestamp).IsZero() + eventTimeValid := !kubernetes.MicroTime(&eve.EventTime).IsZero() // if skipOlder, skip events happened before watch - if m.skipOlder && kubernetes.Time(&eve.LastTimestamp).Before(now) { + if m.skipOlder && kubernetes.Time(&eve.LastTimestamp).Before(now) && lastTimestampValid { + return false + } else if m.skipOlder && kubernetes.MicroTime(&eve.EventTime).Before(now) && eventTimeValid { + // there might be cases that `LastTimestamp` is not a valid number so double check + // with `EventTime` return false } return true From 8921ea4a4cbff116b24a2cae6b2a5e6d6e08d851 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Thu, 16 Dec 2021 21:21:14 +0000 Subject: [PATCH 094/172] ci: enable orka (#29426) --- Jenkinsfile | 2 +- auditbeat/Jenkinsfile.yml | 2 +- filebeat/Jenkinsfile.yml | 2 +- heartbeat/Jenkinsfile.yml | 2 +- metricbeat/Jenkinsfile.yml | 2 +- packetbeat/Jenkinsfile.yml | 2 +- x-pack/auditbeat/Jenkinsfile.yml | 2 +- x-pack/auditbeat/tests/system/test_metricsets.py | 1 + x-pack/elastic-agent/Jenkinsfile.yml | 2 +- x-pack/filebeat/Jenkinsfile.yml | 2 +- x-pack/functionbeat/Jenkinsfile.yml | 2 +- x-pack/heartbeat/Jenkinsfile.yml | 2 +- x-pack/metricbeat/Jenkinsfile.yml | 2 +- x-pack/osquerybeat/Jenkinsfile.yml | 2 +- x-pack/packetbeat/Jenkinsfile.yml | 2 +- 15 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9d5aca6a4ceb..19978442bf8d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -634,7 +634,7 @@ def withBeatsEnv(Map args = [:], Closure body) { if(isUnix()) { gox_flags = (isArm() && is64arm()) ? '-arch arm' : '-arch amd64' - path = "${env.WORKSPACE}/bin:${env.PATH}" + path = "${env.WORKSPACE}/bin:${env.PATH}:/usr/local/bin" magefile = "${WORKSPACE}/.magefile" pythonEnv = "${WORKSPACE}/python-env" testResults = '**/build/TEST*.xml' diff --git a/auditbeat/Jenkinsfile.yml b/auditbeat/Jenkinsfile.yml index ec64b4fc3d79..7b17f617776d 100644 --- a/auditbeat/Jenkinsfile.yml +++ b/auditbeat/Jenkinsfile.yml @@ -44,7 +44,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test auditbeat for macos" diff --git a/filebeat/Jenkinsfile.yml b/filebeat/Jenkinsfile.yml index 758f0d496a00..f5843c43b18f 100644 --- a/filebeat/Jenkinsfile.yml +++ b/filebeat/Jenkinsfile.yml @@ -55,7 +55,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test filebeat for macos" diff --git a/heartbeat/Jenkinsfile.yml b/heartbeat/Jenkinsfile.yml index c6603f1b9695..4eae0d100ef6 100644 --- a/heartbeat/Jenkinsfile.yml +++ b/heartbeat/Jenkinsfile.yml @@ -49,7 +49,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test heartbeat for macos" diff --git a/metricbeat/Jenkinsfile.yml b/metricbeat/Jenkinsfile.yml index 3a66f3e29a75..e7ce5009caf6 100644 --- a/metricbeat/Jenkinsfile.yml +++ b/metricbeat/Jenkinsfile.yml @@ -38,7 +38,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test metricbeat for macos" diff --git a/packetbeat/Jenkinsfile.yml b/packetbeat/Jenkinsfile.yml index 5d09046407a8..bc0f8a13bee0 100644 --- a/packetbeat/Jenkinsfile.yml +++ b/packetbeat/Jenkinsfile.yml @@ -42,7 +42,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test packetbeat for macos" diff --git a/x-pack/auditbeat/Jenkinsfile.yml b/x-pack/auditbeat/Jenkinsfile.yml index aef0ec1fbe5e..9dbb5f77dfae 100644 --- a/x-pack/auditbeat/Jenkinsfile.yml +++ b/x-pack/auditbeat/Jenkinsfile.yml @@ -42,7 +42,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/auditbeat for macos" diff --git a/x-pack/auditbeat/tests/system/test_metricsets.py b/x-pack/auditbeat/tests/system/test_metricsets.py index 2d34f8e4c182..6294d5a02d16 100644 --- a/x-pack/auditbeat/tests/system/test_metricsets.py +++ b/x-pack/auditbeat/tests/system/test_metricsets.py @@ -48,6 +48,7 @@ def test_metricset_login(self): @unittest.skipIf(sys.platform == "win32", "Not implemented for Windows") @unittest.skipIf(sys.platform.startswith('linux') and not (os.path.isdir("/var/lib/dpkg") or os.path.isdir("/var/lib/rpm")), "Only implemented for dpkg and rpm") + @unittest.skipIf(sys.platform.startswith('darwin'), "See https://github.com/elastic/beats/issues/21308") def test_metricset_package(self): """ package metricset collects information about installed packages on a system. diff --git a/x-pack/elastic-agent/Jenkinsfile.yml b/x-pack/elastic-agent/Jenkinsfile.yml index a80fdb1297c7..d2381654009c 100644 --- a/x-pack/elastic-agent/Jenkinsfile.yml +++ b/x-pack/elastic-agent/Jenkinsfile.yml @@ -42,7 +42,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/elastic-agent for macos" diff --git a/x-pack/filebeat/Jenkinsfile.yml b/x-pack/filebeat/Jenkinsfile.yml index 8ea1c14fa033..c5647d9a854f 100644 --- a/x-pack/filebeat/Jenkinsfile.yml +++ b/x-pack/filebeat/Jenkinsfile.yml @@ -55,7 +55,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/filebeat for macos" diff --git a/x-pack/functionbeat/Jenkinsfile.yml b/x-pack/functionbeat/Jenkinsfile.yml index 84e95e829ea4..f3b4bf109739 100644 --- a/x-pack/functionbeat/Jenkinsfile.yml +++ b/x-pack/functionbeat/Jenkinsfile.yml @@ -39,7 +39,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/functionbeat for macos" diff --git a/x-pack/heartbeat/Jenkinsfile.yml b/x-pack/heartbeat/Jenkinsfile.yml index ca184f785f47..96a48489c620 100644 --- a/x-pack/heartbeat/Jenkinsfile.yml +++ b/x-pack/heartbeat/Jenkinsfile.yml @@ -30,7 +30,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/heartbeat for macos" diff --git a/x-pack/metricbeat/Jenkinsfile.yml b/x-pack/metricbeat/Jenkinsfile.yml index 7a619ed6f160..db7fb380c50e 100644 --- a/x-pack/metricbeat/Jenkinsfile.yml +++ b/x-pack/metricbeat/Jenkinsfile.yml @@ -60,7 +60,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/metricbeat for macos" diff --git a/x-pack/osquerybeat/Jenkinsfile.yml b/x-pack/osquerybeat/Jenkinsfile.yml index fd55f11b63d7..6ebd028027b9 100644 --- a/x-pack/osquerybeat/Jenkinsfile.yml +++ b/x-pack/osquerybeat/Jenkinsfile.yml @@ -28,7 +28,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/osquerybeat for macos" diff --git a/x-pack/packetbeat/Jenkinsfile.yml b/x-pack/packetbeat/Jenkinsfile.yml index a2550062fb78..1771a576f07b 100644 --- a/x-pack/packetbeat/Jenkinsfile.yml +++ b/x-pack/packetbeat/Jenkinsfile.yml @@ -42,7 +42,7 @@ stages: macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. - - "macosx&&x86_64" + - "orka && darwin && poc" when: ## Override the top-level when. comments: - "/test x-pack/packetbeat for macos" From a0ef4d3af0388562674684e3fba3cb56008a5fbb Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Thu, 16 Dec 2021 17:21:09 -0500 Subject: [PATCH 095/172] Stop calling ChangeMessageVisibility after ReceiptHandleIsInvalid (#29480) Stop the keepalive goroutine after ErrCodeReceiptHandleIsInvalid is returned by ChangeMessageVisibility. Add `message_receipt_time` to log messages associated with processing of a given SQS message. Fix incorrect error being wrapped when ApproximateReceiveCount threshold is reached. --- CHANGELOG.next.asciidoc | 1 + x-pack/filebeat/input/awss3/sqs_s3_event.go | 18 +++++++++-- .../filebeat/input/awss3/sqs_s3_event_test.go | 32 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 4a69cc017580..248e16180937 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -149,6 +149,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix `threatintel.misp` filters configuration. {issue}27970[27970] - Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] - Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] +- aws-s3: Stop trying to increase SQS message visibility after ReceiptHandleIsInvalid errors. {pull}29480[29480] - Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] *Heartbeat* diff --git a/x-pack/filebeat/input/awss3/sqs_s3_event.go b/x-pack/filebeat/input/awss3/sqs_s3_event.go index b6641a36c81c..d1865aec9cd5 100644 --- a/x-pack/filebeat/input/awss3/sqs_s3_event.go +++ b/x-pack/filebeat/input/awss3/sqs_s3_event.go @@ -14,6 +14,7 @@ import ( "sync" "time" + "github.com/aws/aws-sdk-go-v2/aws/awserr" "github.com/aws/aws-sdk-go-v2/service/sqs" "github.com/pkg/errors" "go.uber.org/multierr" @@ -105,7 +106,9 @@ func newSQSS3EventProcessor(log *logp.Logger, metrics *inputMetrics, sqs sqsAPI, } func (p *sqsS3EventProcessor) ProcessSQS(ctx context.Context, msg *sqs.Message) error { - log := p.log.With("message_id", *msg.MessageId) + log := p.log.With( + "message_id", *msg.MessageId, + "message_receipt_time", time.Now().UTC()) keepaliveCtx, keepaliveCancel := context.WithCancel(ctx) defer keepaliveCancel() @@ -137,7 +140,7 @@ func (p *sqsS3EventProcessor) ProcessSQS(ctx context.Context, msg *sqs.Message) if receiveCount, err := strconv.Atoi(v); err == nil && receiveCount >= p.maxReceiveCount { processingErr = nonRetryableErrorWrap(fmt.Errorf( "sqs ApproximateReceiveCount <%v> exceeds threshold %v: %w", - receiveCount, p.maxReceiveCount, err)) + receiveCount, p.maxReceiveCount, processingErr)) } } } @@ -180,6 +183,17 @@ func (p *sqsS3EventProcessor) keepalive(ctx context.Context, log *logp.Logger, w // Renew visibility. if err := p.sqs.ChangeMessageVisibility(ctx, msg, p.sqsVisibilityTimeout); err != nil { + var awsErr awserr.Error + if errors.As(err, &awsErr) { + switch awsErr.Code() { + case sqs.ErrCodeReceiptHandleIsInvalid: + log.Warnw("Failed to extend message visibility timeout "+ + "because SQS receipt handle is no longer valid. "+ + "Stopping SQS message keepalive routine.", "error", err) + return + } + } + log.Warnw("Failed to extend message visibility timeout.", "error", err) } } diff --git a/x-pack/filebeat/input/awss3/sqs_s3_event_test.go b/x-pack/filebeat/input/awss3/sqs_s3_event_test.go index ad6d30056d42..6100dbe31191 100644 --- a/x-pack/filebeat/input/awss3/sqs_s3_event_test.go +++ b/x-pack/filebeat/input/awss3/sqs_s3_event_test.go @@ -8,9 +8,12 @@ import ( "context" "errors" "fmt" + "sync" "testing" "time" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/service/sqs" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -161,6 +164,35 @@ func TestSQSS3EventProcessor(t *testing.T) { }) } +func TestSqsProcessor_keepalive(t *testing.T) { + msg := newSQSMessage(newS3Event("log.json")) + + // Test will call ChangeMessageVisibility once and then keepalive will + // exit because the SQS receipt handle is not usable. + t.Run("keepalive stops after receipt handle is invalid", func(t *testing.T) { + const visibilityTimeout = time.Second + + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + + ctrl, ctx := gomock.WithContext(ctx, t) + defer ctrl.Finish() + mockAPI := NewMockSQSAPI(ctrl) + mockS3HandlerFactory := NewMockS3ObjectHandlerFactory(ctrl) + + receiptHandleErr := awserr.New(sqs.ErrCodeReceiptHandleIsInvalid, "fake receipt handle is invalid.", nil) + + mockAPI.EXPECT().ChangeMessageVisibility(gomock.Any(), gomock.Eq(&msg), gomock.Eq(visibilityTimeout)). + Times(1).Return(receiptHandleErr) + + p := newSQSS3EventProcessor(logp.NewLogger(inputName), nil, mockAPI, nil, visibilityTimeout, 5, mockS3HandlerFactory) + var wg sync.WaitGroup + wg.Add(1) + p.keepalive(ctx, p.log, &wg, &msg) + wg.Wait() + }) +} + func TestSqsProcessor_getS3Notifications(t *testing.T) { logp.TestingSetup() From b71fc20b6ae5337122afb4499d8633ca782b7a7a Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 17 Dec 2021 07:04:40 +0100 Subject: [PATCH 096/172] Add backport rule for 7.17 branch (#29479) --- .mergify.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index ade2822ada92..fcf643d21acb 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -185,6 +185,19 @@ pull_request_rules: labels: - "backport" title: "[{{ destination_branch }}](backport #{{ number }}) {{ title }}" + - name: backport patches to 7.17 branch + conditions: + - merged + - label=backport-v7.17.0 + actions: + backport: + assignees: + - "{{ author }}" + branches: + - "7.17" + labels: + - "backport" + title: "[{{ destination_branch }}](backport #{{ number }}) {{ title }}" - name: backport patches to 8.0 branch conditions: - merged From 5173e55bfb46b715372053a9bce75722a517a986 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 17 Dec 2021 13:50:36 +0100 Subject: [PATCH 097/172] Cleanup breaking changes section (#29490) (#29492) (cherry picked from commit d9847d75ef2f681905ee0ef8f4913655ec20bada) --- CHANGELOG.next.asciidoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 248e16180937..770c17fb03c0 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -11,7 +11,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* - Remove the non-ECS `agent.hostname` field. Use the `agent.name` or `agent.id` fields for an identifier. {issue}16377[16377] {pull}18328[18328] -- Make error message about locked data path actionable. {pull}18667[18667] - Remove the deprecated `xpack.monitoring.*` settings. Going forward only `monitoring.*` settings may be used. {issue}9424[9424] {pull}18608[18608] - Remove deprecated/undocumented IncludeCreatorMetadata setting from kubernetes metadata config options {pull}28006[28006] - Remove deprecated fields from kubernetes module {pull}28046[28046] @@ -38,12 +37,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix parsing of Elasticsearch node name by `elasticsearch/slowlog` fileset. {pull}14547[14547] - With the default configuration the following modules will no longer send the `host` field that contains information about the host on which Filebeat is running. You can revert this change by configuring tags for the module and omitting `forwarded` from the list. {issue}13920[13920] -- Preserve case of http.request.method. ECS prior to 1.6 specified normalizing to lowercase, which lost information. Affects filesets: apache/access, elasticsearch/audit, iis/access, iis/error, nginx/access, nginx/ingress_controller, aws/elb, suricata/eve, zeek/http. {issue}18154[18154] {pull}18359[18359] - With the default configuration the cloud modules (aws, azure, googlecloud, o365, okta) - With the default configuration the cef and panw modules will no longer send the `host` -- Preserve case of http.request.method. ECS prior to 1.6 specified normalizing to lowercase, which lost information. Affects filesets: apache/access, elasticsearch/audit, iis/access, iis/error, nginx/access, nginx/ingress_controller, aws/elb, suricata/eve, zeek/http. {issue}18154[18154] {pull}18359[18359] - Add `while_pattern` type to multiline reader. {pull}19662[19662] -- Add support for GMT timezone offsets in `decode_cef`. {pull}20993[20993] *Heartbeat* From b0d35a3d412e3d345f39306c4e22fd09242e9754 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Fri, 17 Dec 2021 14:44:41 +0100 Subject: [PATCH 098/172] [monitoring] bump index name version (#29493) --- metricbeat/helper/elastic/elastic.go | 2 +- metricbeat/helper/elastic/elastic_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/metricbeat/helper/elastic/elastic.go b/metricbeat/helper/elastic/elastic.go index 81216bb0e394..837ff6150646 100644 --- a/metricbeat/helper/elastic/elastic.go +++ b/metricbeat/helper/elastic/elastic.go @@ -79,7 +79,7 @@ func (p Product) String() string { // MakeXPackMonitoringIndexName method returns the name of the monitoring index for // a given product { elasticsearch, kibana, logstash, beats } func MakeXPackMonitoringIndexName(product Product) string { - const version = "7" + const version = "8" return fmt.Sprintf(".monitoring-%v-%v-mb", product.xPackMonitoringIndexString(), version) } diff --git a/metricbeat/helper/elastic/elastic_test.go b/metricbeat/helper/elastic/elastic_test.go index 26f6d4723d51..57f62d0d4d8c 100644 --- a/metricbeat/helper/elastic/elastic_test.go +++ b/metricbeat/helper/elastic/elastic_test.go @@ -38,22 +38,22 @@ func TestMakeXPackMonitoringIndexName(t *testing.T) { { "Elasticsearch monitoring index", Elasticsearch, - ".monitoring-es-7-mb", + ".monitoring-es-8-mb", }, { "Kibana monitoring index", Kibana, - ".monitoring-kibana-7-mb", + ".monitoring-kibana-8-mb", }, { "Logstash monitoring index", Logstash, - ".monitoring-logstash-7-mb", + ".monitoring-logstash-8-mb", }, { "Beats monitoring index", Beats, - ".monitoring-beats-7-mb", + ".monitoring-beats-8-mb", }, } From c428cb17ff0aa6613cf065b2779481a8451e1658 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Fri, 17 Dec 2021 15:32:51 +0100 Subject: [PATCH 099/172] [kibana module] write to rootfields instead of modulefields (#29494) --- metricbeat/module/kibana/stats/data.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricbeat/module/kibana/stats/data.go b/metricbeat/module/kibana/stats/data.go index 79e6454f8050..23696d98670e 100644 --- a/metricbeat/module/kibana/stats/data.go +++ b/metricbeat/module/kibana/stats/data.go @@ -123,7 +123,7 @@ func eventMapping(r mb.ReporterV2, content []byte, isXpack bool) error { event.Error = elastic.MakeErrorForMissingField("cluster_uuid", elastic.Kibana) return event.Error } - event.ModuleFields.Put("elasticsearch.cluster.id", elasticsearchClusterID) + event.RootFields.Put("elasticsearch.cluster.id", elasticsearchClusterID) // Set service ID uuid, err := dataFields.GetValue("uuid") From b52ad7f9ed7a5bd28924acd88ccaf5f3b989c88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Fri, 17 Dec 2021 16:27:05 +0100 Subject: [PATCH 100/172] Change renaming `@timestamp` to copying values in Ingest pipelines (#29425) --- .../module/nginx/ingress_controller/ingest/pipeline.yml | 6 +++--- .../module/checkpoint/firewall/ingest/pipeline.yml | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/filebeat/module/nginx/ingress_controller/ingest/pipeline.yml b/filebeat/module/nginx/ingress_controller/ingest/pipeline.yml index bfe589cf7039..eaed9342b61b 100644 --- a/filebeat/module/nginx/ingress_controller/ingest/pipeline.yml +++ b/filebeat/module/nginx/ingress_controller/ingest/pipeline.yml @@ -208,9 +208,9 @@ processors: patterns: - ^%{IP:source.ip}$ ignore_failure: true - - rename: - field: "@timestamp" - target_field: event.created + - set: + copy_from: "@timestamp" + field: event.created - date: field: nginx.ingress_controller.time target_field: "@timestamp" diff --git a/x-pack/filebeat/module/checkpoint/firewall/ingest/pipeline.yml b/x-pack/filebeat/module/checkpoint/firewall/ingest/pipeline.yml index 13a92e10f31c..b4dd786b0940 100644 --- a/x-pack/filebeat/module/checkpoint/firewall/ingest/pipeline.yml +++ b/x-pack/filebeat/module/checkpoint/firewall/ingest/pipeline.yml @@ -40,10 +40,9 @@ processors: - message - host ignore_missing: true -- rename: - field: "@timestamp" - target_field: "event.created" - ignore_missing: true +- set: + copy_from: "@timestamp" + field: "event.created" - date: field: "syslog5424_ts" formats: ["ISO8601", "UNIX"] From 9fbbdc349b7d35e08cf35e2ada1acf299840f933 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Fri, 17 Dec 2021 16:40:58 +0100 Subject: [PATCH 101/172] Create elastic-agent-project-board.yml (#29500) --- .../workflows/elastic-agent-project-board.yml | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/elastic-agent-project-board.yml diff --git a/.github/workflows/elastic-agent-project-board.yml b/.github/workflows/elastic-agent-project-board.yml new file mode 100644 index 000000000000..7a41ef501e35 --- /dev/null +++ b/.github/workflows/elastic-agent-project-board.yml @@ -0,0 +1,50 @@ +name: Add to Elastic Agent Data Plane or Control Plane Board +on: + issues: + types: + - labeled +jobs: + add_to_data_plane-project: + runs-on: ubuntu-latest + if: | + github.event.label.name == 'Team:Elastic-Agent-Data-Plane' + steps: + - uses: octokit/graphql-action@v2.x + id: add_to_project + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + mutation add_to_project($projectid:String!,$contentid:String!) { + addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { + projectNextItem { + id + } + } + } + projectid: ${{ env.PROJECT_ID }} + contentid: ${{ github.event.issue.node_id }} + env: + PROJECT_ID: "PRO_kwDOAGc3Zs4AzG8z" + GITHUB_TOKEN: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} + add_to_control_plane-project: + runs-on: ubuntu-latest + if: | + github.event.label.name == 'Team:Elastic-Agent-Control-Plane' + steps: + - uses: octokit/graphql-action@v2.x + id: add_to_project + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + mutation add_to_project($projectid:String!,$contentid:String!) { + addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { + projectNextItem { + id + } + } + } + projectid: ${{ env.PROJECT_ID }} + contentid: ${{ github.event.issue.node_id }} + env: + PROJECT_ID: "PRO_kwDOAGc3Zs4AzG9E" + GITHUB_TOKEN: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} From 21096a957ef490344c829e2f4e15d71a2abe66d4 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Fri, 17 Dec 2021 16:48:32 +0100 Subject: [PATCH 102/172] Update elastic-agent-project-board.yml --- .github/workflows/elastic-agent-project-board.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/elastic-agent-project-board.yml b/.github/workflows/elastic-agent-project-board.yml index 7a41ef501e35..edc4687349d1 100644 --- a/.github/workflows/elastic-agent-project-board.yml +++ b/.github/workflows/elastic-agent-project-board.yml @@ -25,7 +25,7 @@ jobs: contentid: ${{ github.event.issue.node_id }} env: PROJECT_ID: "PRO_kwDOAGc3Zs4AzG8z" - GITHUB_TOKEN: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ELASTIC_AGENT_PROJECT_BOARD_TOKEN }} add_to_control_plane-project: runs-on: ubuntu-latest if: | @@ -47,4 +47,4 @@ jobs: contentid: ${{ github.event.issue.node_id }} env: PROJECT_ID: "PRO_kwDOAGc3Zs4AzG9E" - GITHUB_TOKEN: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ELASTIC_AGENT_PROJECT_BOARD_TOKEN }} From 8353bd7ea761ae15123904374063a7a3fb126ad4 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Fri, 17 Dec 2021 17:15:39 +0100 Subject: [PATCH 103/172] Update elastic-agent-project-board.yml --- .../workflows/elastic-agent-project-board.yml | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/elastic-agent-project-board.yml b/.github/workflows/elastic-agent-project-board.yml index edc4687349d1..4e11d39b87d0 100644 --- a/.github/workflows/elastic-agent-project-board.yml +++ b/.github/workflows/elastic-agent-project-board.yml @@ -14,13 +14,9 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { - addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { - projectNextItem { - id - } - } - } + updateIssue(input: {id:$contentid, projectIds:$projectid}) { + clientMutationId + } projectid: ${{ env.PROJECT_ID }} contentid: ${{ github.event.issue.node_id }} env: @@ -36,13 +32,9 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { - addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { - projectNextItem { - id - } - } - } + updateIssue(input: {id:$contentid, projectIds:$projectid}) { + clientMutationId + } projectid: ${{ env.PROJECT_ID }} contentid: ${{ github.event.issue.node_id }} env: From 3e852fbbb1c66583aad8b7190f8116afe6f9aa9b Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Fri, 17 Dec 2021 17:18:45 +0100 Subject: [PATCH 104/172] Update elastic-agent-project-board.yml --- .github/workflows/elastic-agent-project-board.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/elastic-agent-project-board.yml b/.github/workflows/elastic-agent-project-board.yml index 4e11d39b87d0..979966f6b527 100644 --- a/.github/workflows/elastic-agent-project-board.yml +++ b/.github/workflows/elastic-agent-project-board.yml @@ -14,8 +14,10 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - updateIssue(input: {id:$contentid, projectIds:$projectid}) { - clientMutationId + mutation add_to_project($projectid:String!,$contentid:String!) { + updateIssue(input: {id:$contentid, projectIds:$projectid}) { + clientMutationId + } } projectid: ${{ env.PROJECT_ID }} contentid: ${{ github.event.issue.node_id }} @@ -32,9 +34,11 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - updateIssue(input: {id:$contentid, projectIds:$projectid}) { - clientMutationId - } + mutation add_to_project($projectid:String!,$contentid:String!) { + updateIssue(input: {id:$contentid, projectIds:$projectid}) { + clientMutationId + } + } projectid: ${{ env.PROJECT_ID }} contentid: ${{ github.event.issue.node_id }} env: From ecd68dbf492f9fbb5dc8a7b65664b9f0cfd85efa Mon Sep 17 00:00:00 2001 From: Dalibor P <9079844+dplavcic@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:47:25 +0100 Subject: [PATCH 105/172] [Docs] Update logging.files.permissions documentation to consider umask (#20584) (#28347) Changes implemented in the (#14119) made all Beats-created files and folders apply an umask of 0027 (on POSIX systems). Co-authored-by: dplavcic --- filebeat/docs/filebeat-general-options.asciidoc | 6 +++--- .../docs/howto/override-config-settings.asciidoc | 2 +- libbeat/docs/loggingconfig.asciidoc | 13 ++++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/filebeat/docs/filebeat-general-options.asciidoc b/filebeat/docs/filebeat-general-options.asciidoc index fc53057f4c2d..d1bcdf2e545e 100644 --- a/filebeat/docs/filebeat-general-options.asciidoc +++ b/filebeat/docs/filebeat-general-options.asciidoc @@ -41,14 +41,14 @@ That means in case there are some states where the TTL expired, these are only r The permissions mask to apply on registry data file. The default value is 0600. The permissions option must be a valid Unix-style file permissions mask expressed in octal notation. In Go, numbers in octal notation must start with 0. The most permissive mask allowed is 0640. If a higher permissions mask is -specified via this setting, it will be subject to a umask of 0027. +specified via this setting, it will be subject to an umask of 0027. This option is not supported on Windows. Examples: - 0640: give read and write access to the file owner, and read access to members of the group associated with the file. - 0600: give read and write access to the file owner, and no access to all others. +* 0640: give read and write access to the file owner, and read access to members of the group associated with the file. +* 0600: give read and write access to the file owner, and no access to all others. [source,yaml] ------------------------------------------------------------------------------------- diff --git a/filebeat/docs/howto/override-config-settings.asciidoc b/filebeat/docs/howto/override-config-settings.asciidoc index cb69353f00b3..63bcbfa784db 100644 --- a/filebeat/docs/howto/override-config-settings.asciidoc +++ b/filebeat/docs/howto/override-config-settings.asciidoc @@ -37,7 +37,7 @@ logging.files: path: /var/log/filebeat name: filebeat keepfiles: 7 - permissions: 0644 + permissions: 0640 ---- To override the logging level and send logging output to standard error instead diff --git a/libbeat/docs/loggingconfig.asciidoc b/libbeat/docs/loggingconfig.asciidoc index d6232e2cb07e..b5443d2d978b 100644 --- a/libbeat/docs/loggingconfig.asciidoc +++ b/libbeat/docs/loggingconfig.asciidoc @@ -32,7 +32,7 @@ logging.files: path: /var/log/{beatname_lc} name: {beatname_lc} keepfiles: 7 - permissions: 0644 + permissions: 0640 ---- endif::win_only[] @@ -45,7 +45,7 @@ logging.files: path: C:{backslash}ProgramData{backslash}{beatname_lc}{backslash}Logs name: {beatname_lc} keepfiles: 7 - permissions: 0644 + permissions: 0640 ---- endif::win_only[] @@ -231,12 +231,15 @@ The permissions mask to apply when rotating log files. The default value is expressed in octal notation. In Go, numbers in octal notation must start with '0'. +The most permissive mask allowed is 0640. If a higher permissions mask is +specified via this setting, it will be subject to an umask of 0027. + +This option is not supported on Windows. + Examples: -* 0644: give read and write access to the file owner, and read access to all others. +* 0640: give read and write access to the file owner, and read access to members of the group associated with the file. * 0600: give read and write access to the file owner, and no access to all others. -* 0664: give read and write access to the file owner and members of the group -associated with the file, as well as read access to all other users. [float] ==== `logging.files.interval` From 1b7d6e090cad8b603671f6c5dba41027a9ed19a0 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Fri, 17 Dec 2021 12:31:39 -0600 Subject: [PATCH 106/172] Fix cloudtrail config (#29450) --- CHANGELOG.next.asciidoc | 5 +++-- x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 770c17fb03c0..ab3dbaa0c408 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -147,6 +147,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] - aws-s3: Stop trying to increase SQS message visibility after ReceiptHandleIsInvalid errors. {pull}29480[29480] - Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] +- Undo deletion of endpoint config from cloudtrail fileset in {pull}29415[29415]. {pull}29450[29450] *Heartbeat* @@ -227,8 +228,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] - Support self signed certificates on outputs {pull}29229[29229] - Update k8s library {pull}29394[29394] -- Add FIPS configuration option for all AWS API calls. {pull}[28899] -- Add `default_region` config to AWS common module. {pull}[29415] +- Add FIPS configuration option for all AWS API calls. {pull}28899[28899] +- Add `default_region` config to AWS common module. {pull}29415[29415] *Auditbeat* diff --git a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml index 8c98bc31be6f..ada3a502fc20 100644 --- a/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml +++ b/x-pack/filebeat/module/aws/cloudtrail/config/aws-s3.yml @@ -49,6 +49,10 @@ visibility_timeout: {{ .visibility_timeout }} api_timeout: {{ .api_timeout }} {{ end }} +{{ if .endpoint }} +endpoint: {{ .endpoint }} +{{ end }} + {{ if .default_region }} default_region: {{ .default_region }} {{ end }} From e3b1183a3c6d4bafa40362b3bd44d356994352fc Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Fri, 17 Dec 2021 17:33:51 -0600 Subject: [PATCH 107/172] [heartbeat] Only add monitor.status to browser summary events (#29460) we now only add monitor status to summary events for browsers. Additionally, this renames the poorly renamed wrappers/monitor* to wrappers/wrappers* --- CHANGELOG.next.asciidoc | 1 + .../wrappers/{monitors.go => wrappers.go} | 14 ++- .../{monitors_test.go => wrappers_test.go} | 87 ++++++++++++++----- 3 files changed, 77 insertions(+), 25 deletions(-) rename heartbeat/monitors/wrappers/{monitors.go => wrappers.go} (96%) rename heartbeat/monitors/wrappers/{monitors_test.go => wrappers_test.go} (87%) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ab3dbaa0c408..dcedb9456fad 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -42,6 +42,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `while_pattern` type to multiline reader. {pull}19662[19662] *Heartbeat* +- Only add monitor.status to browser events when summary. {pull}29460[29460] *Metricbeat* diff --git a/heartbeat/monitors/wrappers/monitors.go b/heartbeat/monitors/wrappers/wrappers.go similarity index 96% rename from heartbeat/monitors/wrappers/monitors.go rename to heartbeat/monitors/wrappers/wrappers.go index dca3a8b70de1..c9e0c79c105f 100644 --- a/heartbeat/monitors/wrappers/monitors.go +++ b/heartbeat/monitors/wrappers/wrappers.go @@ -51,7 +51,7 @@ func WrapLightweight(js []jobs.Job, stdMonFields stdfields.StdMonitorFields) []j jobs.WrapAll( js, addMonitorMeta(stdMonFields, len(js) > 1), - addMonitorStatus(stdMonFields.Type), + addMonitorStatus(stdMonFields.Type, false), addMonitorDuration, ), func() jobs.JobWrapper { @@ -66,7 +66,7 @@ func WrapBrowser(js []jobs.Job, stdMonFields stdfields.StdMonitorFields) []jobs. return jobs.WrapAll( js, addMonitorMeta(stdMonFields, len(js) > 1), - addMonitorStatus(stdMonFields.Type), + addMonitorStatus(stdMonFields.Type, true), ) } @@ -142,12 +142,18 @@ func timespan(started time.Time, sched *schedule.Schedule, timeout time.Duration // by the original Job will be set as a field. The original error will not be // passed through as a return value. Errors may still be present but only if there // is an actual error wrapping the error. - -func addMonitorStatus(monitorType string) jobs.JobWrapper { +func addMonitorStatus(monitorType string, summaryOnly bool) jobs.JobWrapper { return func(origJob jobs.Job) jobs.Job { return func(event *beat.Event) ([]jobs.Job, error) { cont, err := origJob(event) + if summaryOnly { + hasSummary, _ := event.Fields.HasKey("summary.up") + if !hasSummary { + return cont, nil + } + } + fields := common.MapStr{ "monitor": common.MapStr{ "status": look.Status(err), diff --git a/heartbeat/monitors/wrappers/monitors_test.go b/heartbeat/monitors/wrappers/wrappers_test.go similarity index 87% rename from heartbeat/monitors/wrappers/monitors_test.go rename to heartbeat/monitors/wrappers/wrappers_test.go index 88e6fd769973..b84b18f65a92 100644 --- a/heartbeat/monitors/wrappers/monitors_test.go +++ b/heartbeat/monitors/wrappers/wrappers_test.go @@ -428,7 +428,6 @@ func TestInlineBrowserJob(t *testing.T) { "id": testMonFields.ID, "name": testMonFields.Name, "type": fields.Type, - "status": "up", "check_group": "inline-check-group", }, }), @@ -450,7 +449,7 @@ var suiteBrowserJobValues = struct { checkGroup: "journey-1-check-group", } -func makeSuiteBrowserJob(t *testing.T, u string) jobs.Job { +func makeSuiteBrowserJob(t *testing.T, u string, summary bool, suiteErr error) jobs.Job { parsed, err := url.Parse(u) require.NoError(t, err) return func(event *beat.Event) (i []jobs.Job, e error) { @@ -462,7 +461,18 @@ func makeSuiteBrowserJob(t *testing.T, u string) jobs.Job { "check_group": suiteBrowserJobValues.checkGroup, }, }) - return nil, nil + if summary { + sumFields := common.MapStr{"up": 0, "down": 0} + if suiteErr == nil { + sumFields["up"] = 1 + } else { + sumFields["down"] = 1 + } + eventext.MergeEventFields(event, common.MapStr{ + "summary": sumFields, + }) + } + return nil, suiteErr } } @@ -470,30 +480,65 @@ func TestSuiteBrowserJob(t *testing.T) { fields := testBrowserMonFields urlStr := "http://foo.com" urlU, _ := url.Parse(urlStr) + expectedMonFields := lookslike.MustCompile(map[string]interface{}{ + "monitor": map[string]interface{}{ + "id": fmt.Sprintf("%s-%s", testMonFields.ID, suiteBrowserJobValues.id), + "name": fmt.Sprintf("%s - %s", testMonFields.Name, suiteBrowserJobValues.name), + "type": fields.Type, + "check_group": suiteBrowserJobValues.checkGroup, + "timespan": common.MapStr{ + "gte": hbtestllext.IsTime, + "lt": hbtestllext.IsTime, + }, + }, + "url": URLFields(urlU), + }) testCommonWrap(t, testDef{ - "simple", + "simple", // has no summary fields! fields, - []jobs.Job{makeSuiteBrowserJob(t, urlStr)}, + []jobs.Job{makeSuiteBrowserJob(t, urlStr, false, nil)}, []validator.Validator{ - lookslike.Compose( - urlValidator(t, urlStr), - lookslike.Strict( + lookslike.Strict( + lookslike.Compose( + urlValidator(t, urlStr), + expectedMonFields, + ))}, + nil, + }) + testCommonWrap(t, testDef{ + "with up summary", + fields, + []jobs.Job{makeSuiteBrowserJob(t, urlStr, true, nil)}, + []validator.Validator{ + lookslike.Strict( + lookslike.Compose( + urlValidator(t, urlStr), + expectedMonFields, lookslike.MustCompile(map[string]interface{}{ - "monitor": map[string]interface{}{ - "id": fmt.Sprintf("%s-%s", testMonFields.ID, suiteBrowserJobValues.id), - "name": fmt.Sprintf("%s - %s", testMonFields.Name, suiteBrowserJobValues.name), - "type": fields.Type, - "check_group": suiteBrowserJobValues.checkGroup, - "status": "up", - "timespan": common.MapStr{ - "gte": hbtestllext.IsTime, - "lt": hbtestllext.IsTime, - }, + "monitor": map[string]interface{}{"status": "up"}, + "summary": map[string]interface{}{"up": 1, "down": 0}, + }), + ))}, + nil, + }) + testCommonWrap(t, testDef{ + "with down summary", + fields, + []jobs.Job{makeSuiteBrowserJob(t, urlStr, true, fmt.Errorf("testerr"))}, + []validator.Validator{ + lookslike.Strict( + lookslike.Compose( + urlValidator(t, urlStr), + expectedMonFields, + lookslike.MustCompile(map[string]interface{}{ + "monitor": map[string]interface{}{"status": "down"}, + "summary": map[string]interface{}{"up": 0, "down": 1}, + "error": map[string]interface{}{ + "type": isdef.IsString, + "message": "testerr", }, - "url": URLFields(urlU), }), - ), - )}, + ))}, nil, }) } From ef6899f3e16218a10160eafe6b284127f7bebc2d Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Sun, 19 Dec 2021 15:56:07 +0000 Subject: [PATCH 108/172] update beats-tester main branch (#29496) --- .ci/beats-tester-bc.groovy | 2 +- .ci/beats-tester.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/beats-tester-bc.groovy b/.ci/beats-tester-bc.groovy index d7fb36f15bd8..d026fa77a15a 100644 --- a/.ci/beats-tester-bc.groovy +++ b/.ci/beats-tester-bc.groovy @@ -7,7 +7,7 @@ pipeline { environment { BASE_DIR = 'src/github.com/elastic/beats' PIPELINE_LOG_LEVEL = "INFO" - BEATS_TESTER_JOB = 'Beats/beats-tester-mbp/master' + BEATS_TESTER_JOB = 'Beats/beats-tester-mbp/main' BASE_URL = "https://staging.elastic.co/${params.version}/downloads" APM_BASE_URL = "${env.BASE_URL}/apm-server" BEATS_BASE_URL = "${env.BASE_URL}/beats" diff --git a/.ci/beats-tester.groovy b/.ci/beats-tester.groovy index 8d96fb1efeaa..ef0b83828265 100644 --- a/.ci/beats-tester.groovy +++ b/.ci/beats-tester.groovy @@ -7,7 +7,7 @@ pipeline { environment { BASE_DIR = 'src/github.com/elastic/beats' PIPELINE_LOG_LEVEL = "INFO" - BEATS_TESTER_JOB = 'Beats/beats-tester-mbp/master' + BEATS_TESTER_JOB = 'Beats/beats-tester-mbp/main' } options { timeout(time: 1, unit: 'HOURS') From e9c18f7f357a5349bbbb2883a18c925d5d8aa1b0 Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Mon, 20 Dec 2021 02:06:28 -0500 Subject: [PATCH 109/172] [Automation] Update elastic stack version to 8.1.0-befff95a for testing (#29535) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index ce828d0f5ab3..2b252a4a60cd 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-d8a3a806-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-befff95a-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-d8a3a806-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-befff95a-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-d8a3a806-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-befff95a-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 2ef97dfeebd7..d46af8af39af 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-d8a3a806-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-befff95a-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-d8a3a806-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-befff95a-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From d61c298e8050a1b6bdd9125a080f87d8726f94d3 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 20 Dec 2021 08:07:03 +0100 Subject: [PATCH 110/172] Forward port 7.16.2 changelog to master and cleanup (#29532) --- CHANGELOG.asciidoc | 21 +++++ CHANGELOG.next.asciidoc | 149 ++-------------------------------- libbeat/docs/release.asciidoc | 1 + 3 files changed, 28 insertions(+), 143 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 082ef758cb62..dfad0bb2de10 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -17,6 +17,27 @@ Changes will be described in a later alpha / beta. === Beats version 8.0.0-alpha1 Changes will be described in a later alpha / beta. +[[release-notes-7.16.2]] +=== Beats version 7.16.2 +https://github.com/elastic/beats/compare/v7.16.1...v7.16.2[View commits] + +==== Bugfixes + +*Filebeat* + +- Resolve issue with @timestamp for `defender_atp`. {pull}28272[28272] +- Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] + +==== Added + +*Filebeat* + +- Update Cisco module to enable TCP input. {issue}26118[26118] {issue}28821[28821] {pull}26159[26159] + +*Winlogbeat* + +- Add configuration option for registry file flush timeout {issue}29001[29001] {pull}29053[29053] + [[release-notes-7.16.1]] === Beats version 7.16.1 https://github.com/elastic/beats/compare/v7.16.0...v7.16.1[View commits] diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index dcedb9456fad..1ceabcb9c57e 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -10,7 +10,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* -- Remove the non-ECS `agent.hostname` field. Use the `agent.name` or `agent.id` fields for an identifier. {issue}16377[16377] {pull}18328[18328] - Remove the deprecated `xpack.monitoring.*` settings. Going forward only `monitoring.*` settings may be used. {issue}9424[9424] {pull}18608[18608] - Remove deprecated/undocumented IncludeCreatorMetadata setting from kubernetes metadata config options {pull}28006[28006] - Remove deprecated fields from kubernetes module {pull}28046[28046] @@ -36,7 +35,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Filebeat* - Fix parsing of Elasticsearch node name by `elasticsearch/slowlog` fileset. {pull}14547[14547] -- With the default configuration the following modules will no longer send the `host` field that contains information about the host on which Filebeat is running. You can revert this change by configuring tags for the module and omitting `forwarded` from the list. {issue}13920[13920] - With the default configuration the cloud modules (aws, azure, googlecloud, o365, okta) - With the default configuration the cef and panw modules will no longer send the `host` - Add `while_pattern` type to multiline reader. {pull}19662[19662] @@ -71,7 +69,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Improve ECS field mappings in Sysmon module. Hashes are now also populated to the corresponding `process.hash`, `process.pe.imphash`, `file.hash`, or `file.pe.imphash`. {issue}18364[18364] - Improve ECS field mappings in Sysmon module. `file.name`, `file.directory`, and `file.extension` are now populated. {issue}18364[18364] - Improve ECS field mappings in Sysmon module. `rule.name` is populated for all events when present. {issue}18364[18364] -- Fix unprefixed fields in `fields.yml` for Powershell module {issue}18984[18984] - Remove top level `hash` property from sysmon events {pull}20653[20653] *Functionbeat* @@ -81,109 +78,21 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* -- Fix a race condition with the Kafka pipeline client, it is possible that `Close()` get called before `Connect()` . {issue}11945[11945] -- Allow users to configure only `cluster_uuid` setting under `monitoring` namespace. {pull}14338[14338] -- Update replicaset group to apps/v1 {pull}15854[15802] -- Fix missing output in dockerlogbeat {pull}15719[15719] -- Fix issue where TLS settings would be ignored when a forward proxy was in use. {pull}15516[15516] -- Update replicaset group to apps/v1 {pull}15854[15802] -- Add `ssl.ca_sha256` option to the supported TLS option, this allow to check that a specific certificate is used as part of the verified chain. {issue}15717[15717] -- Improve some logging messages for add_kubernetes_metadata processor {pull}16866{16866} -- Do not rotate log files on startup when interval is configured and rotateonstartup is disabled. {pull}17613[17613] -- Fix `setup.dashboards.index` setting not working. {pull}17749[17749] -- Fix Elasticsearch license endpoint URL referenced in error message. {issue}17880[17880] {pull}18030[18030] -- Change `decode_json_fields` processor, to merge parsed json objects with existing objects in the event instead of fully replacing them. {pull}17958[17958] -- Gives monitoring reporter hosts, if configured, total precedence over corresponding output hosts. {issue}17937[17937] {pull}17991[17991] -- Change `decode_json_fields` processor, to merge parsed json objects with existing objects in the event instead of fully replacing them. {pull}17958[17958] -- [Autodiscover] Check if runner is already running before starting again. {pull}18564[18564] -- Fix an issue where error messages are not accurate in mapstriface. {issue}18662[18662] {pull}18663[18663] -- Fix regression in `add_kubernetes_metadata`, so configured `indexers` and `matchers` are used if defaults are not disabled. {issue}18481[18481] {pull}18818[18818] -- Fix the `translate_sid` processor's handling of unconfigured target fields. {issue}18990[18990] {pull}18991[18991] -- Fixed a service restart failure under Windows. {issue}18914[18914] {pull}18916[18916] -- Fix terminating pod autodiscover issue. {pull}20084[20084] -- Fix seccomp policy for calls to `chmod` and `chown`. {pull}20054[20054] -- Output errors when Kibana index pattern setup fails. {pull}20121[20121] -- Fix issue in autodiscover that kept inputs stopped after config updates. {pull}20305[20305] -- Add service resource in k8s cluster role. {pull}20546[20546] -- Allows disable pod events enrichment with deployment name {pull}28521[28521] -- Fix `fingerprint` processor to give it access to the `@timestamp` field. {issue}28683[28683] -- Fix the wrong beat name on monitoring and state endpoint {issue}27755[27755] - *Auditbeat* -- system/package: Fix parsing of Installed-Size field of DEB packages. {issue}16661[16661] {pull}17188[17188] -- system module: Fix panic during initialisation when /proc/stat can't be read. {pull}17569[17569] -- system/package: Fix an error that can occur while trying to persist package metadata. {issue}18536[18536] {pull}18887[18887] -- system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] *Filebeat* -- cisco/asa fileset: Fix parsing of 302021 message code. {pull}14519[14519] -- Fix filebeat azure dashboards, event category should be `Alert`. {pull}14668[14668] -- Fix s3 input with cloudtrail fileset reading json file. {issue}16374[16374] {pull}16441[16441] -- Add queue_url definition in manifest file for aws module. {pull}16640[16640] -- Add queue_url definition in manifest file for aws module. {pull}16640{16640} -- Fix `elasticsearch.gc` fileset to not collect _all_ logs when Elasticsearch is running in Docker. {issue}13164[13164] {issue}16583[16583] {pull}17164[17164] -- Fixed a mapping exception when ingesting CEF logs that used the spriv or dpriv extensions. {issue}17216[17216] {pull}17220[17220] -- Remove migrationVersion map 7.7.0 reference from Kibana dashboard file to fix backward compatibility issues. {pull}17425[17425] -- Fix issue 17734 to retry on rate-limit error in the Filebeat httpjson input. {issue}17734[17734] {pull}17735[17735] -- Fixed `cloudfoundry.access` to have the correct `cloudfoundry.app.id` contents. {pull}17847[17847] -- Fixing `ingress_controller.` fields to be of type keyword instead of text. {issue}17834[17834] -- Fixed typo in log message. {pull}17897[17897] -- Fix `o365` module ignoring `var.api` settings. {pull}18948[18948] -- Fix `netflow` module to support 7 bytepad for IPFIX template. {issue}18098[18098] -- Update container name for the azure filesets. {pull}19899[19899] -- Fix `o365` module ignoring `var.api` settings. {pull}18948[18948] -- Fix S3 input to trim delimiter /n from each log line. {pull}19972[19972] -- Fix s3 input parsing json file without expand_event_list_from_field. {issue}19902[19902] {pull}19962[19962] {pull}20370[20370] -- Fix millisecond timestamp normalization issues in CrowdStrike module {issue}20035[20035], {pull}20138[20138] -- Fix support for message code 106100 in Cisco ASA and FTD. {issue}19350[19350] {pull}20245[20245] -- Fix `fortinet` setting `event.timezone` to the system one when no `tz` field present {pull}20273[20273] -- Fix `okta` geoip lookup in pipeline for `destination.ip` {pull}20454[20454] -- Fix mapping exception in the `googlecloud/audit` dataset pipeline. {issue}18465[18465] {pull}20465[20465] -- Fix `cisco` asa and ftd parsing of messages 106102 and 106103. {pull}20469[20469] -- Resolve issue with @timestamp for defender_atp. {pull}28272[28272] -- Fix `threatintel.misp` filters configuration. {issue}27970[27970] -- Fix handling of escaped newlines in the `decode_cef` processor. {issue}16995[16995] {pull}29268[29268] -- Fix `panw` module ingest errors for GLOBALPROTECT logs {pull}29154[29154] - aws-s3: Stop trying to increase SQS message visibility after ReceiptHandleIsInvalid errors. {pull}29480[29480] - Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] - Undo deletion of endpoint config from cloudtrail fileset in {pull}29415[29415]. {pull}29450[29450] *Heartbeat* -- Remove accidentally included cups library in docker images. {pull}28853[pull] - Fix broken monitors with newer versions of image relying on dup3. {pull}28938[pull] *Metricbeat* -- Fix checking tagsFilter using length in cloudwatch metricset. {pull}14525[14525] -- Log bulk failures from bulk API requests to monitoring cluster. {issue}14303[14303] {pull}14356[14356] -- Fix skipping protocol scheme by light modules. {pull}16205[pull] -- Revert changes in `docker` module: add size flag to docker.container. {pull}16600[16600] -- Fix detection and logging of some error cases with light modules. {pull}14706[14706] -- Fix imports after PR was merged before rebase. {pull}16756[16756] -- Reduce memory usage in `elasticsearch/index` metricset. {issue}16503[16503] {pull}16538[16538] -- Fix issue in Jolokia module when mbean contains multiple quoted properties. {issue}17375[17375] {pull}17374[17374] -- Fix issue in Jolokia module when mbean contains multiple quoted properties. {issue}17375[17375] {pull}17374[17374] -- Fix azure storage dashboards. {pull}17590[17590] -- Metricbeat no longer needs to be started strictly after Logstash for `logstash-xpack` module to report correct data. {issue}17261[17261] {pull}17497[17497] -- Fix pubsub metricset to collect all GA stage metrics from gcp stackdriver. {issue}17154[17154] {pull}17600[17600] -- Add privileged option so as mb to access data dir in Openshift. {pull}17606[17606] -- Fix "ID" event generator of Google Cloud module {issue}17160[17160] {pull}17608[17608] -- Add privileged option for Auditbeat in Openshift {pull}17637[17637] -- Fix storage metricset to allow config without region/zone. {issue}17623[17623] {pull}17624[17624] -- Fix overflow on Prometheus rates when new buckets are added on the go. {pull}17753[17753] -- Remove specific win32 api errors from events in perfmon. {issue}18292[18292] {pull}18361[18361] -- Fix application_pool metricset after pdh changes. {pull}18477[18477] -- Fix panic on `metricbeat test modules` when modules are configured in `metricbeat.modules`. {issue}18789[18789] {pull}18797[18797] -- Fix getting gcp compute instance metadata with partial zone/region in config. {pull}18757[18757] -- Add missing network.sent_packets_count metric into compute metricset in googlecloud module. {pull}18802[18802] -- Fix compute and pubsub dashboard for googlecloud module. {issue}18962[18962] {pull}18980[18980] -- Fix crash on vsphere module when Host information is not available. {issue}18996[18996] {pull}19078[19078] -- Modify doc for app_insights metricset to contain example of config. {pull}20185[20185] -- Add required option for `metrics` in app_insights. {pull}20406[20406] -- Groups same timestamp metric values to one event in the app_insights metricset. {pull}20403[20403] - Use xpack.enabled on SM modules to write into .monitoring indices when using Metricbeat standalone {pull}28365[28365] - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] - Enhance filter check in kubernetes event metricset. {pull}29470[29470] @@ -195,7 +104,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Winlogbeat* -- Add source.ip validation for event ID 4778 in the Security module. {issue}19627[19627] *Functionbeat* @@ -207,25 +115,10 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* -- Decouple Debug logging from fail_on_error logic for rename, copy, truncate processors {pull}12451[12451] -- Fingerprint processor adds a new xxhash hashing algorithm {pull}15418[15418] -- Update RPM packages contained in Beat Docker images. {issue}17035[17035] -- Update documentation for system.process.memory fields to include clarification on Windows os's. {pull}17268[17268] -- When using the `decode_json_fields` processor, decoded fields are now deep-merged into existing event. {pull}17958[17958] -- Update documentation for system.process.memory fields to include clarification on Windows os's. {pull}17268[17268] -- Add keystore support for autodiscover static configurations. {pull]16306[16306] -- When using the `decode_json_fields` processor, decoded fields are now deep-merged into existing event. {pull}17958[17958] -- Add keystore support for autodiscover static configurations. {pull]16306[16306] -- Add TLS support to Kerberos authentication in Elasticsearch. {pull}18607[18607] - Add config option `rotate_on_startup` to file output {issue}19150[19150] {pull}19347[19347] -- Set index.max_docvalue_fields_search in index template to increase value to 200 fields. {issue}20215[20215] -- Upgrade prometheus library. {pull}28716[28716] - Name all k8s workqueue. {pull}28085[28085] -- Add options to configure k8s client qps/burst. {pull}28151[28151] - Update to ECS 8.0 fields. {pull}28620[28620] -- Add http.pprof.enabled option to libbeat to allow http/pprof endpoints on the socket that libbeat creates for metrics. {issue}21965[21965] - Support custom analyzers in fields.yml. {issue}28540[28540] {pull}28926[28926] -- SASL/SCRAM in the Kafka output is no longer beta. {pull}29126[29126] - Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139] - Support self signed certificates on outputs {pull}29229[29229] - Update k8s library {pull}29394[29394] @@ -234,55 +127,21 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Auditbeat* -- Reference kubernetes manifests include configuration for auditd and enrichment with kubernetes metadata. {pull}17431[17431] *Filebeat* -- `container` and `docker` inputs now support reading of labels and env vars written by docker JSON file logging driver. {issue}8358[8358] -- Add `index` option to all inputs to directly set a per-input index value. {pull}14010[14010] -- move create-[module,fileset,fields] to mage and enable in x-pack/filebeat {pull}15836[15836] -- Work on e2e ACK's for the azure-eventhub input {issue}15671[15671] {pull}16215[16215] -- Add a TLS test and more debug output to httpjson input {pull}16315[16315] -- Add an SSL config example in config.yml for filebeat MISP module. {pull}16320[16320] -- Update filebeat httpjson input to support pagination via Header and Okta module. {pull}16354[16354] -- Add a TLS test and more debug output to httpjson input {pull}16315[16315] -- Add an SSL config example in config.yml for filebeat MISP module. {pull}16320[16320] -- Added documentation for running Filebeat in Cloud Foundry. {pull}17275[17275] -- Release Google Cloud module as GA. {pull}17511[17511] -- Improve ECS categorization field mappings for nats module. {issue}16173[16173] {pull}17550[17550] -- Enhance `elasticsearch/slowlog` fileset to handle ECS-compatible logs emitted by Elasticsearch. {issue}17715[17715] {pull}17729[17729] -- Added documentation for running Filebeat in Cloud Foundry. {pull}17275[17275] -- Release Google Cloud module as GA. {pull}17511[17511] -- Update filebeat httpjson input to support pagination via Header and Okta module. {pull}16354[16354] -- Change the `json.*` input settings implementation to merge parsed json objects with existing objects in the event instead of fully replacing them. {pull}17958[17958] -- Add support for array parsing in azure-eventhub input. {pull}18585[18585] -- Add support for array parsing in azure-eventhub input. {pull}18585[18585] -- Improved performance of PANW sample dashboards. {issue}19031[19031] {pull}19032[19032] -- Add event.ingested for CrowdStrike module {pull}20138[20138] -- Add support for additional fields and FirewallMatchEvent type events in CrowdStrike module {pull}20138[20138] -- Azure signinlogs - Add support for ManagedIdentitySignInLogs, NonInteractiveUserSignInLogs, and ServicePrincipalSignInLogs. {issue}23653[23653] - Add `text/csv` decoder to `httpjson` input {pull}28564[28564] - Update `aws-s3` input to connect to non AWS S3 buckets {issue}28222[28222] {pull}28234[28234] - Add support for '/var/log/pods/' path for add_kubernetes_metadata processor with `resource_type: pod`. {pull}28868[28868] - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support for parsers on journald input {pull}29070[29070] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] -- Update Cisco module to enable TCP input. {issue}26118[26118] {issue}28821[28821] {pull}26159[26159] *Heartbeat* *Metricbeat* -- Move the windows pdh implementation from perfmon to a shared location in order for future modules/metricsets to make use of. {pull}15503[15503] -- Add database_account azure metricset. {issue}15758[15758] -- Add database_account azure metricset. {issue}15758[15758] -- Release Zookeeper/connection module as GA. {issue}14281[14281] {pull}17043[17043] -- Add dashboard for pubsub metricset in googlecloud module. {pull}17161[17161] -- Added documentation for running Metricbeat in Cloud Foundry. {pull}17275[17275] -- Added documentation for running Metricbeat in Cloud Foundry. {pull}17275[17275] -- Remove required for region/zone and make stackdriver a metricset in googlecloud. {issue}16785[16785] {pull}18398[18398] -- Add memory metrics into compute googlecloud. {pull}18802[18802] - Preliminary AIX support {pull}27954[27954] - Add option to skip older k8s events {pull}29396[29396] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] @@ -294,8 +153,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Winlogbeat* -- Add more DNS error codes to the Sysmon module. {issue}15685[15685] -- Add configuration option for registry file flush timeout {issue}29001[29001] {pull}29053[29053] - Add support for custom XML queries {issue}1054[1054] {pull}29330[29330] *Elastic Log Driver* @@ -324,3 +181,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d ==== Known Issue *Journalbeat* + + + + + + diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index 1529ebf2872b..26e1bd6b14d2 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -11,6 +11,7 @@ upgrade. * <> * <> * <> +* <> * <> * <> * <> From fc01723bd352e712d2787b4759dadc2c221b0270 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Mon, 20 Dec 2021 07:38:13 +0000 Subject: [PATCH 111/172] [mergify]: keep the house clean for conflicts in automated bumps (#29455) --- .mergify.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index fcf643d21acb..7815f7579d3a 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -21,6 +21,7 @@ pull_request_rules: - -merged - -closed - conflict + - -author=apmmachine actions: comment: message: | @@ -32,6 +33,18 @@ pull_request_rules: git merge upstream/{{base}} git push upstream {{head}} ``` + - name: close automated pull requests with bump updates if any conflict + conditions: + - -merged + - -closed + - conflict + - author=apmmachine + - label=automation + actions: + close: + message: | + This pull request has been automatically closed by Mergify. + There are some other up-to-date pull requests. - name: automatic approval for automated pull requests with bump updates conditions: - author=apmmachine From ab8b97ecdb36a36a879733e2c0433ed9a5815893 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Mon, 20 Dec 2021 09:15:24 +0000 Subject: [PATCH 112/172] jjbb: enable 7.17 (and 7.18/19) (#29522) --- .ci/jobs/beats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/jobs/beats.yml b/.ci/jobs/beats.yml index e9a26c87a0d6..0500b2ba8f28 100644 --- a/.ci/jobs/beats.yml +++ b/.ci/jobs/beats.yml @@ -17,7 +17,7 @@ discover-pr-forks-strategy: 'merge-current' discover-pr-forks-trust: 'permission' discover-pr-origin: 'merge-current' - head-filter-regex: '(master|6\.[89]|7\.16|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' + head-filter-regex: '(master|6\.[89]|7\.1[6789]|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' discover-tags: true notification-context: "beats-ci" repo: 'beats' From 00de284f4f169591f4c1d993dfd6301551fd8ffb Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Mon, 20 Dec 2021 10:55:59 +0000 Subject: [PATCH 113/172] update e2e-testing main branch (#29527) --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 19978442bf8d..04423d77b91b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -554,7 +554,7 @@ def e2e_with_entrypoint(Map args = [:]) { def dockerLogFile = "docker_logs_${entrypoint}.log" dir("${env.WORKSPACE}/src/github.com/elastic/e2e-testing") { // TBC with the target branch if running on a PR basis. - git(branch: 'master', credentialsId: '2a9602aa-ab9f-4e52-baf3-b71ca88469c7-UserAndToken', url: 'https://github.com/elastic/e2e-testing.git') + git(branch: 'main', credentialsId: '2a9602aa-ab9f-4e52-baf3-b71ca88469c7-UserAndToken', url: 'https://github.com/elastic/e2e-testing.git') if(isDockerInstalled()) { dockerLogin(secret: "${DOCKER_ELASTIC_SECRET}", registry: "${DOCKER_REGISTRY}") } From e6e65aa92fe355c95789691ebf5a3bcecaf5b4ea Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Mon, 20 Dec 2021 10:59:04 +0000 Subject: [PATCH 114/172] update ingest-dev main branch (#29525) --- .ci/jobs/beats-release-changelog.yml | 2 +- .ci/jobs/beats-release-minor-major.yml | 2 +- .ci/jobs/beats-release-patch.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/jobs/beats-release-changelog.yml b/.ci/jobs/beats-release-changelog.yml index 1cbd94c7168a..6a331022e8f7 100644 --- a/.ci/jobs/beats-release-changelog.yml +++ b/.ci/jobs/beats-release-changelog.yml @@ -17,4 +17,4 @@ credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba reference-repo: /var/lib/jenkins/.git-references/ingest-dev.git branches: - - master + - main diff --git a/.ci/jobs/beats-release-minor-major.yml b/.ci/jobs/beats-release-minor-major.yml index 91c7d105fb8a..04a2e07046d2 100644 --- a/.ci/jobs/beats-release-minor-major.yml +++ b/.ci/jobs/beats-release-minor-major.yml @@ -17,4 +17,4 @@ credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba reference-repo: /var/lib/jenkins/.git-references/ingest-dev.git branches: - - master + - main diff --git a/.ci/jobs/beats-release-patch.yml b/.ci/jobs/beats-release-patch.yml index 4d205f79647a..80c401e6c204 100644 --- a/.ci/jobs/beats-release-patch.yml +++ b/.ci/jobs/beats-release-patch.yml @@ -17,4 +17,4 @@ credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba reference-repo: /var/lib/jenkins/.git-references/ingest-dev.git branches: - - master + - main From 7941c1c936511407ed70460b5657579c9ae1628c Mon Sep 17 00:00:00 2001 From: Michael Katsoulis Date: Tue, 21 Dec 2021 14:17:03 +0200 Subject: [PATCH 115/172] Calculate memory.working_set.limit.pct for pod and container metricset (#29547) * Calculate memory.working_set.limit.pct for pod and container metricset --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 24 +++++++++++++++++++ .../kubernetes/container/_meta/fields.yml | 5 ++++ .../kubernetes/container/container_test.go | 9 +++---- .../module/kubernetes/container/data.go | 1 + metricbeat/module/kubernetes/fields.go | 2 +- .../module/kubernetes/pod/_meta/fields.yml | 5 ++++ metricbeat/module/kubernetes/pod/data.go | 3 +++ metricbeat/module/kubernetes/pod/pod_test.go | 7 +++--- 9 files changed, 49 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1ceabcb9c57e..9c736fd6c64c 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -145,6 +145,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Preliminary AIX support {pull}27954[27954] - Add option to skip older k8s events {pull}29396[29396] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] +- Add `memory.workingset.limit.pct` field in Kubernetes container/pod metricset. {pull}29547[29547] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index c1e7087125c8..2553dc415ed9 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -41959,6 +41959,18 @@ format: bytes -- +*`kubernetes.container.memory.workingset.limit.pct`*:: ++ +-- +Working set memory usage as a percentage of the defined limit for the container (or total node allocatable memory if unlimited) + + +type: scaled_float + +format: percent + +-- + *`kubernetes.container.memory.pagefaults`*:: + -- @@ -43023,6 +43035,18 @@ format: bytes -- +*`kubernetes.pod.memory.working_set.limit.pct`*:: ++ +-- +Working set memory usage as a percentage of the defined limit for the pod containers (or total node allocatable memory if unlimited) + + +type: scaled_float + +format: percent + +-- + *`kubernetes.pod.memory.rss.bytes`*:: + diff --git a/metricbeat/module/kubernetes/container/_meta/fields.yml b/metricbeat/module/kubernetes/container/_meta/fields.yml index 8bd8bd6449a2..81b99f75c0c0 100644 --- a/metricbeat/module/kubernetes/container/_meta/fields.yml +++ b/metricbeat/module/kubernetes/container/_meta/fields.yml @@ -126,6 +126,11 @@ format: bytes description: > Working set memory usage + - name: limit.pct + type: scaled_float + format: percent + description: > + Working set memory usage as a percentage of the defined limit for the container (or total node allocatable memory if unlimited) - name: pagefaults type: double description: > diff --git a/metricbeat/module/kubernetes/container/container_test.go b/metricbeat/module/kubernetes/container/container_test.go index 300098461699..816464d7b9d8 100644 --- a/metricbeat/module/kubernetes/container/container_test.go +++ b/metricbeat/module/kubernetes/container/container_test.go @@ -69,10 +69,11 @@ func TestEventMapping(t *testing.T) { "memory.majorpagefaults": 0, // calculated pct fields: - "cpu.usage.node.pct": 0.005631997, - "cpu.usage.limit.pct": 0.005631997, - "memory.usage.node.pct": 0.01, - "memory.usage.limit.pct": 0.1, + "cpu.usage.node.pct": 0.005631997, + "cpu.usage.limit.pct": 0.005631997, + "memory.usage.node.pct": 0.01, + "memory.usage.limit.pct": 0.1, + "memory.workingset.limit.pct": 0.09943977591036414, "name": "nginx", diff --git a/metricbeat/module/kubernetes/container/data.go b/metricbeat/module/kubernetes/container/data.go index 53a795624d98..ad2e1243339d 100644 --- a/metricbeat/module/kubernetes/container/data.go +++ b/metricbeat/module/kubernetes/container/data.go @@ -135,6 +135,7 @@ func eventMapping(content []byte, perfMetrics *util.PerfMetricsCache) ([]common. if memLimit > 0 { containerEvent.Put("memory.usage.limit.pct", float64(container.Memory.UsageBytes)/memLimit) + containerEvent.Put("memory.workingset.limit.pct", float64(container.Memory.WorkingSetBytes)/memLimit) } events = append(events, containerEvent) diff --git a/metricbeat/module/kubernetes/fields.go b/metricbeat/module/kubernetes/fields.go index 73b71223fe1b..e634e74a2008 100644 --- a/metricbeat/module/kubernetes/fields.go +++ b/metricbeat/module/kubernetes/fields.go @@ -32,5 +32,5 @@ func init() { // AssetKubernetes returns asset data. // This is the base64 encoded zlib format compressed contents of module/kubernetes. func AssetKubernetes() string { - return "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" + return "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" } diff --git a/metricbeat/module/kubernetes/pod/_meta/fields.yml b/metricbeat/module/kubernetes/pod/_meta/fields.yml index 0537faab52ae..0b46d2908398 100644 --- a/metricbeat/module/kubernetes/pod/_meta/fields.yml +++ b/metricbeat/module/kubernetes/pod/_meta/fields.yml @@ -94,6 +94,11 @@ format: bytes description: > Total working set memory + - name: limit.pct + type: scaled_float + format: percent + description: > + Working set memory usage as a percentage of the defined limit for the pod containers (or total node allocatable memory if unlimited) - name: rss type: group fields: diff --git a/metricbeat/module/kubernetes/pod/data.go b/metricbeat/module/kubernetes/pod/data.go index bb24d31905c9..fdb604d4e178 100644 --- a/metricbeat/module/kubernetes/pod/data.go +++ b/metricbeat/module/kubernetes/pod/data.go @@ -128,6 +128,8 @@ func eventMapping(content []byte, perfMetrics *util.PerfMetricsCache) ([]common. } if memLimit > 0 { podEvent.Put("memory.usage.limit.pct", float64(usageMem)/memLimit) + podEvent.Put("memory.working_set.limit.pct", float64(workingSet)/memLimit) + } } @@ -137,6 +139,7 @@ func eventMapping(content []byte, perfMetrics *util.PerfMetricsCache) ([]common. } if memLimit > 0 { podEvent.Put("memory.usage.limit.pct", float64(workingSet)/memLimit) + podEvent.Put("memory.working_set.limit.pct", float64(workingSet)/memLimit) } } diff --git a/metricbeat/module/kubernetes/pod/pod_test.go b/metricbeat/module/kubernetes/pod/pod_test.go index 41340e5dede1..37486ad58e89 100644 --- a/metricbeat/module/kubernetes/pod/pod_test.go +++ b/metricbeat/module/kubernetes/pod/pod_test.go @@ -64,9 +64,10 @@ func TestEventMapping(t *testing.T) { "cpu.usage.node.pct": 0.005631997, "cpu.usage.limit.pct": 0.005631997, - "memory.usage.bytes": 1462272, - "memory.usage.node.pct": 0.01, - "memory.usage.limit.pct": 0.1, + "memory.usage.bytes": 1462272, + "memory.usage.node.pct": 0.01, + "memory.usage.limit.pct": 0.1, + "memory.working_set.limit.pct": 0.09943977591036414, } for k, v := range testCases { From aa248af1ba19d4c4979e810402562a5711642c9b Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Tue, 21 Dec 2021 13:24:23 +0100 Subject: [PATCH 116/172] add/use blocking wait for test data in statsd (#29543) * add/use blocking wait for test data in statsd * refactor to avoid race condition in TestData * fix serverStarted flag --- metricbeat/mb/testing/modules.go | 35 ++++++++++++++----- .../module/airflow/statsd/data_test.go | 22 +++++++++--- .../metricbeat/module/statsd/server/server.go | 30 +++++++++++++--- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/metricbeat/mb/testing/modules.go b/metricbeat/mb/testing/modules.go index 605e44a4d326..c5dd3ecbcdd8 100644 --- a/metricbeat/mb/testing/modules.go +++ b/metricbeat/mb/testing/modules.go @@ -344,20 +344,20 @@ func NewPushMetricSetV2WithContext(t testing.TB, config interface{}) mb.PushMetr return pushMetricSet } -// capturingPushReporterV2 stores all the events and errors from a metricset's +// CapturingPushReporterV2 stores all the events and errors from a metricset's // Run method. -type capturingPushReporterV2 struct { +type CapturingPushReporterV2 struct { context.Context eventsC chan mb.Event } -func newCapturingPushReporterV2(ctx context.Context) *capturingPushReporterV2 { - return &capturingPushReporterV2{Context: ctx, eventsC: make(chan mb.Event)} +func newCapturingPushReporterV2(ctx context.Context) *CapturingPushReporterV2 { + return &CapturingPushReporterV2{Context: ctx, eventsC: make(chan mb.Event)} } // report writes an event to the output channel and returns true. If the output // is closed it returns false. -func (r *capturingPushReporterV2) report(event mb.Event) bool { +func (r *CapturingPushReporterV2) report(event mb.Event) bool { select { case <-r.Done(): // Publisher is stopped. @@ -368,16 +368,16 @@ func (r *capturingPushReporterV2) report(event mb.Event) bool { } // Event stores the passed-in event into the events array -func (r *capturingPushReporterV2) Event(event mb.Event) bool { +func (r *CapturingPushReporterV2) Event(event mb.Event) bool { return r.report(event) } // Error stores the given error into the errors array. -func (r *capturingPushReporterV2) Error(err error) bool { +func (r *CapturingPushReporterV2) Error(err error) bool { return r.report(mb.Event{Error: err}) } -func (r *capturingPushReporterV2) capture(waitEvents int) []mb.Event { +func (r *CapturingPushReporterV2) capture(waitEvents int) []mb.Event { var events []mb.Event for { select { @@ -393,6 +393,20 @@ func (r *capturingPushReporterV2) capture(waitEvents int) []mb.Event { } } +// BlockingCapture blocks until waitEvents n of events are captured +func (r *CapturingPushReporterV2) BlockingCapture(waitEvents int) []mb.Event { + var events []mb.Event + for { + select { + case e := <-r.eventsC: + events = append(events, e) + if waitEvents > 0 && len(events) >= waitEvents { + return events + } + } + } +} + // RunPushMetricSetV2 run the given push metricset for the specific amount of // time and returns all of the events and errors that occur during that period. func RunPushMetricSetV2(timeout time.Duration, waitEvents int, metricSet mb.PushMetricSetV2) []mb.Event { @@ -405,6 +419,11 @@ func RunPushMetricSetV2(timeout time.Duration, waitEvents int, metricSet mb.Push return r.capture(waitEvents) } +// GetCapturingPushReporterV2 is a factory for a capturing push metricset +func GetCapturingPushReporterV2() mb.PushReporterV2 { + return newCapturingPushReporterV2(context.Background()) +} + // RunPushMetricSetV2WithContext run the given push metricset for the specific amount of // time and returns all of the events that occur during that period. func RunPushMetricSetV2WithContext(timeout time.Duration, waitEvents int, metricSet mb.PushMetricSetV2WithContext) []mb.Event { diff --git a/x-pack/metricbeat/module/airflow/statsd/data_test.go b/x-pack/metricbeat/module/airflow/statsd/data_test.go index b8cc1ab4718e..c2c07d32f34b 100644 --- a/x-pack/metricbeat/module/airflow/statsd/data_test.go +++ b/x-pack/metricbeat/module/airflow/statsd/data_test.go @@ -8,8 +8,10 @@ import ( "fmt" "net" "runtime" + "sync" "testing" - "time" + + "github.com/elastic/beats/v7/x-pack/metricbeat/module/statsd/server" "github.com/stretchr/testify/require" @@ -36,7 +38,7 @@ func getConfig() map[string]interface{} { "host": STATSD_HOST, "port": STATSD_PORT, "period": "100ms", - "ttl": "0s", + "ttl": "1ms", } } @@ -58,12 +60,22 @@ func TestData(t *testing.T) { ms := mbtest.NewPushMetricSetV2(t, getConfig()) var events []mb.Event + var reporter mb.PushReporterV2 done := make(chan interface{}) - go func() { - events = mbtest.RunPushMetricSetV2(30*time.Second, 1, ms) + wg := new(sync.WaitGroup) + wg.Add(1) + go func(wg *sync.WaitGroup) { + reporter = mbtest.GetCapturingPushReporterV2() + ms.(*server.MetricSet).ServerStart() + wg.Done() + + go ms.Run(reporter) + events = reporter.(*mbtest.CapturingPushReporterV2).BlockingCapture(1) + close(done) - }() + }(wg) + wg.Wait() createEvent(t) <-done diff --git a/x-pack/metricbeat/module/statsd/server/server.go b/x-pack/metricbeat/module/statsd/server/server.go index b9df691b6b88..a32129910fee 100644 --- a/x-pack/metricbeat/module/statsd/server/server.go +++ b/x-pack/metricbeat/module/statsd/server/server.go @@ -71,9 +71,10 @@ func defaultConfig() Config { // multiple fetch calls. type MetricSet struct { mb.BaseMetricSet - server serverhelper.Server - processor *metricProcessor - mappings map[string]StatsdMapping + server serverhelper.Server + serverStarted bool + processor *metricProcessor + mappings map[string]StatsdMapping } // New create a new instance of the MetricSet @@ -191,13 +192,32 @@ func (m *MetricSet) getEvents() []*mb.Event { return events } +// ServerStart starts the underlying m.server +func (m *MetricSet) ServerStart() { + if m.serverStarted { + return + } + m.server.Start() + m.serverStarted = true +} + +// ServerStop stops the underlying m.server +func (m *MetricSet) ServerStop() { + if !m.serverStarted { + return + } + + m.server.Stop() + m.serverStarted = false +} + // Run method provides the module with a reporter with which events can be reported. func (m *MetricSet) Run(reporter mb.PushReporterV2) { period := m.Module().Config().Period // Start event watcher - m.server.Start() - defer m.server.Stop() + m.ServerStart() + defer m.ServerStop() reportPeriod := time.NewTicker(period) for { From 5648bc10edd5ce45ed49c072ad2ba3ebbe3b6c8c Mon Sep 17 00:00:00 2001 From: Michael Katsoulis Date: Tue, 21 Dec 2021 16:55:48 +0200 Subject: [PATCH 117/172] Populate container.id field in container metricset (#29560) * Populate container.id field in container metricset --- CHANGELOG.next.asciidoc | 1 + metricbeat/module/kubernetes/util/kubernetes.go | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9c736fd6c64c..9e28195c4aba 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -145,6 +145,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Preliminary AIX support {pull}27954[27954] - Add option to skip older k8s events {pull}29396[29396] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] +- Add `container.id` and `container.runtime` ECS fields in container metricset. {pull}29560[29560] - Add `memory.workingset.limit.pct` field in Kubernetes container/pod metricset. {pull}29547[29547] *Packetbeat* diff --git a/metricbeat/module/kubernetes/util/kubernetes.go b/metricbeat/module/kubernetes/util/kubernetes.go index b173c6de3600..56e9684eee3a 100644 --- a/metricbeat/module/kubernetes/util/kubernetes.go +++ b/metricbeat/module/kubernetes/util/kubernetes.go @@ -198,6 +198,14 @@ func NewContainerMetadataEnricher( pod := r.(*kubernetes.Pod) meta := metaGen.Generate(pod) + statuses := make(map[string]*kubernetes.PodContainerStatus) + mapStatuses := func(s []kubernetes.PodContainerStatus) { + for i := range s { + statuses[s[i].Name] = &s[i] + } + } + mapStatuses(pod.Status.ContainerStatuses) + mapStatuses(pod.Status.InitContainerStatuses) for _, container := range append(pod.Spec.Containers, pod.Spec.InitContainers...) { cuid := ContainerUID(pod.GetObjectMeta().GetNamespace(), pod.GetObjectMeta().GetName(), container.Name) @@ -213,6 +221,15 @@ func NewContainerMetadataEnricher( } } + if s, ok := statuses[container.Name]; ok { + // Extracting id and runtime ECS fields from ContainerID + // which is in the form of :// + split := strings.Index(s.ContainerID, "://") + if split != -1 { + meta.Put("container.id", s.ContainerID[split+3:]) + meta.Put("container.runtime", s.ContainerID[:split]) + } + } id := join(pod.GetObjectMeta().GetNamespace(), pod.GetObjectMeta().GetName(), container.Name) m[id] = meta } From 76bf18b0c2be4c8adf1f2a0f9168aadcd04e8593 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 21 Dec 2021 10:50:42 -0800 Subject: [PATCH 118/172] Update monitoring-internal-collection.asciidoc (#27624) (#29551) just to add a clear description regarding cluster_uuid Co-authored-by: Daisuke Harada <1519063+dharada@users.noreply.github.com> --- libbeat/docs/monitoring/monitoring-internal-collection.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbeat/docs/monitoring/monitoring-internal-collection.asciidoc b/libbeat/docs/monitoring/monitoring-internal-collection.asciidoc index 3263777c9f4a..f626ed93a3cc 100644 --- a/libbeat/docs/monitoring/monitoring-internal-collection.asciidoc +++ b/libbeat/docs/monitoring/monitoring-internal-collection.asciidoc @@ -85,7 +85,7 @@ monitoring: <1> This setting identifies the {es} cluster under which the monitoring data for this {beatname_uc} instance will appear in the Stack Monitoring UI. To get a cluster's `cluster_uuid`, -call the `GET /` API against that cluster. +call the `GET /` API against that production cluster. <2> This setting identifies the hosts and port numbers of {es} nodes that are part of the monitoring cluster. <3> Specify one of `api_key` or `username`/`password`. From 391a948ec15e55735367429bec81c22c539a444a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Wed, 22 Dec 2021 12:06:50 +0100 Subject: [PATCH 119/172] Follow up changes in documentation after #28927 (#29501) * Follow up changes in the docs for logging * add reference configuration --- auditbeat/auditbeat.reference.yml | 3 ++- filebeat/filebeat.reference.yml | 3 ++- heartbeat/heartbeat.reference.yml | 3 ++- libbeat/_meta/config/output-file.reference.yml.tmpl | 4 ++-- libbeat/outputs/fileout/docs/fileout.asciidoc | 3 ++- metricbeat/metricbeat.reference.yml | 3 ++- packetbeat/packetbeat.reference.yml | 3 ++- winlogbeat/winlogbeat.reference.yml | 3 ++- x-pack/auditbeat/auditbeat.reference.yml | 3 ++- x-pack/filebeat/filebeat.reference.yml | 3 ++- x-pack/heartbeat/heartbeat.reference.yml | 3 ++- x-pack/metricbeat/metricbeat.reference.yml | 3 ++- x-pack/packetbeat/packetbeat.reference.yml | 3 ++- x-pack/winlogbeat/winlogbeat.reference.yml | 3 ++- 14 files changed, 28 insertions(+), 15 deletions(-) diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 544cd80ade25..27be08dd194b 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -1057,7 +1057,7 @@ output.elasticsearch: #path: "/tmp/auditbeat" # Name of the generated files. The default is `auditbeat` and it generates - # files: `auditbeat`, `auditbeat.1`, `auditbeat.2`, etc. + # files: `auditbeat-{datetime}.ndjson`, `auditbeat-{datetime}-1.ndjson`, etc. #filename: auditbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1075,6 +1075,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index b63760c63dd4..912a8f9bcb62 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -1990,7 +1990,7 @@ output.elasticsearch: #path: "/tmp/filebeat" # Name of the generated files. The default is `filebeat` and it generates - # files: `filebeat`, `filebeat.1`, `filebeat.2`, etc. + # files: `filebeat-{datetime}.ndjson`, `filebeat-{datetime}-1.ndjson`, etc. #filename: filebeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -2008,6 +2008,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 76dcc7758b9e..aca74cd9e636 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -1203,7 +1203,7 @@ output.elasticsearch: #path: "/tmp/heartbeat" # Name of the generated files. The default is `heartbeat` and it generates - # files: `heartbeat`, `heartbeat.1`, `heartbeat.2`, etc. + # files: `heartbeat-{datetime}.ndjson`, `heartbeat-{datetime}-1.ndjson`, etc. #filename: heartbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1221,6 +1221,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/libbeat/_meta/config/output-file.reference.yml.tmpl b/libbeat/_meta/config/output-file.reference.yml.tmpl index 7f7ff9998b33..665b8f3a7c13 100644 --- a/libbeat/_meta/config/output-file.reference.yml.tmpl +++ b/libbeat/_meta/config/output-file.reference.yml.tmpl @@ -16,7 +16,7 @@ #path: "/tmp/{{.BeatName}}" # Name of the generated files. The default is `{{.BeatName}}` and it generates - # files: `{{.BeatName}}`, `{{.BeatName}}.1`, `{{.BeatName}}.2`, etc. + # files: `{{.BeatName}}-{datetime}.ndjson`, `{{.BeatName}}-{datetime}-1.ndjson`, etc. #filename: {{.BeatName}} # Maximum size in kilobytes of each file. When this size is reached, and on @@ -33,4 +33,4 @@ #permissions: 0600 # Configure automatic file rotation on every startup. The default is true. - #rotate_on_startup: true \ No newline at end of file + #rotate_on_startup: true diff --git a/libbeat/outputs/fileout/docs/fileout.asciidoc b/libbeat/outputs/fileout/docs/fileout.asciidoc index a0979f92ef56..f4dc7c5f95db 100644 --- a/libbeat/outputs/fileout/docs/fileout.asciidoc +++ b/libbeat/outputs/fileout/docs/fileout.asciidoc @@ -45,7 +45,8 @@ mandatory. ===== `filename` The name of the generated files. The default is set to the Beat name. For example, the files -generated by default for {beatname_uc} would be "{beatname_lc}", "{beatname_lc}.1", "{beatname_lc}.2", and so on. +generated by default for {beatname_uc} would be "{beatname_lc}-{{datetime}}.ndjson", "{beatname_lc}-{{datetime}}-1.ndjson", +"{beatname_lc}-{{datetime}}-2.ndjson", and so on. ===== `rotate_every_kb` diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index d0ef9b6f6d3e..2d4c51aea508 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -1920,7 +1920,7 @@ output.elasticsearch: #path: "/tmp/metricbeat" # Name of the generated files. The default is `metricbeat` and it generates - # files: `metricbeat`, `metricbeat.1`, `metricbeat.2`, etc. + # files: `metricbeat-{datetime}.ndjson`, `metricbeat-{datetime}-1.ndjson`, etc. #filename: metricbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1938,6 +1938,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 3d9d0f604bf7..739fe5c53324 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1552,7 +1552,7 @@ output.elasticsearch: #path: "/tmp/packetbeat" # Name of the generated files. The default is `packetbeat` and it generates - # files: `packetbeat`, `packetbeat.1`, `packetbeat.2`, etc. + # files: `packetbeat-{datetime}.ndjson`, `packetbeat-{datetime}-1.ndjson`, etc. #filename: packetbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1570,6 +1570,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 11a5ac82351c..51ca51897f8f 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -988,7 +988,7 @@ output.elasticsearch: #path: "/tmp/winlogbeat" # Name of the generated files. The default is `winlogbeat` and it generates - # files: `winlogbeat`, `winlogbeat.1`, `winlogbeat.2`, etc. + # files: `winlogbeat-{datetime}.ndjson`, `winlogbeat-{datetime}-1.ndjson`, etc. #filename: winlogbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1006,6 +1006,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index 5219627ac63c..b058641150cf 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -1113,7 +1113,7 @@ output.elasticsearch: #path: "/tmp/auditbeat" # Name of the generated files. The default is `auditbeat` and it generates - # files: `auditbeat`, `auditbeat.1`, `auditbeat.2`, etc. + # files: `auditbeat-{datetime}.ndjson`, `auditbeat-{datetime}-1.ndjson`, etc. #filename: auditbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1131,6 +1131,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 796d69340463..e65e6990c620 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -4220,7 +4220,7 @@ output.elasticsearch: #path: "/tmp/filebeat" # Name of the generated files. The default is `filebeat` and it generates - # files: `filebeat`, `filebeat.1`, `filebeat.2`, etc. + # files: `filebeat-{datetime}.ndjson`, `filebeat-{datetime}-1.ndjson`, etc. #filename: filebeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -4238,6 +4238,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index 76dcc7758b9e..aca74cd9e636 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -1203,7 +1203,7 @@ output.elasticsearch: #path: "/tmp/heartbeat" # Name of the generated files. The default is `heartbeat` and it generates - # files: `heartbeat`, `heartbeat.1`, `heartbeat.2`, etc. + # files: `heartbeat-{datetime}.ndjson`, `heartbeat-{datetime}-1.ndjson`, etc. #filename: heartbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1221,6 +1221,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index e09b1c7989b0..2c3a35d801be 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -2441,7 +2441,7 @@ output.elasticsearch: #path: "/tmp/metricbeat" # Name of the generated files. The default is `metricbeat` and it generates - # files: `metricbeat`, `metricbeat.1`, `metricbeat.2`, etc. + # files: `metricbeat-{datetime}.ndjson`, `metricbeat-{datetime}-1.ndjson`, etc. #filename: metricbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -2459,6 +2459,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index 3d9d0f604bf7..739fe5c53324 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -1552,7 +1552,7 @@ output.elasticsearch: #path: "/tmp/packetbeat" # Name of the generated files. The default is `packetbeat` and it generates - # files: `packetbeat`, `packetbeat.1`, `packetbeat.2`, etc. + # files: `packetbeat-{datetime}.ndjson`, `packetbeat-{datetime}-1.ndjson`, etc. #filename: packetbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1570,6 +1570,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 940cd6125a02..d74e971638a3 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -1031,7 +1031,7 @@ output.elasticsearch: #path: "/tmp/winlogbeat" # Name of the generated files. The default is `winlogbeat` and it generates - # files: `winlogbeat`, `winlogbeat.1`, `winlogbeat.2`, etc. + # files: `winlogbeat-{datetime}.ndjson`, `winlogbeat-{datetime}-1.ndjson`, etc. #filename: winlogbeat # Maximum size in kilobytes of each file. When this size is reached, and on @@ -1049,6 +1049,7 @@ output.elasticsearch: # Configure automatic file rotation on every startup. The default is true. #rotate_on_startup: true + # ------------------------------- Console Output ------------------------------- #output.console: # Boolean flag to enable or disable the output module. From 3a6bd25c4df97fdf6109df2e99cc157e4bd27a24 Mon Sep 17 00:00:00 2001 From: Craig MacKenzie Date: Wed, 22 Dec 2021 09:17:14 -0500 Subject: [PATCH 120/172] Save docker-compose logs from integration tests. (#29504) Save docker-compose logs from system and integration tests. Allows auditing service logs for issues, in particular it enabled auditing the elasticsearch logs for deprecation warnings. The docker log files are now saved under build/system-tests/docker-logs and preserved as artifacts in Jenkins. Co-authored-by: Victor Martinez --- Jenkinsfile | 1 + dev-tools/mage/integtest_docker.go | 40 ++++++++++++++++++++++++- dev-tools/mage/target/common/package.go | 8 +++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 04423d77b91b..0f8fbcf25964 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -702,6 +702,7 @@ def withBeatsEnv(Map args = [:], Closure body) { error("Error '${err.toString()}'") } finally { if (archive) { + archiveArtifacts(allowEmptyArchive: true, artifacts: "${directory}/build/system-tests/docker-logs/TEST-docker-compose-*.log") archiveTestOutput(directory: directory, testResults: testResults, artifacts: artifacts, id: args.id, upload: upload) } tearDown() diff --git a/dev-tools/mage/integtest_docker.go b/dev-tools/mage/integtest_docker.go index e9767f684367..94d9288d1fa6 100644 --- a/dev-tools/mage/integtest_docker.go +++ b/dev-tools/mage/integtest_docker.go @@ -81,7 +81,7 @@ func (d *DockerIntegrationTester) StepRequirements() IntegrationTestSteps { } // Test performs the tests with docker-compose. -func (d *DockerIntegrationTester) Test(_ string, mageTarget string, env map[string]string) error { +func (d *DockerIntegrationTester) Test(dir string, mageTarget string, env map[string]string) error { var err error d.buildImagesOnce.Do(func() { err = dockerComposeBuildImages() }) if err != nil { @@ -139,6 +139,12 @@ func (d *DockerIntegrationTester) Test(_ string, mageTarget string, env map[stri args..., ) + err = saveDockerComposeLogs(dir, mageTarget, composeEnv) + if err != nil && testErr == nil { + // saving docker-compose logs failed but the test didn't. + return err + } + // Docker-compose rm is noisy. So only pass through stderr when in verbose. out := ioutil.Discard if mg.Verbose() { @@ -160,6 +166,38 @@ func (d *DockerIntegrationTester) Test(_ string, mageTarget string, env map[stri return testErr } +func saveDockerComposeLogs(rootDir string, mageTarget string, composeEnv map[string]string) error { + var ( + composeLogDir = filepath.Join(rootDir, "build", "system-tests", "docker-logs") + composeLogFileName = filepath.Join(composeLogDir, "TEST-docker-compose-"+mageTarget+".log") + ) + + if err := os.MkdirAll(composeLogDir, os.ModeDir|os.ModePerm); err != nil { + return fmt.Errorf("creating docker log dir: %w", err) + } + + composeLogFile, err := os.Create(composeLogFileName) + if err != nil { + return fmt.Errorf("creating docker log file: %w", err) + } + defer composeLogFile.Close() + + _, err = sh.Exec( + composeEnv, + composeLogFile, // stdout + composeLogFile, // stderr + "docker-compose", + "-p", dockerComposeProjectName(), + "logs", + "--no-color", + ) + if err != nil { + return fmt.Errorf("executing docker-compose logs: %w", err) + } + + return nil +} + // InsideTest performs the tests inside of environment. func (d *DockerIntegrationTester) InsideTest(test func() error) error { // Fix file permissions after test is done writing files as root. diff --git a/dev-tools/mage/target/common/package.go b/dev-tools/mage/target/common/package.go index e8849adb26d2..2054538df1f9 100644 --- a/dev-tools/mage/target/common/package.go +++ b/dev-tools/mage/target/common/package.go @@ -30,8 +30,10 @@ import ( func PackageSystemTests() error { excludeds := []string{".ci", ".git", ".github", "vendor", "dev-tools"} - // include run as it's the directory we want to compress - systemTestsDir := filepath.Join("build", "system-tests", "run") + // include run and docker-logs as they are the directories we want to compress + systemTestsDir := filepath.Join("build", "system-tests") + systemTestsRunDir := filepath.Join(systemTestsDir, "run") + systemTestsLogDir := filepath.Join(systemTestsDir, "docker-logs") files, err := devtools.FindFilesRecursive(func(path string, _ os.FileInfo) bool { base := filepath.Base(path) for _, excluded := range excludeds { @@ -40,7 +42,7 @@ func PackageSystemTests() error { } } - return strings.HasPrefix(path, systemTestsDir) + return strings.HasPrefix(path, systemTestsRunDir) || strings.HasPrefix(path, systemTestsLogDir) }) if err != nil { return err From 78e1c58aa905dd8122d4495948b27da3076bd46c Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 23 Dec 2021 13:55:28 +0000 Subject: [PATCH 121/172] Add support for latest k8s versions (#29575) --- .ci/scripts/kind-setup.sh | 20 +------------------ CHANGELOG.next.asciidoc | 1 + deploy/kubernetes/Jenkinsfile.yml | 2 +- metricbeat/docs/modules/kubernetes.asciidoc | 2 +- .../module/kubernetes/_meta/docs.asciidoc | 2 +- .../module/kubernetes/test/integration.go | 20 +++++++++++-------- 6 files changed, 17 insertions(+), 30 deletions(-) diff --git a/.ci/scripts/kind-setup.sh b/.ci/scripts/kind-setup.sh index d2c9eeeb7712..fa4f66dd6e69 100755 --- a/.ci/scripts/kind-setup.sh +++ b/.ci/scripts/kind-setup.sh @@ -1,23 +1,5 @@ #!/usr/bin/env bash set -exuo pipefail -kind create cluster --image kindest/node:${K8S_VERSION} --config - < Date: Thu, 23 Dec 2021 14:59:31 +0100 Subject: [PATCH 122/172] elasticsearch module - xpack enabled parity (#29548) * elasticsearch module - xpack enabled parity * flip ActiveOnly default * add ml_job's node * lint * update shard cluster's state path * add back state.id to prevent breaking changes --- .../module/elasticsearch/index_recovery/index_recovery.go | 2 +- metricbeat/module/elasticsearch/ml_job/_meta/data.json | 5 +++-- metricbeat/module/elasticsearch/ml_job/data.go | 7 ++++++- metricbeat/module/elasticsearch/shard/_meta/data.json | 7 ++++++- metricbeat/module/elasticsearch/shard/data.go | 2 ++ 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/metricbeat/module/elasticsearch/index_recovery/index_recovery.go b/metricbeat/module/elasticsearch/index_recovery/index_recovery.go index eb2eaf93bf65..5b5243de9f95 100644 --- a/metricbeat/module/elasticsearch/index_recovery/index_recovery.go +++ b/metricbeat/module/elasticsearch/index_recovery/index_recovery.go @@ -43,7 +43,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { config := struct { ActiveOnly bool `config:"index_recovery.active_only"` }{ - ActiveOnly: true, + ActiveOnly: false, } if err := base.Module().UnpackConfig(&config); err != nil { return nil, err diff --git a/metricbeat/module/elasticsearch/ml_job/_meta/data.json b/metricbeat/module/elasticsearch/ml_job/_meta/data.json index 0e79d5bad911..6a5e73f48f30 100644 --- a/metricbeat/module/elasticsearch/ml_job/_meta/data.json +++ b/metricbeat/module/elasticsearch/ml_job/_meta/data.json @@ -22,7 +22,8 @@ } }, "node": { - "id": "27fb1c2fd783" + "id": "27fb1c2fd783", + "name": "node-1" } }, "event": { @@ -39,4 +40,4 @@ "name": "elasticsearch", "type": "elasticsearch" } -} \ No newline at end of file +} diff --git a/metricbeat/module/elasticsearch/ml_job/data.go b/metricbeat/module/elasticsearch/ml_job/data.go index 28c296e1e5f6..a23c2677f1b1 100644 --- a/metricbeat/module/elasticsearch/ml_job/data.go +++ b/metricbeat/module/elasticsearch/ml_job/data.go @@ -81,7 +81,12 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX event.ModuleFields = common.MapStr{} event.ModuleFields.Put("cluster.name", info.ClusterName) event.ModuleFields.Put("cluster.id", info.ClusterID) - event.ModuleFields.Put("node.id", info.Name) + + if node, exists := job["node"]; exists { + nodeHash := node.(map[string]interface{}) + event.ModuleFields.Put("node.id", nodeHash["id"]) + event.ModuleFields.Put("node.name", nodeHash["name"]) + } event.MetricSetFields, _ = schema.Apply(job) diff --git a/metricbeat/module/elasticsearch/shard/_meta/data.json b/metricbeat/module/elasticsearch/shard/_meta/data.json index b6278e225f50..e56708307e7f 100644 --- a/metricbeat/module/elasticsearch/shard/_meta/data.json +++ b/metricbeat/module/elasticsearch/shard/_meta/data.json @@ -6,6 +6,11 @@ "name": "docker-cluster", "state": { "id": "XNIdeSZxQwyItvGfR5fHSw" + }, + "stats": { + "state": { + "state_uuid": "XNIdeSZxQwyItvGfR5fHSw" + } } }, "index": { @@ -41,4 +46,4 @@ "address": "172.19.0.2:9200", "type": "elasticsearch" } -} \ No newline at end of file +} diff --git a/metricbeat/module/elasticsearch/shard/data.go b/metricbeat/module/elasticsearch/shard/data.go index 2dd2f93c023b..575be1d7184a 100644 --- a/metricbeat/module/elasticsearch/shard/data.go +++ b/metricbeat/module/elasticsearch/shard/data.go @@ -73,6 +73,7 @@ func eventsMapping(r mb.ReporterV2, content []byte, isXpack bool) error { } event.ModuleFields.Put("cluster.state.id", stateData.StateID) + event.ModuleFields.Put("cluster.stats.state.state_uuid", stateData.StateID) event.ModuleFields.Put("cluster.id", stateData.ClusterID) event.ModuleFields.Put("cluster.name", stateData.ClusterName) @@ -117,6 +118,7 @@ func eventsMapping(r mb.ReporterV2, content []byte, isXpack bool) error { errs = append(errs, errors.Wrap(err, "failure getting source node information")) continue } + event.ModuleFields.Put("node.name", sourceNode["name"]) event.MetricSetFields.Put("source_node", sourceNode) } From 9b19aaeaf0d03521c701c4f498ba3dacdfd94970 Mon Sep 17 00:00:00 2001 From: Tetiana Kravchenko Date: Thu, 23 Dec 2021 15:00:32 +0100 Subject: [PATCH 123/172] Align elastic-agent-standalone manifest with the kubernetes package changes (#29595) * align elastic-agent-standalone manifest with the managed version Signed-off-by: Tetiana Kravchenko * revetn docker image version Signed-off-by: Tetiana Kravchenko * remove ES_HOST used to run test locally Signed-off-by: Tetiana Kravchenko * set default values for container parser implicitly Signed-off-by: Tetiana Kravchenko * remove skip_older as it is a default value anyway Signed-off-by: Tetiana Kravchenko --- .../elastic-agent-standalone-kubernetes.yaml | 76 +++++++++++++++++-- ...-agent-standalone-daemonset-configmap.yaml | 76 +++++++++++++++++-- 2 files changed, 138 insertions(+), 14 deletions(-) diff --git a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml index 6b306051eb27..9f58ec9c4f33 100644 --- a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml +++ b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml @@ -32,7 +32,7 @@ data: meta: package: name: kubernetes - version: 0.2.8 + version: 1.9.0 data_stream: namespace: default streams: @@ -72,6 +72,15 @@ data: hosts: - 'kube-state-metrics:8080' period: 10s + - data_stream: + dataset: kubernetes.state_daemonset + type: metrics + metricsets: + - state_daemonset + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s - data_stream: dataset: kubernetes.state_deployment type: metrics @@ -214,20 +223,73 @@ data: fields: ecs.version: 1.12.0 - name: container-log - type: logfile + type: filestream use_output: default meta: package: - name: log - version: 0.4.6 + name: kubernetes + version: 1.9.0 data_stream: namespace: default streams: - data_stream: - dataset: generic - symlinks: true + dataset: kubernetes.container_logs + type: logs + prospector.scanner.symlinks: true + parsers: + - container: ~ + # - ndjson: + # target: json + # - multiline: + # type: pattern + # pattern: '^\[' + # negate: true + # match: after paths: - /var/log/containers/*${kubernetes.container.id}.log + - name: audit-log + type: filestream + use_output: default + meta: + package: + name: kubernetes + version: 1.9.0 + data_stream: + namespace: default + streams: + - data_stream: + dataset: kubernetes.audit_logs + type: logs + exclude_files: + - .gz$ + parsers: + - ndjson: + add_error_key: true + target: kubernetes_audit + paths: + - /var/log/kubernetes/kube-apiserver-audit.log + processors: + - rename: + fields: + - from: kubernetes_audit + to: kubernetes.audit + - script: + id: dedot_annotations + lang: javascript + source: | + function process(event) { + var audit = event.Get("kubernetes.audit"); + for (var annotation in audit["annotations"]) { + var annotation_dedoted = annotation.replace(/\./g,'_') + event.Rename("kubernetes.audit.annotations."+annotation, "kubernetes.audit.annotations."+annotation_dedoted) + } + return event; + } function test() { + var event = process(new Event({ "kubernetes": { "audit": { "annotations": { "authorization.k8s.io/decision": "allow", "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:kube-scheduler\" of ClusterRole \"system:kube-scheduler\" to User \"system:kube-scheduler\"" } } } })); + if (event.Get("kubernetes.audit.annotations.authorization_k8s_io/decision") !== "allow") { + throw "expected kubernetes.audit.annotations.authorization_k8s_io/decision === allow"; + } + } - name: system-metrics type: system/metrics use_output: default @@ -332,7 +394,7 @@ data: meta: package: name: kubernetes - version: 0.2.8 + version: 1.9.0 data_stream: namespace: default streams: diff --git a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset-configmap.yaml b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset-configmap.yaml index d3f290b2aabf..0ad4f6098835 100644 --- a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset-configmap.yaml +++ b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset-configmap.yaml @@ -32,7 +32,7 @@ data: meta: package: name: kubernetes - version: 0.2.8 + version: 1.9.0 data_stream: namespace: default streams: @@ -72,6 +72,15 @@ data: hosts: - 'kube-state-metrics:8080' period: 10s + - data_stream: + dataset: kubernetes.state_daemonset + type: metrics + metricsets: + - state_daemonset + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s - data_stream: dataset: kubernetes.state_deployment type: metrics @@ -214,20 +223,73 @@ data: fields: ecs.version: 1.12.0 - name: container-log - type: logfile + type: filestream use_output: default meta: package: - name: log - version: 0.4.6 + name: kubernetes + version: 1.9.0 data_stream: namespace: default streams: - data_stream: - dataset: generic - symlinks: true + dataset: kubernetes.container_logs + type: logs + prospector.scanner.symlinks: true + parsers: + - container: ~ + # - ndjson: + # target: json + # - multiline: + # type: pattern + # pattern: '^\[' + # negate: true + # match: after paths: - /var/log/containers/*${kubernetes.container.id}.log + - name: audit-log + type: filestream + use_output: default + meta: + package: + name: kubernetes + version: 1.9.0 + data_stream: + namespace: default + streams: + - data_stream: + dataset: kubernetes.audit_logs + type: logs + exclude_files: + - .gz$ + parsers: + - ndjson: + add_error_key: true + target: kubernetes_audit + paths: + - /var/log/kubernetes/kube-apiserver-audit.log + processors: + - rename: + fields: + - from: kubernetes_audit + to: kubernetes.audit + - script: + id: dedot_annotations + lang: javascript + source: | + function process(event) { + var audit = event.Get("kubernetes.audit"); + for (var annotation in audit["annotations"]) { + var annotation_dedoted = annotation.replace(/\./g,'_') + event.Rename("kubernetes.audit.annotations."+annotation, "kubernetes.audit.annotations."+annotation_dedoted) + } + return event; + } function test() { + var event = process(new Event({ "kubernetes": { "audit": { "annotations": { "authorization.k8s.io/decision": "allow", "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:kube-scheduler\" of ClusterRole \"system:kube-scheduler\" to User \"system:kube-scheduler\"" } } } })); + if (event.Get("kubernetes.audit.annotations.authorization_k8s_io/decision") !== "allow") { + throw "expected kubernetes.audit.annotations.authorization_k8s_io/decision === allow"; + } + } - name: system-metrics type: system/metrics use_output: default @@ -332,7 +394,7 @@ data: meta: package: name: kubernetes - version: 0.2.8 + version: 1.9.0 data_stream: namespace: default streams: From bea8e454ea289e28ea260a8c88e7997364da2a75 Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Thu, 23 Dec 2021 09:22:28 -0800 Subject: [PATCH 124/172] Remove references to username/password (#29458) * Remove references to username/password * restore ouput username/password * Update CHANGELOG --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../_meta/config/common.p2.yml.tmpl | 8 +-- .../_meta/config/common.reference.p2.yml.tmpl | 8 +-- .../config/elastic-agent.docker.yml.tmpl | 3 +- x-pack/elastic-agent/_meta/elastic-agent.yml | 3 +- x-pack/elastic-agent/elastic-agent.docker.yml | 3 +- .../elastic-agent/elastic-agent.reference.yml | 8 +-- x-pack/elastic-agent/elastic-agent.yml | 8 +-- .../elastic-agent/pkg/agent/cmd/container.go | 17 +---- .../pkg/agent/cmd/enroll_cmd_test.go | 6 -- .../pkg/agent/cmd/setup_config.go | 8 --- .../pkg/agent/configuration/fleet_server.go | 17 +---- x-pack/elastic-agent/pkg/remote/client.go | 14 ---- .../elastic-agent/pkg/remote/client_test.go | 65 ------------------- x-pack/elastic-agent/pkg/remote/config.go | 9 --- .../elastic-agent/pkg/remote/config_test.go | 2 - .../pkg/remote/round_trippers.go | 30 --------- 17 files changed, 24 insertions(+), 186 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 374c63acdb05..8164397c26eb 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -14,6 +14,7 @@ - Default to port 80 and 443 for Kibana and Fleet Server connections. {pull}25723[25723] - Remove deprecated/undocumented IncludeCreatorMetadata setting from kubernetes metadata config options {pull}28006[28006] - The `/processes/` endpoint proxies to the subprocess's monitoring endpoint, instead of querying its `/stats` endpoint {pull}28165[28165] +- Remove username/password for fleet-server authentication. {pull}29458[29458] ==== Bugfixes - Fix rename *ConfigChange to *PolicyChange to align on changes in the UI. {pull}20779[20779] diff --git a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl index e8f4c31e8e18..bbadcdc1055f 100644 --- a/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.p2.yml.tmpl @@ -5,8 +5,9 @@ outputs: default: type: elasticsearch hosts: [127.0.0.1:9200] - username: elastic - password: changeme + api-key: "example-key" + # username: "elastic" + # password: "changeme" inputs: - type: system/metrics @@ -74,8 +75,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "example-token" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl index 8a3ef0773578..bfb84102e3ca 100644 --- a/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/common.reference.p2.yml.tmpl @@ -5,8 +5,9 @@ outputs: default: type: elasticsearch hosts: [127.0.0.1:9200] - username: elastic - password: changeme + api-key: "example-key" + # username: "elastic" + # password: "changeme" inputs: - type: system/metrics @@ -43,8 +44,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "example-token" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl index 17201aa6dcea..b039db330912 100644 --- a/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl +++ b/x-pack/elastic-agent/_meta/config/elastic-agent.docker.yml.tmpl @@ -43,8 +43,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "${FLEET_SERVER_SERVICE_TOKEN}" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/_meta/elastic-agent.yml b/x-pack/elastic-agent/_meta/elastic-agent.yml index 493887180138..7c24af477d24 100644 --- a/x-pack/elastic-agent/_meta/elastic-agent.yml +++ b/x-pack/elastic-agent/_meta/elastic-agent.yml @@ -43,8 +43,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "example-token" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/elastic-agent.docker.yml b/x-pack/elastic-agent/elastic-agent.docker.yml index b7d5ff2017ea..91148cee08e6 100644 --- a/x-pack/elastic-agent/elastic-agent.docker.yml +++ b/x-pack/elastic-agent/elastic-agent.docker.yml @@ -43,8 +43,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "${FLEET_SERVER_SERVICE_TOKEN}" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/elastic-agent.reference.yml b/x-pack/elastic-agent/elastic-agent.reference.yml index da04df95ea81..7770b036dbaa 100644 --- a/x-pack/elastic-agent/elastic-agent.reference.yml +++ b/x-pack/elastic-agent/elastic-agent.reference.yml @@ -11,8 +11,9 @@ outputs: default: type: elasticsearch hosts: [127.0.0.1:9200] - username: elastic - password: changeme + api-key: "example-key" + # username: "elastic" + # password: "changeme" inputs: - type: system/metrics @@ -49,8 +50,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "example-token" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/elastic-agent.yml b/x-pack/elastic-agent/elastic-agent.yml index 802df992ba7c..d2cfa19d3847 100644 --- a/x-pack/elastic-agent/elastic-agent.yml +++ b/x-pack/elastic-agent/elastic-agent.yml @@ -11,8 +11,9 @@ outputs: default: type: elasticsearch hosts: [127.0.0.1:9200] - username: elastic - password: changeme + api-key: "example-key" + # username: "elastic" + # password: "changeme" inputs: - type: system/metrics @@ -80,8 +81,7 @@ inputs: # # optional values # #protocol: "https" -# #username: "elastic" -# #password: "changeme" +# #service_token: "example-token" # #path: "" # #ssl.verification_mode: full # #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index d72b0128430e..f127d972bf10 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -79,8 +79,6 @@ The following actions are possible and grouped based on the actions. The following vars are need in the scenario that Elastic Agent should automatically fetch its own token. KIBANA_FLEET_HOST - kibana host to enable create enrollment token on [$KIBANA_HOST] - KIBANA_FLEET_USERNAME - kibana username to create enrollment token [$KIBANA_USERNAME] - KIBANA_FLEET_PASSWORD - kibana password to create enrollment token [$KIBANA_PASSWORD] FLEET_TOKEN_NAME - token name to use for fetching token from Kibana. This requires Kibana configs to be set. FLEET_TOKEN_POLICY_NAME - token policy name to use for fetching token from Kibana. This requires Kibana configs to be set. @@ -93,8 +91,6 @@ The following actions are possible and grouped based on the actions. FLEET_SERVER_ENABLE - set to 1 enables bootstrapping of Fleet Server inside Elastic Agent (forces FLEET_ENROLL enabled) FLEET_SERVER_ELASTICSEARCH_HOST - elasticsearch host for Fleet Server to communicate with [$ELASTICSEARCH_HOST] - FLEET_SERVER_ELASTICSEARCH_USERNAME - elasticsearch username for Fleet Server [$ELASTICSEARCH_USERNAME] - FLEET_SERVER_ELASTICSEARCH_PASSWORD - elasticsearch password for Fleet Server [$ELASTICSEARCH_PASSWORD] FLEET_SERVER_ELASTICSEARCH_CA - path to certificate authority to use with communicate with elasticsearch [$ELASTICSEARCH_CA] FLEET_SERVER_ELASTICSEARCH_CA_TRUSTED_FINGERPRINT - The sha-256 fingerprint value of the certificate authority to trust FLEET_SERVER_ELASTICSEARCH_INSECURE - disables cert validation for communication with Elasticsearch @@ -113,8 +109,6 @@ The following actions are possible and grouped based on the actions. KIBANA_FLEET_SETUP - set to 1 enables the setup of Fleet in Kibana by Elastic Agent. This was previously FLEET_SETUP. KIBANA_FLEET_HOST - Kibana host accessible from fleet-server. [$KIBANA_HOST] - KIBANA_FLEET_USERNAME - kibana username to enable Fleet [$KIBANA_USERNAME] - KIBANA_FLEET_PASSWORD - kibana password to enable Fleet [$KIBANA_PASSWORD] KIBANA_FLEET_CA - path to certificate authority to use with communicate with Kibana [$KIBANA_CA] KIBANA_REQUEST_RETRY_SLEEP - specifies sleep duration taken when agent performs a request to kibana [default 1s] KIBANA_REQUEST_RETRY_COUNT - specifies number of retries agent performs when executing a request to kibana [default 30] @@ -123,12 +117,8 @@ The following environment variables are provided as a convenience to prevent a l be used when the same credentials will be used across all the possible actions above. ELASTICSEARCH_HOST - elasticsearch host [http://elasticsearch:9200] - ELASTICSEARCH_USERNAME - elasticsearch username [elastic] - ELASTICSEARCH_PASSWORD - elasticsearch password [changeme] ELASTICSEARCH_CA - path to certificate authority to use with communicate with elasticsearch KIBANA_HOST - kibana host [http://kibana:5601] - KIBANA_USERNAME - kibana username [$ELASTICSEARCH_USERNAME] - KIBANA_PASSWORD - kibana password [$ELASTICSEARCH_PASSWORD] KIBANA_CA - path to certificate authority to use with communicate with Kibana [$ELASTICSEARCH_CA] @@ -427,10 +417,7 @@ func buildFleetServerConnStr(cfg fleetServerConfig) (string, error) { if u.Path != "" { path += "/" + strings.TrimLeft(u.Path, "/") } - if cfg.Elasticsearch.ServiceToken != "" { - return fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, path), nil - } - return fmt.Sprintf("%s://%s:%s@%s%s", u.Scheme, cfg.Elasticsearch.Username, cfg.Elasticsearch.Password, u.Host, path), nil + return fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, path), nil } func kibanaSetup(cfg setupConfig, client *kibana.Client, streams *cli.IOStreams) error { @@ -485,8 +472,6 @@ func kibanaClient(cfg kibanaConfig, headers map[string]string) (*kibana.Client, return kibana.NewClientWithConfigDefault(&kibana.ClientConfig{ Host: cfg.Fleet.Host, - Username: cfg.Fleet.Username, - Password: cfg.Fleet.Password, ServiceToken: cfg.Fleet.ServiceToken, IgnoreVersion: true, Transport: transport, diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd_test.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd_test.go index d58202753716..17bcbcedd25f 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd_test.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd_test.go @@ -157,8 +157,6 @@ func TestEnroll(t *testing.T) { require.NoError(t, err) require.Equal(t, "my-access-api-key", config.AccessAPIKey) require.Equal(t, host, config.Client.Host) - require.Equal(t, "", config.Client.Username) - require.Equal(t, "", config.Client.Password) }, )) @@ -217,8 +215,6 @@ func TestEnroll(t *testing.T) { require.NoError(t, err) require.Equal(t, "my-access-api-key", config.AccessAPIKey) require.Equal(t, host, config.Client.Host) - require.Equal(t, "", config.Client.Username) - require.Equal(t, "", config.Client.Password) }, )) @@ -277,8 +273,6 @@ func TestEnroll(t *testing.T) { require.NoError(t, err) require.Equal(t, "my-access-api-key", config.AccessAPIKey) require.Equal(t, host, config.Client.Host) - require.Equal(t, "", config.Client.Username) - require.Equal(t, "", config.Client.Password) }, )) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go index b33c0f8fa8ee..39cf43de28c2 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go @@ -43,8 +43,6 @@ type elasticsearchConfig struct { CA string `config:"ca"` CATrustedFingerprint string `config:"ca_trusted_fingerprint"` Host string `config:"host"` - Username string `config:"username"` - Password string `config:"password"` ServiceToken string `config:"service_token"` Insecure bool `config:"insecure"` } @@ -59,9 +57,7 @@ type kibanaConfig struct { type kibanaFleetConfig struct { CA string `config:"ca"` Host string `config:"host"` - Password string `config:"password"` Setup bool `config:"setup"` - Username string `config:"username"` ServiceToken string `config:"service_token"` } @@ -93,8 +89,6 @@ func defaultAccessConfig() (setupConfig, error) { CertKey: envWithDefault("", "FLEET_SERVER_CERT_KEY"), Elasticsearch: elasticsearchConfig{ Host: envWithDefault("http://elasticsearch:9200", "FLEET_SERVER_ELASTICSEARCH_HOST", "ELASTICSEARCH_HOST"), - Username: envWithDefault("elastic", "FLEET_SERVER_ELASTICSEARCH_USERNAME", "ELASTICSEARCH_USERNAME"), - Password: envWithDefault("changeme", "FLEET_SERVER_ELASTICSEARCH_PASSWORD", "ELASTICSEARCH_PASSWORD"), ServiceToken: envWithDefault("", "FLEET_SERVER_SERVICE_TOKEN"), CA: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA", "ELASTICSEARCH_CA"), CATrustedFingerprint: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA_TRUSTED_FINGERPRINT"), @@ -115,8 +109,6 @@ func defaultAccessConfig() (setupConfig, error) { // reflect that its setting up Fleet in Kibana versus setting up Fleet Server. Setup: envBool("KIBANA_FLEET_SETUP", "FLEET_SETUP"), Host: envWithDefault("http://kibana:5601", "KIBANA_FLEET_HOST", "KIBANA_HOST"), - Username: envWithDefault("elastic", "KIBANA_FLEET_USERNAME", "KIBANA_USERNAME", "ELASTICSEARCH_USERNAME"), - Password: envWithDefault("changeme", "KIBANA_FLEET_PASSWORD", "KIBANA_PASSWORD", "ELASTICSEARCH_PASSWORD"), ServiceToken: envWithDefault("", "KIBANA_FLEET_SERVICE_TOKEN", "FLEET_SERVER_SERVICE_TOKEN"), CA: envWithDefault("", "KIBANA_FLEET_CA", "KIBANA_CA", "ELASTICSEARCH_CA"), }, diff --git a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go index 425d899a55b3..5a4e135afae5 100644 --- a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go +++ b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go @@ -37,8 +37,6 @@ type Elasticsearch struct { Protocol string `config:"protocol" yaml:"protocol"` Hosts []string `config:"hosts" yaml:"hosts"` Path string `config:"path" yaml:"path,omitempty"` - Username string `config:"username" yaml:"username,omitempty"` - Password string `config:"password" yaml:"password,omitempty"` ServiceToken string `config:"service_token" yaml:"service_token,omitempty"` TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` Headers map[string]string `config:"headers" yaml:"headers,omitempty"` @@ -70,18 +68,9 @@ func ElasticsearchFromConnStr(conn string, serviceToken string, insecure bool) ( VerificationMode: tlscommon.VerifyNone, } } - if serviceToken != "" { - cfg.ServiceToken = serviceToken - return cfg, nil + if serviceToken == "" { + return Elasticsearch{}, errors.New("invalid connection string: must include a service token") } - if u.User == nil || u.User.Username() == "" { - return Elasticsearch{}, errors.New("invalid connection string: must include a username unless a service token is provided") - } - password, ok := u.User.Password() - if !ok { - return Elasticsearch{}, errors.New("invalid connection string: must include a password unless a service token is provided") - } - cfg.Username = u.User.Username() - cfg.Password = password + cfg.ServiceToken = serviceToken return cfg, nil } diff --git a/x-pack/elastic-agent/pkg/remote/client.go b/x-pack/elastic-agent/pkg/remote/client.go index 19e1da1dbb8f..23f6162c08e3 100644 --- a/x-pack/elastic-agent/pkg/remote/client.go +++ b/x-pack/elastic-agent/pkg/remote/client.go @@ -60,19 +60,10 @@ func NewConfigFromURL(kURL string) (Config, error) { return Config{}, errors.Wrap(err, "could not parse url") } - var username, password string - if u.User != nil { - username = u.User.Username() - // _ is true when password is set. - password, _ = u.User.Password() - } - c := DefaultClientConfig() c.Protocol = Protocol(u.Scheme) c.Host = u.Host c.Path = u.Path - c.Username = username - c.Password = password return c, nil } @@ -126,11 +117,6 @@ func NewWithConfig(log *logger.Logger, cfg Config, wrapper wrapperFunc) (*Client return nil, err } - if cfg.IsBasicAuth() { - // Pass basic auth credentials to all the underlying calls. - transport = NewBasicAuthRoundTripper(transport, cfg.Username, cfg.Password) - } - if wrapper != nil { transport, err = wrapper(transport) if err != nil { diff --git a/x-pack/elastic-agent/pkg/remote/client_test.go b/x-pack/elastic-agent/pkg/remote/client_test.go index a48ebe82daf1..ef8a5f0d626b 100644 --- a/x-pack/elastic-agent/pkg/remote/client_test.go +++ b/x-pack/elastic-agent/pkg/remote/client_test.go @@ -160,58 +160,6 @@ func TestHTTPClient(t *testing.T) { }, )) - t.Run("Basic auth when credentials are valid", withServer( - func(t *testing.T) *http.ServeMux { - msg := `{ message: "hello" }` - mux := http.NewServeMux() - mux.HandleFunc("/echo-hello", basicAuthHandler(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, msg) - }, "hello", "world", "testing")) - return mux - }, func(t *testing.T, host string) { - cfg := config.MustNewConfigFrom(map[string]interface{}{ - "username": "hello", - "password": "world", - "host": host, - }) - - client, err := NewWithRawConfig(nil, cfg, nil) - require.NoError(t, err) - resp, err := client.Send(ctx, "GET", "/echo-hello", nil, nil, nil) - require.NoError(t, err) - - body, err := ioutil.ReadAll(resp.Body) - require.NoError(t, err) - defer resp.Body.Close() - assert.Equal(t, `{ message: "hello" }`, string(body)) - }, - )) - - t.Run("Basic auth when credentials are invalid", withServer( - func(t *testing.T) *http.ServeMux { - msg := `{ message: "hello" }` - mux := http.NewServeMux() - mux.HandleFunc("/echo-hello", basicAuthHandler(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, msg) - }, "hello", "world", "testing")) - return mux - }, func(t *testing.T, host string) { - cfg := config.MustNewConfigFrom(map[string]interface{}{ - "username": "bye", - "password": "world", - "host": host, - }) - - client, err := NewWithRawConfig(nil, cfg, nil) - require.NoError(t, err) - resp, err := client.Send(ctx, "GET", "/echo-hello", nil, nil, nil) - require.NoError(t, err) - assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) - }, - )) - t.Run("Custom user agent", withServer( func(t *testing.T) *http.ServeMux { msg := `{ message: "hello" }` @@ -400,19 +348,6 @@ func withServer(m func(t *testing.T) *http.ServeMux, test func(t *testing.T, hos } } -func basicAuthHandler(handler http.HandlerFunc, username, password, realm string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - u, p, ok := r.BasicAuth() - - if !ok || u != username || p != password { - w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - handler(w, r) - } -} - type debugStack struct { sync.Mutex messages []string diff --git a/x-pack/elastic-agent/pkg/remote/config.go b/x-pack/elastic-agent/pkg/remote/config.go index 31ae29f70bad..495f850f5bc8 100644 --- a/x-pack/elastic-agent/pkg/remote/config.go +++ b/x-pack/elastic-agent/pkg/remote/config.go @@ -15,8 +15,6 @@ import ( type Config struct { Protocol Protocol `config:"protocol" yaml:"protocol"` SpaceID string `config:"space.id" yaml:"space.id,omitempty"` - Username string `config:"username" yaml:"username,omitempty"` - Password string `config:"password" yaml:"password,omitempty"` Path string `config:"path" yaml:"path,omitempty"` Host string `config:"host" yaml:"host,omitempty"` Hosts []string `config:"hosts" yaml:"hosts,omitempty"` @@ -55,17 +53,10 @@ func DefaultClientConfig() Config { Host: "localhost:5601", Path: "", SpaceID: "", - Username: "", - Password: "", Transport: transport, } } -// IsBasicAuth returns true if the username and password are both defined. -func (c *Config) IsBasicAuth() bool { - return len(c.Username) > 0 && len(c.Password) > 0 -} - // GetHosts returns the hosts to connect. // // This looks first at `Hosts` and then at `Host` when `Hosts` is not defined. diff --git a/x-pack/elastic-agent/pkg/remote/config_test.go b/x-pack/elastic-agent/pkg/remote/config_test.go index 403609735ddc..5a71cb9b6cdc 100644 --- a/x-pack/elastic-agent/pkg/remote/config_test.go +++ b/x-pack/elastic-agent/pkg/remote/config_test.go @@ -21,8 +21,6 @@ func TestPackUnpack(t *testing.T) { c := Config{ Protocol: Protocol("https"), SpaceID: "123", - Username: "foo", - Password: "bar", Path: "/ok", Transport: httpcommon.HTTPTransportSettings{ Timeout: 10 * time.Second, diff --git a/x-pack/elastic-agent/pkg/remote/round_trippers.go b/x-pack/elastic-agent/pkg/remote/round_trippers.go index 8c5b86f45ca2..e6583af57a84 100644 --- a/x-pack/elastic-agent/pkg/remote/round_trippers.go +++ b/x-pack/elastic-agent/pkg/remote/round_trippers.go @@ -123,36 +123,6 @@ func NewDebugRoundTripper(wrapped http.RoundTripper, log debugLogger) http.Round return &DebugRoundTripper{rt: wrapped, log: log} } -// BasicAuthRoundTripper wraps any request using a basic auth. -type BasicAuthRoundTripper struct { - rt http.RoundTripper - username string - password string -} - -// RoundTrip add username and password on every request send to the remove service. -func (r *BasicAuthRoundTripper) RoundTrip( - req *http.Request, -) (*http.Response, error) { - // if we already have authorization set on the request we do not force our username, password. - const key = "Authorization" - - if len(req.Header.Get(key)) > 0 { - return r.rt.RoundTrip(req) - } - - req.SetBasicAuth(r.username, r.password) - return r.rt.RoundTrip(req) -} - -// NewBasicAuthRoundTripper returns a Basic Auth round tripper. -func NewBasicAuthRoundTripper( - wrapped http.RoundTripper, - username, password string, -) http.RoundTripper { - return &BasicAuthRoundTripper{rt: wrapped, username: username, password: password} -} - func prettyBody(data []byte) []byte { var pretty bytes.Buffer From 77d59694597024d959024d928396be103deb5ad7 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Sun, 26 Dec 2021 16:03:36 -0600 Subject: [PATCH 125/172] [Filebeat] httpjson - Add function to return User-Agent #29453 (#29528) Adds a new value template function for the httpjson input to generate/update the User Agent. --- CHANGELOG.next.asciidoc | 1 + libbeat/common/useragent/useragent.go | 25 +++++-- libbeat/common/useragent/useragent_test.go | 3 + .../docs/inputs/input-httpjson.asciidoc | 8 ++- x-pack/filebeat/input/httpjson/value_tpl.go | 19 ++++++ .../filebeat/input/httpjson/value_tpl_test.go | 66 +++++++++++++++++++ 6 files changed, 113 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 6183bdb2d8d7..0a7be0c25fa6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -137,6 +137,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support for parsers on journald input {pull}29070[29070] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] +- Add new `userAgent` and `beatInfo` template functions for httpjson input {pull}29528[29528] *Heartbeat* diff --git a/libbeat/common/useragent/useragent.go b/libbeat/common/useragent/useragent.go index fdff31c2dc15..a60533982ee1 100644 --- a/libbeat/common/useragent/useragent.go +++ b/libbeat/common/useragent/useragent.go @@ -18,17 +18,30 @@ package useragent import ( - "fmt" "runtime" + "strings" "github.com/elastic/beats/v7/libbeat/version" ) // UserAgent takes the capitalized name of the current beat and returns // an RFC compliant user agent string for that beat. -func UserAgent(beatNameCapitalized string) string { - return fmt.Sprintf("Elastic-%s/%s (%s; %s; %s; %s)", - beatNameCapitalized, - version.GetDefaultVersion(), runtime.GOOS, runtime.GOARCH, - version.Commit(), version.BuildTime()) +func UserAgent(beatNameCapitalized string, additionalComments ...string) string { + var builder strings.Builder + builder.WriteString("Elastic-" + beatNameCapitalized + "/" + version.GetDefaultVersion() + " ") + uaValues := []string{ + runtime.GOOS, + runtime.GOARCH, + version.Commit(), + version.BuildTime().String(), + } + for _, val := range additionalComments { + if val != "" { + uaValues = append(uaValues, val) + } + } + builder.WriteByte('(') + builder.WriteString(strings.Join(uaValues, "; ")) + builder.WriteByte(')') + return builder.String() } diff --git a/libbeat/common/useragent/useragent_test.go b/libbeat/common/useragent/useragent_test.go index d55f20dde4b9..9ca1951059f9 100644 --- a/libbeat/common/useragent/useragent_test.go +++ b/libbeat/common/useragent/useragent_test.go @@ -27,4 +27,7 @@ import ( func TestUserAgent(t *testing.T) { ua := UserAgent("FakeBeat") assert.Regexp(t, regexp.MustCompile("^Elastic-FakeBeat"), ua) + + ua2 := UserAgent("FakeBeat", "integration_name/1.2.3") + assert.Regexp(t, regexp.MustCompile("; integration_name\\/1\\.2\\.3\\)$"), ua2) } diff --git a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc index cbde7b8b831e..15860c458252 100644 --- a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc @@ -219,7 +219,9 @@ Some built-in helper functions are provided to work with the input state inside - `join`: joins a list using the specified separator. Example: `[[join .body.arr ","]]` - `sprintf`: formats according to a format specifier and returns the resulting string. Refer to https://pkg.go.dev/fmt#Sprintf[the Go docs] for usage. Example: `[[sprintf "%d:%q" 34 "quote this"]]` - `hmacBase64`: calculates the hmac signature of a list of strings concatenated together. Returns a base64 encoded signature. Supports sha1 or sha256. Example `[[hmac "sha256" "secret" "string1" "string2" (formatDate (now) "RFC1123")]]` -- `uuid`: returns a random UUID such as `a11e8780-e3e7-46d0-8e76-f66e75acf019` Example: `[[ uuid ]]` +- `uuid`: returns a random UUID such as `a11e8780-e3e7-46d0-8e76-f66e75acf019`. Example: `[[ uuid ]]` +- `userAgent`: generates the User Agent with optional additional values. If no arguments are provided, it will generate the default User Agent that is added to all requests by default. It is recommended to delete the existing User-Agent header before setting a new one. Example: `[[ userAgent "integration/1.2.3" ]]` would generate `Elastic-Filebeat/8.1.0 (darwin; amd64; 9b893e88cfe109e64638d65c58fd75c2ff695402; 2021-12-15 13:20:00 +0000 UTC; integration_name/1.2.3)` +- `beatInfo`: returns a map containing information about the Beat. Available keys in the map are `goos` (running operating system), `goarch` (running system architecture), `commit` (git commit of current build), `buildtime` (compile time of current build), `version` (version of current build). Example: `[[ beatInfo.version ]]` returns `{version}`. In addition to the provided functions, any of the native functions for https://golang.org/pkg/time/#Time[`time.Time`], https://golang.org/pkg/net/http/#Header[`http.Header`], and https://golang.org/pkg/net/url/#Values[`url.Values`] types can be used on the corresponding objects. Examples: `[[(now).Day]]`, `[[.last_response.header.Get "key"]]` @@ -290,8 +292,8 @@ The user used as part of the authentication flow. It is required for authenticat The password used as part of the authentication flow. It is required for authentication - grant type password. It is only available for provider `default`. -NOTE: user and password are required for grant_type password. If user and -password is not used then it will automatically use the `token_url` and +NOTE: user and password are required for grant_type password. If user and +password is not used then it will automatically use the `token_url` and `client credential` method. [float] diff --git a/x-pack/filebeat/input/httpjson/value_tpl.go b/x-pack/filebeat/input/httpjson/value_tpl.go index 95c95093e5fa..d2786b4ce76f 100644 --- a/x-pack/filebeat/input/httpjson/value_tpl.go +++ b/x-pack/filebeat/input/httpjson/value_tpl.go @@ -16,6 +16,7 @@ import ( "hash" "reflect" "regexp" + "runtime" "strconv" "strings" "text/template" @@ -23,7 +24,9 @@ import ( "github.com/google/uuid" + "github.com/elastic/beats/v7/libbeat/common/useragent" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/version" ) // we define custom delimiters to prevent issues when using template values as part of other Go templates. @@ -66,6 +69,8 @@ func (t *valueTpl) Unpack(in string) error { "sprintf": fmt.Sprintf, "hmacBase64": hmacStringBase64, "uuid": uuidString, + "userAgent": userAgentString, + "beatInfo": beatInfo, }). Delims(leftDelim, rightDelim). Parse(in) @@ -360,3 +365,17 @@ func join(v interface{}, sep string) string { // return the stringified single value return fmt.Sprint(v) } + +func userAgentString(values ...string) string { + return useragent.UserAgent("Filebeat", values...) +} + +func beatInfo() map[string]string { + return map[string]string{ + "goos": runtime.GOOS, + "goarch": runtime.GOARCH, + "commit": version.Commit(), + "buildtime": version.BuildTime().String(), + "version": version.GetDefaultVersion(), + } +} diff --git a/x-pack/filebeat/input/httpjson/value_tpl_test.go b/x-pack/filebeat/input/httpjson/value_tpl_test.go index ad6aab449de1..8c111ee78b69 100644 --- a/x-pack/filebeat/input/httpjson/value_tpl_test.go +++ b/x-pack/filebeat/input/httpjson/value_tpl_test.go @@ -6,13 +6,16 @@ package httpjson import ( "net/http" + "runtime" "testing" "time" "github.com/stretchr/testify/assert" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/useragent" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/version" ) func TestValueTpl(t *testing.T) { @@ -394,6 +397,69 @@ func TestValueTpl(t *testing.T) { expectedVal: "", expectedError: errEmptyTemplateResult.Error(), }, + { + name: "func userAgent no values", + value: `[[userAgent]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: useragent.UserAgent("Filebeat"), + }, + { + name: "func userAgent blank value", + value: `[[userAgent ""]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: useragent.UserAgent("Filebeat"), + }, + { + name: "func userAgent 1 value", + value: `[[userAgent "integration_name/1.2.3"]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: useragent.UserAgent("Filebeat", "integration_name/1.2.3"), + }, + { + name: "func userAgent 2 value", + value: `[[userAgent "integration_name/1.2.3" "test"]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: useragent.UserAgent("Filebeat", "integration_name/1.2.3", "test"), + }, + { + name: "func beatInfo GOOS", + value: `[[beatInfo.goos]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: runtime.GOOS, + }, + { + name: "func beatInfo Arch", + value: `[[beatInfo.goarch]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: runtime.GOARCH, + }, + { + name: "func beatInfo Commit", + value: `[[beatInfo.commit]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: version.Commit(), + }, + { + name: "func beatInfo Build Time", + value: `[[beatInfo.buildtime]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: version.BuildTime().String(), + }, + { + name: "func beatInfo Version", + value: `[[beatInfo.version]]`, + paramCtx: emptyTransformContext(), + paramTr: transformable{}, + expectedVal: version.GetDefaultVersion(), + }, } for _, tc := range cases { From 90dd16973b1d0e90c377de5b73a0967686691ced Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Mon, 27 Dec 2021 00:35:23 +0100 Subject: [PATCH 126/172] beat/kibana module - add {module}.elasticsearch.cluster.id property (#29577) * add elasticsearch.cluster.id property to beats state * add elasticsearch.cluster.id property to beats stats * fix test * lint * add missing reloads property * dont break earlier assumptions * remove trailing comma * update beats.stats fields * add updated fields doc * beat: update cluster.id path * kibana: update cluster.id path * mage fmt update * fix fields path * add missing map initialization * add changelog entry * fix pr number --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 21 +++++++++++ metricbeat/module/beat/_meta/fields.yml | 2 ++ metricbeat/module/beat/fields.go | 2 +- metricbeat/module/beat/state/_meta/data.json | 7 +++- metricbeat/module/beat/state/data.go | 5 ++- metricbeat/module/beat/stats/_meta/data.json | 10 ++++-- metricbeat/module/beat/stats/_meta/fields.yml | 2 ++ metricbeat/module/beat/stats/data.go | 16 +++++---- metricbeat/module/beat/stats/data_test.go | 4 ++- metricbeat/module/beat/stats/stats.go | 35 ++++++++++++++++++- metricbeat/module/kibana/_meta/fields.yml | 2 ++ metricbeat/module/kibana/fields.go | 2 +- metricbeat/module/kibana/stats/data.go | 2 +- 14 files changed, 96 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 0a7be0c25fa6..419b02cb29bb 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -149,6 +149,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] - Add `container.id` and `container.runtime` ECS fields in container metricset. {pull}29560[29560] - Add `memory.workingset.limit.pct` field in Kubernetes container/pod metricset. {pull}29547[29547] +- Add `elasticsearch.cluster.id` field to Beat and Kibana modules. {pull}29577[29577] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 2553dc415ed9..e1e256d0dc3d 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -7535,6 +7535,13 @@ type: keyword -- +*`beat.elasticsearch.cluster.id`*:: ++ +-- +type: keyword + +-- + [float] === state @@ -8707,6 +8714,13 @@ type: short -- +*`beat.stats.libbeat.config.reloads`*:: ++ +-- +type: short + +-- + [float] === output @@ -40648,6 +40662,13 @@ alias to: service.id -- +*`kibana.elasticsearch.cluster.id`*:: ++ +-- +type: keyword + +-- + [float] === settings diff --git a/metricbeat/module/beat/_meta/fields.yml b/metricbeat/module/beat/_meta/fields.yml index b29bffb2cfa2..8cb1de91166b 100644 --- a/metricbeat/module/beat/_meta/fields.yml +++ b/metricbeat/module/beat/_meta/fields.yml @@ -634,3 +634,5 @@ type: keyword description: > Beat type. + - name: elasticsearch.cluster.id + type: keyword diff --git a/metricbeat/module/beat/fields.go b/metricbeat/module/beat/fields.go index 03105135aaad..4948b3e3346e 100644 --- a/metricbeat/module/beat/fields.go +++ b/metricbeat/module/beat/fields.go @@ -32,5 +32,5 @@ func init() { // AssetBeat returns asset data. // This is the base64 encoded zlib format compressed contents of module/beat. func AssetBeat() string { - return "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" + return "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" } diff --git a/metricbeat/module/beat/state/_meta/data.json b/metricbeat/module/beat/state/_meta/data.json index 6e85c8a30185..627b84f32edf 100644 --- a/metricbeat/module/beat/state/_meta/data.json +++ b/metricbeat/module/beat/state/_meta/data.json @@ -1,6 +1,11 @@ { "@timestamp": "2017-10-12T08:05:34.853Z", "beat": { + "elasticsearch": { + "cluster": { + "id": "foobar" + } + }, "state": { "beat": { "host": "2963d991095f", @@ -58,4 +63,4 @@ "address": "172.19.0.2:5066", "type": "beat" } -} \ No newline at end of file +} diff --git a/metricbeat/module/beat/state/data.go b/metricbeat/module/beat/state/data.go index 2a356407ef70..d22830e12ba1 100644 --- a/metricbeat/module/beat/state/data.go +++ b/metricbeat/module/beat/state/data.go @@ -69,7 +69,8 @@ var ( func eventMapping(r mb.ReporterV2, info beat.Info, content []byte, isXpack bool) error { event := mb.Event{ - RootFields: common.MapStr{}, + RootFields: common.MapStr{}, + ModuleFields: common.MapStr{}, } var data map[string]interface{} @@ -85,6 +86,8 @@ func eventMapping(r mb.ReporterV2, info beat.Info, content []byte, isXpack bool) if isOutputES(data) { clusterUUID = getClusterUUID(data) if clusterUUID != "" { + event.ModuleFields.Put("elasticsearch.cluster.id", clusterUUID) + if event.MetricSetFields != nil { event.MetricSetFields.Put("cluster.uuid", clusterUUID) } diff --git a/metricbeat/module/beat/stats/_meta/data.json b/metricbeat/module/beat/stats/_meta/data.json index ecda85834927..361d56878f0c 100644 --- a/metricbeat/module/beat/stats/_meta/data.json +++ b/metricbeat/module/beat/stats/_meta/data.json @@ -2,6 +2,11 @@ "@timestamp": "2017-10-12T08:05:34.853Z", "beat": { "id": "c4c9bc08-e990-4529-8bf5-715c00fa6615", + "elasticsearch": { + "cluster": { + "id": "foobar" + } + }, "stats": { "beat": { "host": "2963d991095f", @@ -48,7 +53,8 @@ "config": { "running": 3, "starts": 3, - "stops": 0 + "stops": 0, + "reloads": 1 }, "output": { "events": { @@ -133,4 +139,4 @@ "name": "beat", "type": "beat" } -} \ No newline at end of file +} diff --git a/metricbeat/module/beat/stats/_meta/fields.yml b/metricbeat/module/beat/stats/_meta/fields.yml index 56b598c7d054..539a4071b4c7 100644 --- a/metricbeat/module/beat/stats/_meta/fields.yml +++ b/metricbeat/module/beat/stats/_meta/fields.yml @@ -392,6 +392,8 @@ type: short - name: stops type: short + - name: reloads + type: short - name: output type: group description: > diff --git a/metricbeat/module/beat/stats/data.go b/metricbeat/module/beat/stats/data.go index 5e95f27a22ef..096dc028ba7a 100644 --- a/metricbeat/module/beat/stats/data.go +++ b/metricbeat/module/beat/stats/data.go @@ -88,10 +88,11 @@ var ( "total": c.Int("total"), }), }), - "config": c.Dict("config.module", s.Schema{ - "running": c.Int("running"), - "starts": c.Int("starts"), - "stops": c.Int("stops"), + "config": c.Dict("config", s.Schema{ + "running": c.Int("module.running"), + "starts": c.Int("module.starts"), + "stops": c.Int("module.stops"), + "reloads": c.Int("reloads"), }), }), "state": c.Dict("metricbeat.beat.state", s.Schema{ @@ -110,7 +111,7 @@ var ( } ) -func eventMapping(r mb.ReporterV2, info beat.Info, content []byte, isXpack bool) error { +func eventMapping(r mb.ReporterV2, info beat.Info, clusterUUID string, content []byte, isXpack bool) error { event := mb.Event{ RootFields: common.MapStr{}, ModuleFields: common.MapStr{}, @@ -118,10 +119,13 @@ func eventMapping(r mb.ReporterV2, info beat.Info, content []byte, isXpack bool) } event.RootFields.Put("service.name", beat.ModuleName) - event.ModuleFields = common.MapStr{} event.ModuleFields.Put("id", info.UUID) event.ModuleFields.Put("type", info.Beat) + if clusterUUID != "" { + event.ModuleFields.Put("elasticsearch.cluster.id", clusterUUID) + } + var data map[string]interface{} err := json.Unmarshal(content, &data) if err != nil { diff --git a/metricbeat/module/beat/stats/data_test.go b/metricbeat/module/beat/stats/data_test.go index 5a58a7c7ee1f..ee4b0f389573 100644 --- a/metricbeat/module/beat/stats/data_test.go +++ b/metricbeat/module/beat/stats/data_test.go @@ -42,12 +42,14 @@ func TestEventMapping(t *testing.T) { Beat: "helloworld", } + clusterUUID := "foo" + for _, f := range files { input, err := ioutil.ReadFile(f) require.NoError(t, err) reporter := &mbtest.CapturingReporterV2{} - err = eventMapping(reporter, info, input, true) + err = eventMapping(reporter, info, clusterUUID, input, true) require.NoError(t, err, f) require.True(t, len(reporter.GetEvents()) >= 1, f) diff --git a/metricbeat/module/beat/stats/stats.go b/metricbeat/module/beat/stats/stats.go index 7058a54614b4..7c260cf3e0a9 100644 --- a/metricbeat/module/beat/stats/stats.go +++ b/metricbeat/module/beat/stats/stats.go @@ -18,6 +18,8 @@ package stats import ( + "github.com/pkg/errors" + "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" "github.com/elastic/beats/v7/metricbeat/module/beat" @@ -66,5 +68,36 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error { return err } - return eventMapping(r, *info, content, m.XPackEnabled) + clusterUUID, err := m.getClusterUUID() + if err != nil { + return err + } + + return eventMapping(r, *info, clusterUUID, content, m.XPackEnabled) +} + +func (m *MetricSet) getClusterUUID() (string, error) { + state, err := beat.GetState(m.MetricSet) + if err != nil { + return "", errors.Wrap(err, "could not get state information") + } + + clusterUUID := state.Monitoring.ClusterUUID + if clusterUUID != "" { + return clusterUUID, nil + } + + if state.Output.Name != "elasticsearch" { + return "", nil + } + + clusterUUID = state.Outputs.Elasticsearch.ClusterUUID + if clusterUUID == "" { + // Output is ES but cluster UUID could not be determined. No point sending monitoring + // data with empty cluster UUID since it will not be associated with the correct ES + // production cluster. Log error instead. + return "", beat.ErrClusterUUID + } + + return clusterUUID, nil } diff --git a/metricbeat/module/kibana/_meta/fields.yml b/metricbeat/module/kibana/_meta/fields.yml index 633cbadde968..05a9818f2ae9 100644 --- a/metricbeat/module/kibana/_meta/fields.yml +++ b/metricbeat/module/kibana/_meta/fields.yml @@ -63,3 +63,5 @@ - name: kibana type: group fields: + - name: elasticsearch.cluster.id + type: keyword diff --git a/metricbeat/module/kibana/fields.go b/metricbeat/module/kibana/fields.go index 815dad6c8530..2c728c5076d6 100644 --- a/metricbeat/module/kibana/fields.go +++ b/metricbeat/module/kibana/fields.go @@ -32,5 +32,5 @@ func init() { // AssetKibana returns asset data. // This is the base64 encoded zlib format compressed contents of module/kibana. func AssetKibana() string { - return "eJzMWUtv4zYQvudXDHzZy0ZADnvxoWjRFmhRbFCkDXooCmMsjS02FKlyqCTury+oh60H9bAkd9eHIJA03/fNDDlDje7hhU5beBF7VHgHYIWVtIXNL/mFzR1ARBwakVqh1Ra+uQMAKG5CoqNM0h0Ax9rYXajVQRy3cEDJ7qohSci0haMDZrJWqCNv4c8Ns9x8hE1sbbr56w7gIEhGvM2x70FhQpWiHVu0nN8AsKfUoRmdpeWVumHd2IqE2GKSnu9U1igFcu1qijbewubbs8WmA1YoCQxxqhXTzj0aJPg+Ebs0zx3pggQJ9xE6i4znsPgBKnjNQUKJNqfgYIh2Qu32J0uziMagKsrU6JCYgyx1frvnEiGlmMXZxPLFr3qilBYTpgGLf2knRSLsEk4/YuB3OtQqzIwhlW8NRaHbQrNcHkHq8dsQi8jZMNldrnZJqsfAe4KgOZAao+Ahmbm+2tZt4E+LgD/1Az8sQ37wQFcxpFcXOal1uotI4mlJPtpYvg1h6J+M2HJgtUU5r27lCC2ADn4kuFygs9ZYxeKDuXDVKijftA63qPCVDB5pOR2+HgfKfpaJaCIHk3kVIQWlQRPo6qZZdegOed3Y/TwngupXngxyrwFVBCZT985pSMgaEXJQe7x5QKh+bXl1ia3YXCS+0OlNm/a9htBSmlBsUYUEz88//+AlcX/XIulgVSRCRfQ+l+UREwJ9KNk+MAhlySiUHtiKMNZs1/LKYfV6Zg0qTt2BEKPIEPNCVrfIyXzgM2u+rhyBl/6VDAutFpL6UM77RGHKsfZHc6+1JGzTNyj+iMnGZMDGVNHtMyEjEAx4Ri+u+QW0D4ZLkukCSyht7IOtGKUOUU7fFOd+105SZeTW65FMtwTVTvvwFdafRmUdFtkH1Xa3k8hpoc242YrmCBmqRZM09FXjdreCvo51+SXiaLDIqDVZ27OBjMMl67ct7eO0tyn2Xd655T+4rfsrdIXxheO3XmP1rNhnfG5ME+FHbYbA/8xQCNbqXF3ZX7iXjS7KSd1N+/nnVPRIsDX6qoreNX8q+tJslFSiPWiTLAZYKqSYFfSa+wIMA0GuQ/eNrrosUqvjIFT+TrsSVsYULYC6nLewG9U1wvbgWxQX6BjlYXeQGtsloonyaRWUh3kwk8drMBTrsRabJXsyrsmGUpCyUKOABCMCq/OiV3SNAB61JbAxWtgb/cZkGEJUwKQiSDJpRSoJWLh/UZHOuIFodTVDqT2cIwMykzvLWtAqpI95U7IxnXJ4Q/cZExBb3EvBMUV12MB/KC8GR5NL3kikfi3gqvP1VQfPibPE0WSed19nJDzZdGiM1gRh9yoU9azvkWAB/Oh4wPFAzgNCQTELp1CrqE3ailRM2N35Q1VhVE+VPofck8PxrpdX0J6kjZRO12bQbqHPeNQBgN8de+EASvemailyO6pc6C7CfvR60f5i6n9yup0C2J+mS+79+PD/Cf+M7wFoGQGnGFKuqBn/Rx1R8DdXTn2ckIje/TvizgS5zzm2q+i1IPfuvNZke61iCfBUlvlQZ8peVTQbp0TPlH2tQF1aXzXWL/raGxmqUVP/sa/9lWEtZcVGVx19PZmrjdzn5e+phCg+J89MVmvYPyca3xUfHs4u5XpGGketdTQ/bswR8BnfRZIlEwX0vtpdPc37LUcoQ1y7c/3g7vaDH/9h66sdkTlhfsnleCEo9tlt5hvlJg5uNefI102g3b6RMv8Gt372S/ScrCf7/ooxu3t8LuC6+wEm1KFJr0uwQpX+vmCpEfa/k4DnI/LV770TNFVd1+VKsG19B6h+U16gh3svjE8KJukFT7ert97hiMKEXnxLpQ1x/wUAAP//yfELdw==" + return "eJzMWU2P2zYQve+vGPiSS1bAHnLxoWjRFmhRJCjSBj0UhTGWxhYbilQ51O66v74gJdn6oCxZkpv4sFhI4ntvZsgZcvgIn+m0hc9ijwofAKywkraw+cU/2DwAJMSxEbkVWm3hmwcAgPIlZDopJD0AcKqN3cVaHcRxCweU7J4akoRMWzg6YCZrhTryFv7cMMvNW9ik1uabvx4ADoJkwluP/QgKM6oV7diiZf8CwJ5yh2Z0kVdPmgObg63IiC1m+flNPRqlQG48zdGmW9h8ex6x6YGVSiJDnGvFtHOfRhm+TsSuhntD+iBRxkOEbkTBc1jCADW85iijTJtTdDBEO6F2+5OlWURjUDVlbnRMzFGRO7vdd5mQUszibGOF/Fd/UUlLCfOIxb+0kyITdglnGDEKGx1rFRfGkPJLQ1HsltAsk0eQBuw2xCJxY5jszqtdEuox8AEnaI6kxiR6ymbOr+7oLvC7RcDvhoGfliE/BaBrH9Kz85zUOt8lJPG0JB5drNCCMPRPQWw5stqinJe3PEIHoIefCK4m6Kw5VrOEYC5cjQzKd83DHSp8JoNHWk6Hz8crab8oRDKRg8k8i5iiakAb6OaiSRLZipgJTZxGsSzYkokCYj7T6UWbpAdQl/jegCa7+wW2FPWv2lp4twGqBEyhHp3XICNrRMxR4/P2DqP+de1rSuw4d9imgNBKmlBsUcUEnz79/EOQxP1di6SHVZMIldDrXJYPmBHoQ8X2hkEoS0ahDMDWhKlmu5ZVDmvQMmtQce52lJgkhpgXsrpVQuYNn1n9vHIEQfpnMiy0WkgaQjmvE4U5pzrszb3WkrBL36L4IyWbkgGbUk23L4RMQDDgGb18FhbQ3VkuCaZzLKG0aQi2ZpQ6Rjl9UZwLZjdI9SA3X49k+imocVyArzD/tFLzdZFDUF1ze4Gc5tqC27VsjpBruWiShqFs3C13MFTyLr9MHA2WEbWm6Fp2JeJwifp9U/s47X2SfZ93bvqP7mv+ClVhfOKER68xe1asMyEzpokIo7ZdEP7mmgvWqlx92V+4lo1OyknVTYf552T0RLA1+qaM3h/+saxLs1FyifagTbYYYKmQstkwODzkYLji5Cb0UO+rzyK1Ol6F8ofilbAKpmQB1GW/hX2vruG2p9CkuECnKA+7g9TYTRFtlHeroDzNg5ncn4Nrvh4rsUW2J+OKbCwFKQsNCsgwIbDaJ72yakTwQVsCm6KFvdEvTIYhRgVMKoGskFbkkoCF+xcV6YJbiFbXTZjGxx4ZkJncXtaCVjG99UXJpnTy8IYeCyYgtriXglNKmrBReFNedp4mp7wRT/1awtX765s2nhObkaPBPK++Xk958tBrfbg2CLujUDIwv0ecBfCj4wHHA54HhIKymU6xVkmXtOOplLC/8q9lhVE9dfgc8kAMx6uez6ADQRtJna7MoN3C0OBRAwB+d+ylASjdSdVS4lZUNdGdh8PozaT9xdT/5HQ7BbA/TZc8eHvx/wl/j68RaJkA5xiTV9T2/wedUPQ310a9nRCIwfU7Ys4EuZ88tsvoDScPrrxOa3ytZAnwsUrzsS6UvSlptnaJgTb9Wo66lL76XqCsay9kqEFNw9u+7jXFWsrKha56+gYi1+jZz4vfxwqivI+eGazObcEcb3xX3lycTfJ6RgpHo3S0b0fmCHiPryIrsokCBo92N3fzfvMIlYsbb25v3N2/8RPebH21LTInLCy5ai9E5Tq7T3+jWsTRvfocft5E2q0bKf0l3vrRr9A92UD0wxljdvV4X8L11wNMyEOTjkuwQpb+vmRpEA6fSSBwC33zuXeCprrqulgJf0va1zHtAH299sJ4p2CSXghUu2bpve5RmFCL76m0Je6/AAAA//9Bvx66" } diff --git a/metricbeat/module/kibana/stats/data.go b/metricbeat/module/kibana/stats/data.go index 23696d98670e..79e6454f8050 100644 --- a/metricbeat/module/kibana/stats/data.go +++ b/metricbeat/module/kibana/stats/data.go @@ -123,7 +123,7 @@ func eventMapping(r mb.ReporterV2, content []byte, isXpack bool) error { event.Error = elastic.MakeErrorForMissingField("cluster_uuid", elastic.Kibana) return event.Error } - event.RootFields.Put("elasticsearch.cluster.id", elasticsearchClusterID) + event.ModuleFields.Put("elasticsearch.cluster.id", elasticsearchClusterID) // Set service ID uuid, err := dataFields.GetValue("uuid") From eef7d855f45b5a34b785fb01876722bb427e40b6 Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Tue, 28 Dec 2021 02:05:32 -0500 Subject: [PATCH 127/172] [Automation] Update elastic stack version to 8.1.0-b989cb5c for testing (#29618) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index 2b252a4a60cd..72ecd550e0b6 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-befff95a-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b989cb5c-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-befff95a-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-b989cb5c-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-befff95a-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-b989cb5c-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index d46af8af39af..9c508bb04ff7 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-befff95a-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b989cb5c-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-befff95a-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-b989cb5c-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 7c0428e25361760c8ba93be9faa9ddf8e14da999 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 28 Dec 2021 17:55:45 +0800 Subject: [PATCH 128/172] Fix gcp metrics metricset apply aligner to all metric_types (#29513) (#29514) Co-authored-by: endorama <526307+endorama@users.noreply.github.com> --- CHANGELOG.next.asciidoc | 1 + .../metricbeat/module/gcp/metrics/metrics_requester.go | 9 ++++----- x-pack/metricbeat/module/gcp/metrics/metricset.go | 10 +++++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 419b02cb29bb..b99794d9a4f7 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -96,6 +96,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Use xpack.enabled on SM modules to write into .monitoring indices when using Metricbeat standalone {pull}28365[28365] - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] - Enhance filter check in kubernetes event metricset. {pull}29470[29470] +- Fix gcp metrics metricset apply aligner to all metric_types {pull}29514[29513] *Packetbeat* diff --git a/x-pack/metricbeat/module/gcp/metrics/metrics_requester.go b/x-pack/metricbeat/module/gcp/metrics/metrics_requester.go index e5cf8c8b05de..d518acc0014a 100644 --- a/x-pack/metricbeat/module/gcp/metrics/metrics_requester.go +++ b/x-pack/metricbeat/module/gcp/metrics/metrics_requester.go @@ -69,22 +69,21 @@ func (r *metricsRequester) Metric(ctx context.Context, serviceName, metricType s return } -func (r *metricsRequester) Metrics(ctx context.Context, sdc metricsConfig, metricsMeta map[string]metricMeta) ([]timeSeriesWithAligner, error) { +func (r *metricsRequester) Metrics(ctx context.Context, serviceName string, aligner string, metricsToCollect map[string]metricMeta) ([]timeSeriesWithAligner, error) { var lock sync.Mutex var wg sync.WaitGroup results := make([]timeSeriesWithAligner, 0) - aligner := sdc.Aligner - for mt, meta := range metricsMeta { + for mt, meta := range metricsToCollect { wg.Add(1) metricMeta := meta go func(mt string) { defer wg.Done() - r.logger.Debugf("For metricType %s, metricMeta = %d", mt, metricMeta) + r.logger.Debugf("For metricType %s, metricMeta = %d, aligner = %s", mt, metricMeta, aligner) interval, aligner := getTimeIntervalAligner(metricMeta.ingestDelay, metricMeta.samplePeriod, r.config.period, aligner) - ts := r.Metric(ctx, sdc.ServiceName, mt, interval, aligner) + ts := r.Metric(ctx, serviceName, mt, interval, aligner) lock.Lock() defer lock.Unlock() results = append(results, ts) diff --git a/x-pack/metricbeat/module/gcp/metrics/metricset.go b/x-pack/metricbeat/module/gcp/metrics/metricset.go index d284d80ca5d4..e121d6a3a022 100644 --- a/x-pack/metricbeat/module/gcp/metrics/metricset.go +++ b/x-pack/metricbeat/module/gcp/metrics/metricset.go @@ -165,7 +165,15 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) (err error) { for _, sdc := range m.MetricsConfig { m.Logger().Debugf("metrics config: %v", sdc) - responses, err := m.requester.Metrics(ctx, sdc, m.metricsMeta) + // m.metricsMeta contains all metrics to be collected, not just the one in the current MetricsConfig. + // this loop filters the metrics in metricsMeta so requester.Metrics can collect only the appropriate + // ones. + // See https://github.com/elastic/beats/pull/29514 + metricsToCollect := map[string]metricMeta{} + for _, v := range sdc.MetricTypes { + metricsToCollect[sdc.AddPrefixTo(v)] = m.metricsMeta[sdc.AddPrefixTo(v)] + } + responses, err := m.requester.Metrics(ctx, sdc.ServiceName, sdc.Aligner, metricsToCollect) if err != nil { err = errors.Wrapf(err, "error trying to get metrics for project '%s' and zone '%s' or region '%s'", m.config.ProjectID, m.config.Zone, m.config.Region) m.Logger().Error(err) From ffbc6e6747c6e80b114ba5b772502dbb9fbea137 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 28 Dec 2021 12:09:52 +0100 Subject: [PATCH 129/172] ci: enable 7.17 branch (#29602) --- .ci/schedule-daily.groovy | 3 ++- .ci/schedule-weekly.groovy | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.ci/schedule-daily.groovy b/.ci/schedule-daily.groovy index 2211dec4c499..5c1cc904f5ca 100644 --- a/.ci/schedule-daily.groovy +++ b/.ci/schedule-daily.groovy @@ -25,7 +25,8 @@ pipeline { runBuild(quietPeriod: 2000, job: 'Beats/beats/8.0') // This should be `current_7` bump.getCurrentMinorReleaseFor7 or // `next_minor_7` bump.getNextMinorReleaseFor7 - runBuild(quietPeriod: 4000, job: 'Beats/beats/7.16') + runBuild(quietPeriod: 4000, job: 'Beats/beats/7.17') + runBuild(quietPeriod: 6000, job: 'Beats/beats/7.16') } } } diff --git a/.ci/schedule-weekly.groovy b/.ci/schedule-weekly.groovy index c2d96964575d..6d5c1a7f0072 100644 --- a/.ci/schedule-weekly.groovy +++ b/.ci/schedule-weekly.groovy @@ -25,7 +25,8 @@ pipeline { runBuild(quietPeriod: 1000, job: 'Beats/beats/8.0') // This should be `current_7` bump.getCurrentMinorReleaseFor7 or // `next_minor_7` bump.getNextMinorReleaseFor7 - runBuild(quietPeriod: 2000, job: 'Beats/beats/7.16') + runBuild(quietPeriod: 2000, job: 'Beats/beats/7.17') + runBuild(quietPeriod: 3000, job: 'Beats/beats/7.16') } } } From 2b23068a87f7ef3cb7469761169476469ab92704 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Tue, 28 Dec 2021 16:48:32 +0100 Subject: [PATCH 130/172] kibana.stats: extract correct index property (#29622) * kibana.stats: extract correct index property * changelog entry --- CHANGELOG.next.asciidoc | 1 + metricbeat/module/kibana/stats/_meta/data.json | 4 ++-- metricbeat/module/kibana/stats/data.go | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b99794d9a4f7..6e0eb0967ac1 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -97,6 +97,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix in rename processor to ingest metrics for `write.iops` to proper field instead of `write_iops` in rds metricset. {pull}28960[28960] - Enhance filter check in kubernetes event metricset. {pull}29470[29470] - Fix gcp metrics metricset apply aligner to all metric_types {pull}29514[29513] +- Extract correct index property in kibana.stats metricset {pull}29622[29622] *Packetbeat* diff --git a/metricbeat/module/kibana/stats/_meta/data.json b/metricbeat/module/kibana/stats/_meta/data.json index dde2be30ac3e..46e85773eeb6 100644 --- a/metricbeat/module/kibana/stats/_meta/data.json +++ b/metricbeat/module/kibana/stats/_meta/data.json @@ -16,7 +16,7 @@ "host": { "name": "0.0.0.0" }, - "index": "b04775fa6831", + "index": ".kibana", "name": "b04775fa6831", "os": { "distro": "CentOS", @@ -88,4 +88,4 @@ "type": "kibana", "version": "7.14.0" } -} \ No newline at end of file +} diff --git a/metricbeat/module/kibana/stats/data.go b/metricbeat/module/kibana/stats/data.go index 79e6454f8050..a2148f64e84d 100644 --- a/metricbeat/module/kibana/stats/data.go +++ b/metricbeat/module/kibana/stats/data.go @@ -52,7 +52,7 @@ var ( "uuid": c.Str("kibana.uuid"), "name": c.Str("kibana.name"), - "index": c.Str("kibana.name"), + "index": c.Str("kibana.index"), "host": s.Object{ "name": c.Str("kibana.host"), }, From 6794652a17dddbba371c2d27e1f71674de70a813 Mon Sep 17 00:00:00 2001 From: Marc Lopez Rubio Date: Wed, 29 Dec 2021 00:37:14 +0800 Subject: [PATCH 131/172] apm-server: Remove `data_streams.enabled` flag (#29168) * apm-server: Remove `data_streams.enabled` flag Removes the `"apm-server.data_streams.enabled` flag in the `apm-server` spec, since it's been marked as deprecated in `8.0`. Signed-off-by: Marc Lopez Rubio --- x-pack/elastic-agent/pkg/agent/program/supported.go | 2 +- x-pack/elastic-agent/spec/apm-server.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/program/supported.go b/x-pack/elastic-agent/pkg/agent/program/supported.go index 70e7c6f716fb..220f187a3fe2 100644 --- a/x-pack/elastic-agent/pkg/agent/program/supported.go +++ b/x-pack/elastic-agent/pkg/agent/program/supported.go @@ -25,7 +25,7 @@ func init() { // spec/metricbeat.yml // spec/osquerybeat.yml // spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("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") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/x-pack/elastic-agent/spec/apm-server.yml b/x-pack/elastic-agent/spec/apm-server.yml index 993c28498a87..0258eb9fb0f5 100644 --- a/x-pack/elastic-agent/spec/apm-server.yml +++ b/x-pack/elastic-agent/spec/apm-server.yml @@ -3,7 +3,6 @@ cmd: apm-server artifact: apm-server args: [ "-E", "management.enabled=true", - "-E", "apm-server.data_streams.enabled=true", "-E", "gc_percent=${APMSERVER_GOGC:100}" ] exported_metrics: [ From 4ae6306b73bebab9cc51d366690e6d73c821792b Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Wed, 29 Dec 2021 02:50:18 -0500 Subject: [PATCH 132/172] [Automation] Update elastic stack version to 8.1.0-c1a942c7 for testing (#29630) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index 72ecd550e0b6..eea246eaeb8c 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b989cb5c-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-c1a942c7-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-b989cb5c-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-c1a942c7-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-b989cb5c-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-c1a942c7-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 9c508bb04ff7..ae706a3d2e83 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-b989cb5c-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-c1a942c7-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-b989cb5c-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-c1a942c7-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 1386a04099c81f791b334616437d71c56109e0e9 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Wed, 29 Dec 2021 13:27:51 +0100 Subject: [PATCH 133/172] add elasticsearch.cluster.id to logstash metricsets (#29625) * add elasticsearch.cluster.id to logstash metricsets * changelog entry --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 7 +++++++ metricbeat/module/logstash/_meta/fields.yml | 2 ++ metricbeat/module/logstash/fields.go | 2 +- metricbeat/module/logstash/node/_meta/data.json | 7 ++++++- metricbeat/module/logstash/node/data.go | 1 + metricbeat/module/logstash/node_stats/_meta/data.json | 11 +++++++++-- metricbeat/module/logstash/node_stats/data.go | 3 ++- 8 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 6e0eb0967ac1..e5152441e174 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -152,6 +152,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `container.id` and `container.runtime` ECS fields in container metricset. {pull}29560[29560] - Add `memory.workingset.limit.pct` field in Kubernetes container/pod metricset. {pull}29547[29547] - Add `elasticsearch.cluster.id` field to Beat and Kibana modules. {pull}29577[29577] +- Add `elasticsearch.cluster.id` field to Logstash module. {pull}29625[29625] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index e1e256d0dc3d..2a866020d37b 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -46325,6 +46325,13 @@ alias to: logstash.node.state.pipeline.hash -- +*`logstash.elasticsearch.cluster.id`*:: ++ +-- +type: keyword + +-- + [float] === node diff --git a/metricbeat/module/logstash/_meta/fields.yml b/metricbeat/module/logstash/_meta/fields.yml index caa5d1529746..850e5b0ba0d4 100644 --- a/metricbeat/module/logstash/_meta/fields.yml +++ b/metricbeat/module/logstash/_meta/fields.yml @@ -104,3 +104,5 @@ - name: logstash type: group fields: + - name: elasticsearch.cluster.id + type: keyword diff --git a/metricbeat/module/logstash/fields.go b/metricbeat/module/logstash/fields.go index c2a1e2089293..0f9ed6305658 100644 --- a/metricbeat/module/logstash/fields.go +++ b/metricbeat/module/logstash/fields.go @@ -32,5 +32,5 @@ func init() { // AssetLogstash returns asset data. // This is the base64 encoded zlib format compressed contents of module/logstash. func AssetLogstash() string { - return "eJy8Wc2Oq0YT3fspSl5/F+lbZONFlEUSZaJEyepuogj1QBn3vUB3+sfJ5OkjsMFA/xWGGRazaFznnKouqqtrPsFXfDtBLSptmL4cAAw3NZ7g+Mt96XgAKFEXikvDRXuCbw8AAMNraERpazwAKKyRaTxBxQ4AGo3hbaVP8MdR6/r4PzhejJHHP7t3F6FMXoj2zKsTnFmtO/szx7rUpx79E7SswYeuXBtmdP8KwLzJjkUJK+8rU9OpueENasMaOb4ZrFnNmZ6sSmYuJzh+N1ocHbAv18aBmYrwCZnaN9jM1kMYIZwp1gWZzK3GMudt/vpmUDs/DXk693gIcNaKErM+ytmXa5M12GQEkpmehv3z7nKCHIMSK7st7H7T8LrmS6qwiLiAIOzAi1dsjd6UILzdQexNR7bAGiiENftxLMEGktIq1pWKXTfhzhnBXtaMTXthLS93UD2uOXgD0RWV5mKPnR/XlpADleQSa96im6UtaoOlYyC25XMh7W4Fr3MxWFN8gDHQKXBrm1dUuTjnWDPZFTuJiovSV6MgWcUgukNCZ0WvNSuk7deydfTTcy03FyWMqbHMW9aKD9JLZnbj2x+tD9uPjm+K/lE+WJmzKypW4btk3P+/WfYBe/kubTZVn4WYRiUfJiSu48MCsiAaC5VvO5+vVYW0rChMZjWrMPiJPNsOzZI8yDPWfCUK1LdQSFQFtobYC/u4Y2gD418WLd6P67wQdhNhAMx7PcDV14PhQMxmZ/M6jZj5UByGi68heYJjxAl0O3TnO/Tk8e65+A3Pwn5++xue9yS/3QmhQaN4obPVWmDRXjyivFslcHrIB9xXfPtbqPAxtEiYtPFoKPTaHr8zybo/HcLiFw2vbh33CYyyy7eRLeqen4Q24IBua301qisv0Olyd5A7zjQ+e7D9YwCI5keC7+fPv8JLexYrs8rvOSRTK6mne3yuw6yihXM6fpgNh4cfIb5xRPG/3yjg5fvgV+6/iz7zcbuJEMeLYQJ9gjEnqkVbRdHcqRNNaUotrJ1GEXU7uImpEgE2OKKZ24YiQci7H3pkb34Bcded4Q/BMbK+7nlpC9HwtrqHAfpuClUWVeXOi/aW9Zs1lVgr68xrgypxh9yu7cc7zSptyekXQWVklDW33lRn3BHXHDx8jlDOojSOd8y0n3/u+ImGncIH+rCATkghBdIQYc4ZrbNAmQU8ibdVX/RuPsfYYyNpd3aidiBlIc0BihOQHpSuJ6USw4ZhqqsqmV/w3Bh0I9PaKSaRjjalmQOVwr7WbrGJDfnnAIth/+MhtSnbj4zAzXYdSD8YeveqEJhi+QlJ5aD7aRIpFgBYBiHX/F/cufHueu5dwZMtOOy6b+G2laAVnmnmCLiTlsnwIhjN/aKwp3hwv4rgjWUl3FCxcpQXbFCxOg9WGSB/I4smfx3JwtPN6bQQQ4BN1lt4NhIEt2+fvrT6kj+RQ+daRFuQmZp1VKT/MczV9PvyXwAAAP//XRLRjg==" + return "eJy8Wb2OrEYTzfcpShN/F+kLnExgObAtr2XLjm5iWagXaqDvbeh2/4y9fnoLZmCB/qEY2CWYAKhzTlcV1dU1n+Arvp5ByMpYZuonAMutwDOcfrnfOj0BlGgKzZXlsj3Dt08AAMNjaGTpBD4BaBTIDJ6hYk8ABq3lbWXO8MfJGHH6H5xqa9Xpz+5ZLbXNC9leeHWGCxOms79wFKU59+ifoGUNvunKjWXW9I8A7KvqWLR06n5najo1t7xBY1mjxieDNROcmcldxWx9htN3o8XJA/tybTyYqYiQkKl9g83sfgwjhjPFqpGp3Bksc97mL68WjfdqbKXzFQ8OzlpZYtZ7OftybbIGm4xAMtPTsH/eXU6UY1DiVBfC7p2GC8GXVHERaQFR2IEXr9hasytBeHuA2JuObIE1UEhnj+NYgg0kpdOsKxWHBuHOmcBe1oxdsXCOlweoHu95eAPRFbXh8ojIj/eWkAOV4goFb9HP0haNxdIzkPvyuVDusILXLTFaU0KAKdApcOuaF9S5vOQomOqKnULNZRmqUbBaxSAZIWmyoteaFcr197Jt9NN9Lbe1ltYKLPOWtfKD9JKZff/2W+ub7Uf7d43+rXywMmdX1KzCd8m4/3+z7AOOWrty2VR9FmMalXyYkLSOD3PIgmgsVKFwPl6rCuVYUdjMGVZh9BN5tB2aJXmUZ6z5WhZobq5QqAtsLbEXDnGn0AbGvxw6vG/XeSHdLsIIWPB4gJuPB8OGmM325m0aMQuheAx1qCF5gGPEiXQ79MWjYMbywiDTRZ0VwhmLOuSJr/j6t9T+2jp5q/1B4OQ4XAv7+fFxuGLqjyC/HSqhQat5YbLNWmDRn7yF6bBS4jWhEA3L0nSRcevGo6E0Ww8JnUnW/XQIizcaXt1a9jNY7ZZPEyHqrp+kseCB7uudDeorL9Brkw+QOw5FPgeww3MESObHCt/Pn3+F5/YiN2ZVeOWwmlqrerortHSYlcR4Tqd3w2H3CSOkA0cU//uNAp6/j37l4cPsIx+3nwhpvBQm0EcgcyIh2yqJ5o+taErX1MLWcRZRt4e7MpYiwEZnPHPbmCcIefdDjxzMLyBG3ZseERZG1tddz20hG95WdzdA346hzpKq/IHT0bJ+c7aSW2VduLCoVw6h+7X9eKfZpG11fEZQmZiFza131Rl/RjYHj+8jlL1oHSc4pzpuff78ioa9hg/0aQOdkEIKpCnEnDNZZ4EyTHgQb6++5OF+jnFEIGmHfqJ2IGUhbQGURcD6pHU7KZUYdkxjfVWr+QWPzVF3Mm0dgxLpaGOeOVAp3Yvwi03qX4I5wOLfgreL1Kbs3zIiJ9ttIP1k6d2rQmQMFiYklYPu1VWklANg6YTc8H/x4Ma767kPBV9tweHQuMXbVoJWeKSZI+BOWibLi6g3j/PCkeLB/yqiJ5aNcEPFylHV2KBmIo9WGSB/I4smfxvJYqW702khhgC7Wm/hUU8Qln379JUzdf5ADl2ETLYgMzXbqEh/UszV9HH5LwAA//8MYuTR" } diff --git a/metricbeat/module/logstash/node/_meta/data.json b/metricbeat/module/logstash/node/_meta/data.json index a847bea944a2..cfc36e09d31f 100644 --- a/metricbeat/module/logstash/node/_meta/data.json +++ b/metricbeat/module/logstash/node/_meta/data.json @@ -9,6 +9,11 @@ "cluster": { "id": "VUwnkX_lTzCFP9VUoXT1IQ" }, + "elasticsearch": { + "cluster": { + "id": "VUwnkX_lTzCFP9VUoXT1IQ" + } + }, "node": { "host": "7dc1b688baf4", "id": "9a1f83e1-52b9-4625-a98a-6aa336f41719", @@ -101,4 +106,4 @@ "type": "logstash", "version": "7.12.0" } -} \ No newline at end of file +} diff --git a/metricbeat/module/logstash/node/data.go b/metricbeat/module/logstash/node/data.go index bb9f51c98471..1d5725ed969d 100644 --- a/metricbeat/module/logstash/node/data.go +++ b/metricbeat/module/logstash/node/data.go @@ -122,6 +122,7 @@ func eventMapping(r mb.ReporterV2, content []byte, pipelines []logstash.Pipeline if clusterUUID != "" { event.ModuleFields.Put("cluster.id", clusterUUID) + event.ModuleFields.Put("elasticsearch.cluster.id", clusterUUID) } event.ID = pipeline.EphemeralID diff --git a/metricbeat/module/logstash/node_stats/_meta/data.json b/metricbeat/module/logstash/node_stats/_meta/data.json index 5343737c3b44..b218c10246e6 100644 --- a/metricbeat/module/logstash/node_stats/_meta/data.json +++ b/metricbeat/module/logstash/node_stats/_meta/data.json @@ -6,7 +6,14 @@ "module": "logstash" }, "logstash": { - "cluster.id": "VUwnkX_lTzCFP9VUoXT1IQ", + "cluster": { + "id": "VUwnkX_lTzCFP9VUoXT1IQ" + }, + "elasticsearch": { + "cluster": { + "id": "VUwnkX_lTzCFP9VUoXT1IQ" + } + }, "node": { "stats": { "events": { @@ -136,4 +143,4 @@ "type": "logstash", "version": "7.12.0" } -} \ No newline at end of file +} diff --git a/metricbeat/module/logstash/node_stats/data.go b/metricbeat/module/logstash/node_stats/data.go index 85eaaa8b493f..d91e27245481 100644 --- a/metricbeat/module/logstash/node_stats/data.go +++ b/metricbeat/module/logstash/node_stats/data.go @@ -204,7 +204,8 @@ func eventMapping(r mb.ReporterV2, content []byte, isXpack bool) error { event.RootFields.Put("service.version", nodeStats.Version) if clusterUUID != "" { - event.ModuleFields["cluster.id"] = clusterUUID + event.ModuleFields.Put("cluster.id", clusterUUID) + event.ModuleFields.Put("elasticsearch.cluster.id", clusterUUID) } // xpack.enabled in config using standalone metricbeat writes to `.monitoring` instead of `metricbeat-*` From 84924e9f32d018e360303714c26f754dbab34f93 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Thu, 30 Dec 2021 03:59:45 +0100 Subject: [PATCH 134/172] Ensure that match_only_text and wildcard fields can be added to default_field list (#29634) Fixes the construction of the index template's default_field list so that fields of type match_only_text and wildcard can be added to it. --- CHANGELOG.next.asciidoc | 2 ++ libbeat/template/processor.go | 2 +- libbeat/template/processor_test.go | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e5152441e174..bbf88e791f47 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -78,6 +78,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* +- Fields of type `match_only_text` (i.e. `message`) and `wildcard` were missing from the template's default_field list. {issue}29633[29633] {pull}29634[29634] + *Auditbeat* diff --git a/libbeat/template/processor.go b/libbeat/template/processor.go index cb13a95aa2d1..9e4214ac04e6 100644 --- a/libbeat/template/processor.go +++ b/libbeat/template/processor.go @@ -136,7 +136,7 @@ func (p *Processor) Process(fields mapping.Fields, state *fieldState, output, an if *field.DefaultField { switch field.Type { - case "", "keyword", "text": + case "", "keyword", "text", "match_only_text", "wildcard": addToDefaultFields(&field) } } diff --git a/libbeat/template/processor_test.go b/libbeat/template/processor_test.go index fefeb9b4313d..4b35da898156 100644 --- a/libbeat/template/processor_test.go +++ b/libbeat/template/processor_test.go @@ -719,6 +719,18 @@ func TestProcessDefaultField(t *testing.T) { }, }, }, + // Ensure that text_only_keyword fields can be added to default_field + mapping.Field{ + Name: "a_match_only_text_field", + Type: "match_only_text", + DefaultField: &enableDefaultField, + }, + // Ensure that wildcard fields can be added to default_field + mapping.Field{ + Name: "a_wildcard_field", + Type: "wildcard", + DefaultField: &enableDefaultField, + }, } version, err := common.NewVersion("7.0.0") @@ -734,6 +746,8 @@ func TestProcessDefaultField(t *testing.T) { } expectedFields := []string{ + "a_match_only_text_field", + "a_wildcard_field", "bar", "nested.bar", "nested.foo", From d46bb5f0cd6e84faa54c66138848aff46f2417f9 Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:37:43 +1030 Subject: [PATCH 135/172] x-pack/auditbeat/module/system/socket: get full length path and arg from /proc when not available from kprobe (#29410) Also use first arg from sysinfo.Processes in place of Name to avoid process name truncation. --- CHANGELOG.next.asciidoc | 5 ++ NOTICE.txt | 2 +- .../auditbeat/module/system/socket/events.go | 76 ++++++++++++++----- .../module/system/socket/socket_linux.go | 9 +++ 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index bbf88e791f47..208d11073851 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -82,6 +82,11 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Auditbeat* +- system/package: Fix parsing of Installed-Size field of DEB packages. {issue}16661[16661] {pull}17188[17188] +- system module: Fix panic during initialisation when /proc/stat can't be read. {pull}17569[17569] +- system/package: Fix an error that can occur while trying to persist package metadata. {issue}18536[18536] {pull}18887[18887] +- system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] +- system/socket: Fix process name and arg truncation for long names, paths and args lists. {issue}24667[24667] {pull}29410[29410] *Filebeat* diff --git a/NOTICE.txt b/NOTICE.txt index 148e4680e06a..7853a1492311 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,5 +1,5 @@ Elastic Beats -Copyright 2014-2021 Elasticsearch BV +Copyright 2014-2022 Elasticsearch BV This product includes software developed by The Apache Software Foundation (http://www.apache.org/). diff --git a/x-pack/auditbeat/module/system/socket/events.go b/x-pack/auditbeat/module/system/socket/events.go index d0c37701d541..74b31cc7e7f3 100644 --- a/x-pack/auditbeat/module/system/socket/events.go +++ b/x-pack/auditbeat/module/system/socket/events.go @@ -859,8 +859,10 @@ func (e *inetReleaseCall) Update(s *state) error { // kernels it needs to dump fixed-size arrays in 8-byte chunks. As the total // number of fetchargs available is limited, we have to dump only the first // 128 bytes of every argument. -const maxProgArgLen = 128 -const maxProgArgs = 5 +const ( + maxProgArgLen = 128 + maxProgArgs = 5 +) type execveCall struct { Meta tracing.Metadata `kprobe:"metadata"` @@ -880,38 +882,78 @@ type execveCall struct { func (e *execveCall) getProcess() *process { p := &process{ pid: e.Meta.PID, - path: readCString(e.Path[:]), created: kernelTime(e.Meta.Timestamp), } - p.name = filepath.Base(p.path) - var argc int - for argc = 0; argc <= maxProgArgs; argc++ { - if e.Ptrs[argc] == 0 { - break + + if idx := bytes.IndexByte(e.Path[:], 0); idx >= 0 { + // Fast path if we already have the path. + p.path = string(e.Path[:idx]) + } else { + // Attempt to get the path from the /prox//exe symlink. + var err error + p.path, err = filepath.EvalSymlinks(fmt.Sprintf("/proc/%d/exe", e.Meta.PID)) + if err != nil { + if pe, ok := err.(*os.PathError); ok && strings.Contains(pe.Path, "(deleted)") { + // Keep the deleted path from the PathError. + p.path = pe.Path + } else { + // Fallback to the truncated path. + p.path = string(e.Path[:]) + " ..." + } } } - p.args = make([]string, argc) - params := [maxProgArgs][]byte{ + + // Check for truncation of arg list or arguments. + params := [...][]byte{ e.Param0[:], e.Param1[:], e.Param2[:], e.Param3[:], e.Param4[:], } - limit := argc - if limit > maxProgArgs { - limit = maxProgArgs - p.args[limit] = "..." + var ( + argc int + truncatedArg bool + ) + for argc = 0; argc < len(e.Ptrs); argc++ { + if e.Ptrs[argc] == 0 { + break + } + if argc < len(params) && bytes.IndexByte(params[argc], 0) < 0 { + truncatedArg = true + } + } + if argc > maxProgArgs || truncatedArg { + // Attempt to get complete args list from /proc//cmdline. + cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", e.Meta.PID)) + if err == nil { + p.args = strings.Split(strings.TrimRight(string(cmdline), "\x00"), "\x00") + } } - for i := 0; i < limit; i++ { - p.args[i] = readCString(params[i]) + + if p.args == nil { + // Fallback to arg list if unsuccessful or no truncation. + p.args = make([]string, argc) + if argc > maxProgArgs { + argc = maxProgArgs + p.args[argc] = "..." + } + for i, par := range params[:argc] { + p.args[i] = readCString(par) + } } - if p.hasCreds = e.creds != nil; p.hasCreds { + + // Get name from first argument. + p.name = filepath.Base(p.args[0]) + + if e.creds != nil { + p.hasCreds = true p.uid = e.creds.UID p.gid = e.creds.GID p.euid = e.creds.EUID p.egid = e.creds.EGID } + return p } diff --git a/x-pack/auditbeat/module/system/socket/socket_linux.go b/x-pack/auditbeat/module/system/socket/socket_linux.go index e7f1a059dd1e..fb66f717d843 100644 --- a/x-pack/auditbeat/module/system/socket/socket_linux.go +++ b/x-pack/auditbeat/module/system/socket/socket_linux.go @@ -187,6 +187,15 @@ func (m *MetricSet) Run(r mb.PushReporterV2) { } else { for _, p := range procs { if i, err := p.Info(); err == nil { + if len(i.Name) == 16 && len(i.Args) != 0 { + // github.com/prometheus/procfs uses /proc//stat for + // the process name which is truncated to 16 bytes, so get + // the name from the cmdline data if it might be truncated. + // The guard for length of i.Args is for cases where there + // is no command line reported by proc fs; this should never + // happen, but does. + i.Name = filepath.Base(i.Args[0]) + } process := &process{ name: i.Name, pid: uint32(i.PID), From 0ea9581a49ae7e30f39137b4d1c42090c11b2dd5 Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Tue, 4 Jan 2022 17:53:58 +1030 Subject: [PATCH 136/172] x-pack/filebeat/module/sophos/xg: fix kv field separation and add support for timestamped log line (#29331) This change also needed changes in the cisco asa module's test expect files to bring timestamp handling during testing up to date. --- CHANGELOG.next.asciidoc | 1 + filebeat/docs/fields.asciidoc | 10 + .../additional_messages.log-expected.json | 36 +-- .../cisco/asa/test/asa.log-expected.json | 100 ------- .../asa/test/hostnames.log-expected.json | 2 - .../cisco/asa/test/not-ip.log-expected.json | 3 - .../cisco/asa/test/sample.log-expected.json | 87 ------ x-pack/filebeat/module/sophos/fields.go | 2 +- .../module/sophos/xg/_meta/fields.yml | 5 + .../module/sophos/xg/ingest/pipeline.yml | 8 +- .../module/sophos/xg/test/anti-spam.log | 22 +- .../xg/test/anti-spam.log-expected.json | 31 +-- .../module/sophos/xg/test/anti-virus.log | 18 +- .../xg/test/anti-virus.log-expected.json | 22 +- x-pack/filebeat/module/sophos/xg/test/atp.log | 10 +- .../sophos/xg/test/atp.log-expected.json | 10 +- .../module/sophos/xg/test/cfilter.log | 20 +- .../sophos/xg/test/cfilter.log-expected.json | 25 +- .../filebeat/module/sophos/xg/test/event.log | 40 +-- .../sophos/xg/test/event.log-expected.json | 55 ++-- .../module/sophos/xg/test/firewall.log | 43 +-- .../sophos/xg/test/firewall.log-expected.json | 256 +++++++++++++++--- x-pack/filebeat/module/sophos/xg/test/idp.log | 12 +- .../sophos/xg/test/idp.log-expected.json | 13 +- .../module/sophos/xg/test/sandbox.log | 12 +- .../sophos/xg/test/sandbox.log-expected.json | 16 +- .../xg/test/system-health.log-expected.json | 5 - x-pack/filebeat/module/sophos/xg/test/waf.log | 10 +- .../sophos/xg/test/waf.log-expected.json | 13 +- .../sophos/xg/test/wifi.log-expected.json | 2 - 30 files changed, 411 insertions(+), 478 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 208d11073851..1d4234fad775 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -92,6 +92,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - aws-s3: Stop trying to increase SQS message visibility after ReceiptHandleIsInvalid errors. {pull}29480[29480] - Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] +- Fix `sophos` KV splitting and syslog header handling {issue}24237[24237] {pull}29331[29331] - Undo deletion of endpoint config from cloudtrail fileset in {pull}29415[29415]. {pull}29450[29450] *Heartbeat* diff --git a/filebeat/docs/fields.asciidoc b/filebeat/docs/fields.asciidoc index 0dd3105d3996..73d50ea649d2 100644 --- a/filebeat/docs/fields.asciidoc +++ b/filebeat/docs/fields.asciidoc @@ -143278,6 +143278,16 @@ type: keyword The related XSS caught by the WAF +type: keyword + +-- + +*`sophos.xg.ether_type`*:: ++ +-- +The ethernet frame type + + type: keyword -- diff --git a/x-pack/filebeat/module/cisco/asa/test/additional_messages.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/additional_messages.log-expected.json index ca9623da72a6..2992f9a237c5 100644 --- a/x-pack/filebeat/module/cisco/asa/test/additional_messages.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/additional_messages.log-expected.json @@ -181,12 +181,12 @@ "event.code": 609002, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T17:51:17.000-02:00", + "event.end": "2022-05-05T17:51:17.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%FTD-7-609002: Teardown local-host net:192.168.2.2 duration 0:00:00", "event.severity": 7, - "event.start": "2021-05-05T19:51:17.000Z", + "event.start": "2022-05-05T19:51:17.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -701,12 +701,12 @@ "event.code": 609002, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T18:24:31.000-02:00", + "event.end": "2022-05-05T18:24:31.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-7-609002: Teardown local-host identity:10.10.10.10 duration 0:00:00", "event.severity": 7, - "event.start": "2021-05-05T20:24:31.000Z", + "event.start": "2022-05-05T20:24:31.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -849,13 +849,13 @@ "event.code": 302014, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T18:29:32.000-02:00", + "event.end": "2022-05-05T18:29:32.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-6-302014: Teardown TCP connection 2960892904 for out111:10.10.10.10/443 to fw111:192.168.2.2/55225 duration 0:00:00 bytes 0 TCP Reset-I", "event.reason": "TCP Reset-I", "event.severity": 6, - "event.start": "2021-05-05T20:29:32.000Z", + "event.start": "2022-05-05T20:29:32.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -966,12 +966,12 @@ "event.code": 305012, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T18:29:32.000-02:00", + "event.end": "2022-05-05T18:29:32.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-6-305012: Teardown dynamic UDP translation from fw111:10.10.10.10/54230 to out111:192.168.2.2/54230 duration 0:00:00", "event.severity": 6, - "event.start": "2021-05-05T20:29:32.000Z", + "event.start": "2022-05-05T20:29:32.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -1175,12 +1175,12 @@ "event.code": 302016, "event.dataset": "cisco.asa", "event.duration": 124000000000, - "event.end": "2021-05-05T18:40:50.000-02:00", + "event.end": "2022-05-05T18:40:50.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-2-302016: Teardown UDP connection 1671727 for intfacename:10.10.10.10/161 to net:192.186.2.2/53356 duration 0:02:04 bytes 64585", "event.severity": 2, - "event.start": "2021-05-05T20:38:46.000Z", + "event.start": "2022-05-05T20:38:46.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -1812,13 +1812,13 @@ "event.code": 302023, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T19:02:58.000-02:00", + "event.end": "2022-05-05T19:02:58.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-6-302023: Teardown stub TCP connection for fw111:10.10.10.10/39210 to net:192.168.2.2/10051 duration 0:00:00 forwarded bytes 0 Cluster flow with CLU closed on owner", "event.reason": "Cluster flow with CLU closed on owner", "event.severity": 6, - "event.start": "2021-05-05T21:02:58.000Z", + "event.start": "2022-05-05T21:02:58.000Z", "event.timezone": "-02:00", "event.type": [ "info" @@ -1868,13 +1868,13 @@ "event.code": 302023, "event.dataset": "cisco.asa", "event.duration": 0, - "event.end": "2021-05-05T19:02:58.000-02:00", + "event.end": "2022-05-05T19:02:58.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-6-302023: Teardown stub TCP connection for net:10.10.10.10/10051 to unknown:192.168.2.2/39222 duration 0:00:00 forwarded bytes 0 Forwarding or redirect flow removed to create director or backup flow", "event.reason": "Forwarding or redirect flow removed to create director or backup flow", "event.severity": 6, - "event.start": "2021-05-05T21:02:58.000Z", + "event.start": "2022-05-05T21:02:58.000Z", "event.timezone": "-02:00", "event.type": [ "info" @@ -2687,13 +2687,13 @@ "event.code": 302304, "event.dataset": "cisco.asa", "event.duration": 3602000000000, - "event.end": "2021-04-27T04:12:23.000-02:00", + "event.end": "2022-04-27T04:12:23.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-6-302304: Teardown TCP state-bypass connection 2751765169 from server.deflan:81.2.69.143/54242 to server.deflan:67.43.156.12/9101 duration 1:00:02 bytes 245 Connection timeout", "event.reason": "Connection timeout", "event.severity": 6, - "event.start": "2021-04-27T05:12:21.000Z", + "event.start": "2022-04-27T05:12:21.000Z", "event.timezone": "-02:00", "event.type": [ "connection", @@ -3228,13 +3228,13 @@ "event.code": 113019, "event.dataset": "cisco.asa", "event.duration": 1936000000000, - "event.end": "2021-04-27T02:03:03.000-02:00", + "event.end": "2022-04-27T02:03:03.000-02:00", "event.kind": "event", "event.module": "cisco", "event.original": "%ASA-4-113019: Group = 81.2.69.143, Username = 81.2.69.143, IP = 81.2.69.143, Session disconnected. Session Type: LAN-to-LAN, Duration: 0h:32m:16s, Bytes xmt: 297103, Bytes rcv: 1216163, Reason: User Requested", "event.reason": "User Requested", "event.severity": 4, - "event.start": "2021-04-27T03:30:47.000Z", + "event.start": "2022-04-27T03:30:47.000Z", "event.timezone": "-02:00", "event.type": [ "info" diff --git a/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json index 81c80ebf991e..ebd653dfbc07 100644 --- a/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -55,7 +54,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11757", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -116,7 +114,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11749", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -178,7 +175,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11748", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -240,7 +236,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11745", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -302,7 +297,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11744", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -364,7 +358,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11742", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -426,7 +419,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11738", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -488,7 +480,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11739", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -550,7 +541,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11731", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -612,7 +602,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11723", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -674,7 +663,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11715", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -736,7 +724,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11711", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -798,7 +785,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11712", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -860,7 +846,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11708", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -922,7 +907,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11746", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -984,7 +968,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11706", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1046,7 +1029,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11702", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1108,7 +1090,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11753", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1170,7 +1151,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1225,7 +1205,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11758", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1286,7 +1265,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11758", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1347,7 +1325,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11759", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1408,7 +1385,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11759", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1469,7 +1445,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1524,7 +1499,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11760", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1585,7 +1559,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1640,7 +1613,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11761", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1701,7 +1673,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11762", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1762,7 +1733,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11763", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1823,7 +1793,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11762", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1884,7 +1853,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11763", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1945,7 +1913,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2000,7 +1967,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11764", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2061,7 +2027,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2116,7 +2081,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11772", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2177,7 +2141,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11773", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2238,7 +2201,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11772", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2299,7 +2261,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11773", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2360,7 +2321,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2415,7 +2375,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11774", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2476,7 +2435,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11775", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2537,7 +2495,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11776", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2598,7 +2555,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11775", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2659,7 +2615,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11776", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2720,7 +2675,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2775,7 +2729,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11777", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2836,7 +2789,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11777", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -2898,7 +2850,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11779", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2959,7 +2910,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11778", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -3020,7 +2970,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11779", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -3081,7 +3030,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3136,7 +3084,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11780", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3197,7 +3144,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3252,7 +3198,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11781", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3313,7 +3258,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3368,7 +3312,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11782", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3429,7 +3372,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11783", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3490,7 +3432,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11783", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -3551,7 +3492,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3606,7 +3546,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11784", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3667,7 +3606,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3722,7 +3660,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11785", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3783,7 +3720,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11786", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3844,7 +3780,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11784", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -3906,7 +3841,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3961,7 +3895,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11787", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -4022,7 +3955,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11786", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -4083,7 +4015,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4138,7 +4069,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11788", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -4199,7 +4129,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4258,7 +4187,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4313,7 +4241,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11797", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.156.80", @@ -4374,7 +4301,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4433,7 +4359,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4492,7 +4417,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4551,7 +4475,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4610,7 +4533,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4669,7 +4591,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4728,7 +4649,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11564", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -4790,7 +4710,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11797", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -4852,7 +4771,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4907,7 +4825,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11798", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.156.80", @@ -4968,7 +4885,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5026,7 +4942,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5084,7 +4999,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5142,7 +5056,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5200,7 +5113,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5258,7 +5170,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5316,7 +5227,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5374,7 +5284,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5432,7 +5341,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5490,7 +5398,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5548,7 +5455,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5606,7 +5512,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5664,7 +5569,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5722,7 +5626,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -5777,7 +5680,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11799", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -5838,7 +5740,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -5893,7 +5794,6 @@ ] }, { - "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11800", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", diff --git a/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json index e959ed691457..598cd963c84b 100644 --- a/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2019-10-10T10:21:36.000-02:00", "cisco.asa.mapped_source_ip": "10.0.55.66", "cisco.asa.message_id": "302021", "destination.domain": "target.destination.hostname.local", @@ -48,7 +47,6 @@ ] }, { - "@timestamp": "2011-06-04T21:59:52.000-02:00", "cisco.asa.icmp_code": 0, "cisco.asa.icmp_type": 8, "cisco.asa.mapped_source_ip": "192.0.2.134", diff --git a/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json index 09357b0121bf..2301c80480a8 100644 --- a/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2019-10-04T15:27:55.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "AL-DMZ-LB-IN", @@ -53,7 +52,6 @@ ] }, { - "@timestamp": "2020-01-01T10:42:53.000-02:00", "cisco.asa.mapped_source_host": "mydomain.example.net", "cisco.asa.message_id": "302021", "destination.address": "172.24.177.29", @@ -102,7 +100,6 @@ ] }, { - "@timestamp": "2020-01-02T11:33:20.000-02:00", "cisco.asa.destination_interface": "wan", "cisco.asa.mapped_destination_host": "www.example.org", "cisco.asa.mapped_destination_port": 80, diff --git a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json index 65608c192ee3..70dc3befff2f 100644 --- a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2013-04-15T09:36:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_dmz", @@ -51,7 +50,6 @@ ] }, { - "@timestamp": "2013-04-15T09:36:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_dmz", @@ -102,7 +100,6 @@ ] }, { - "@timestamp": "2014-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -154,7 +151,6 @@ ] }, { - "@timestamp": "2013-04-24T16:00:28.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "inside", @@ -210,7 +206,6 @@ ] }, { - "@timestamp": "2013-04-24T16:00:27.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "inside", @@ -266,7 +261,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -314,7 +308,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743274", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.3.42", @@ -369,7 +362,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -417,7 +409,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743275", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.1.35", @@ -474,7 +465,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -522,7 +512,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743276", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.3.130", @@ -579,7 +568,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743275", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -633,7 +621,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "666", "cisco.asa.destination_interface": "inside", "cisco.asa.destination_username": "user2", @@ -696,7 +683,6 @@ "user.name": "user2" }, { - "@timestamp": "2011-06-04T21:59:52.000-02:00", "cisco.asa.mapped_source_ip": "192.168.132.46", "cisco.asa.message_id": "302021", "destination.address": "172.24.177.29", @@ -745,7 +731,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -793,7 +778,6 @@ ] }, { - "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743277", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "10.0.0.130", @@ -850,7 +834,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:33.000-02:00", "cisco.asa.message_id": "106007", "destination.address": "10.1.2.60", "destination.ip": "10.1.2.60", @@ -898,7 +881,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:38.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -949,7 +931,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:38.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1000,7 +981,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1051,7 +1031,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1102,7 +1081,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1153,7 +1131,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:40.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1204,7 +1181,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:41.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1255,7 +1231,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:47.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1306,7 +1281,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:48.000-02:00", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1357,7 +1331,6 @@ ] }, { - "@timestamp": "2013-04-30T09:22:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1408,7 +1381,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:02.000-02:00", "cisco.asa.message_id": "106006", "cisco.asa.source_interface": "inside", "destination.address": "10.1.2.42", @@ -1457,7 +1429,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:03.000-02:00", "cisco.asa.message_id": "106007", "destination.address": "10.1.5.60", "destination.ip": "10.1.5.60", @@ -1505,7 +1476,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:06.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1556,7 +1526,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:08.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1607,7 +1576,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:15.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1658,7 +1626,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1709,7 +1676,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1760,7 +1726,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:40.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_out", @@ -1811,7 +1776,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:41.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_out", @@ -1862,7 +1826,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:43.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1913,7 +1876,6 @@ ] }, { - "@timestamp": "2013-04-30T09:23:43.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1964,7 +1926,6 @@ ] }, { - "@timestamp": "2018-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -2016,7 +1977,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.connection_id": "447235", "cisco.asa.destination_interface": "identity", "cisco.asa.mapped_destination_ip": "10.0.13.13", @@ -2071,7 +2031,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2123,7 +2082,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2175,7 +2133,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_host": "OCSP_Server", @@ -2231,7 +2188,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_host": "OCSP_Server", @@ -2287,7 +2243,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2343,7 +2298,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.connection_id": "447234", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2399,7 +2353,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.connection_id": "447234", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2455,7 +2408,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.message_id": "106015", "cisco.asa.source_interface": "outside", "destination.address": "192.168.1.34", @@ -2504,7 +2456,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.message_id": "106015", "cisco.asa.source_interface": "outside", "destination.address": "192.168.1.34", @@ -2553,7 +2504,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2605,7 +2555,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_ip": "192.168.1.34", @@ -2660,7 +2609,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_ip": "192.168.1.34", @@ -2715,7 +2663,6 @@ ] }, { - "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2771,7 +2718,6 @@ ] }, { - "@timestamp": "2012-08-15T23:30:09.000-02:00", "cisco.asa.connection_id": "40", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2825,7 +2771,6 @@ ] }, { - "@timestamp": "2014-09-12T06:50:53.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -2873,7 +2818,6 @@ ] }, { - "@timestamp": "2014-09-12T06:51:01.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -2921,7 +2865,6 @@ ] }, { - "@timestamp": "2014-09-12T06:51:05.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -2969,7 +2912,6 @@ ] }, { - "@timestamp": "2014-09-12T06:51:05.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -3017,7 +2959,6 @@ ] }, { - "@timestamp": "2014-09-12T06:51:06.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -3065,7 +3006,6 @@ ] }, { - "@timestamp": "2014-09-12T06:51:17.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -3113,7 +3053,6 @@ ] }, { - "@timestamp": "2014-09-12T06:52:48.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.168.1.255", @@ -3161,7 +3100,6 @@ ] }, { - "@timestamp": "2014-09-12T06:53:00.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.168.1.255", @@ -3209,7 +3147,6 @@ ] }, { - "@timestamp": "2014-09-12T06:53:01.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "PERMIT_IN", @@ -3265,7 +3202,6 @@ ] }, { - "@timestamp": "2014-09-12T06:53:02.000-02:00", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, "cisco.asa.message_id": "313001", @@ -3314,7 +3250,6 @@ ] }, { - "@timestamp": "2015-01-14T13:16:13.000-02:00", "cisco.asa.icmp_type": 0, "cisco.asa.message_id": "313004", "cisco.asa.source_interface": "inside", @@ -3361,7 +3296,6 @@ ] }, { - "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "192.88.99.129", "cisco.asa.mapped_destination_port": 80, @@ -3424,7 +3358,6 @@ ] }, { - "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outsidet", "cisco.asa.mapped_destination_ip": "192.0.2.223", "cisco.asa.mapped_destination_port": 80, @@ -3482,7 +3415,6 @@ ] }, { - "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outsidet", "cisco.asa.mapped_destination_ip": "192.0.2.223", "cisco.asa.mapped_destination_port": 80, @@ -3541,7 +3473,6 @@ ] }, { - "@timestamp": "2009-11-16T14:12:35.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "192.0.2.1", "destination.ip": "192.0.2.1", @@ -3584,7 +3515,6 @@ "url.path": "/app" }, { - "@timestamp": "2009-11-16T14:12:36.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "192.0.2.32", "destination.ip": "192.0.2.32", @@ -3629,7 +3559,6 @@ "url.scheme": "http" }, { - "@timestamp": "2009-11-16T14:12:37.000-02:00", "cisco.asa.message_id": "304002", "cisco.asa.source_interface": "inside", "destination.address": "192.0.0.19", @@ -3677,7 +3606,6 @@ "url.scheme": "http" }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "27215708", "cisco.asa.destination_interface": "vlan-42", "cisco.asa.mapped_destination_ip": "81.2.69.143", @@ -3746,7 +3674,6 @@ ] }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "172.17.6.211", "destination.ip": "172.17.6.211", @@ -3796,7 +3723,6 @@ "url.scheme": "http" }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "195207391", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "89.160.20.156", @@ -3871,7 +3797,6 @@ ] }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "195207391", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "89.160.20.156", @@ -3950,7 +3875,6 @@ ] }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "LOCAL\\USER001", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -4015,7 +3939,6 @@ "user.name": "USER001" }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "LOCAL\\user@domain.tld", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -4085,7 +4008,6 @@ "user.name": "user@domain.tld" }, { - "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "AD\\USER002", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -4154,7 +4076,6 @@ "user.name": "USER002" }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "OUTSIDE", @@ -4213,7 +4134,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.icmp_code": 0, "cisco.asa.icmp_type": 134, "cisco.asa.mapped_source_ip": "fe80::2205:baff:fe9d:f637", @@ -4259,7 +4179,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "251933191", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "2a03:2880:f253:cb:face:b00c:0:43fe", @@ -4314,7 +4233,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "OUTSIDE", @@ -4385,7 +4303,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261246338", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "302014", @@ -4461,7 +4378,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261311655", "cisco.asa.destination_interface": "INSIDE", "cisco.asa.mapped_destination_ip": "192.168.0.1", @@ -4537,7 +4453,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261311655", "cisco.asa.destination_interface": "INSIDE", "cisco.asa.message_id": "302016", @@ -4611,7 +4526,6 @@ ] }, { - "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261246338", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "40.0.0.1", @@ -4687,7 +4601,6 @@ ] }, { - "@timestamp": "2021-07-29T08:35:29.000-02:00", "cisco.asa.message_id": "602304", "cisco.asa.tunnel_type": "LAN-to-LAN", "destination.address": "81.2.69.1452", diff --git a/x-pack/filebeat/module/sophos/fields.go b/x-pack/filebeat/module/sophos/fields.go index aa22bfaf89b7..b784d8fbff3b 100644 --- a/x-pack/filebeat/module/sophos/fields.go +++ b/x-pack/filebeat/module/sophos/fields.go @@ -19,5 +19,5 @@ func init() { // AssetSophos returns asset data. // This is the base64 encoded zlib format compressed contents of module/sophos. func AssetSophos() string { - return "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" + return "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" } diff --git a/x-pack/filebeat/module/sophos/xg/_meta/fields.yml b/x-pack/filebeat/module/sophos/xg/_meta/fields.yml index 47c90ce99671..d5716542bfab 100644 --- a/x-pack/filebeat/module/sophos/xg/_meta/fields.yml +++ b/x-pack/filebeat/module/sophos/xg/_meta/fields.yml @@ -943,3 +943,8 @@ type: keyword description: > The related XSS caught by the WAF + + - name: ether_type + type: keyword + description: > + The ethernet frame type diff --git a/x-pack/filebeat/module/sophos/xg/ingest/pipeline.yml b/x-pack/filebeat/module/sophos/xg/ingest/pipeline.yml index 3e1a5f518c2f..2db7a8ad8495 100644 --- a/x-pack/filebeat/module/sophos/xg/ingest/pipeline.yml +++ b/x-pack/filebeat/module/sophos/xg/ingest/pipeline.yml @@ -6,7 +6,7 @@ processors: - grok: field: message patterns: - - '%{SYSLOG5424PRI}%{GREEDYDATA:log.original}$' + - '%{SYSLOG5424PRI}(%{SYSLOGTIMESTAMP} %{NOTSPACE} )?%{GREEDYDATA:log.original}$' # optimize fields / strings in log.original for KV processor - gsub: @@ -17,7 +17,7 @@ processors: # split Sophos-XG fields - kv: field: log.original - field_split: " (?=[a-zA-Z0-9\\_\\-]+=)" + field_split: " (?=[a-zA-Z0-9_]+=)" value_split: "=" prefix: "sophos.xg." ignore_missing: true @@ -248,6 +248,10 @@ processors: - sophos.xg.dir_disp - sophos.xg.srczone - sophos.xg.dstzone + - sophos.xg.log_occurrence + - sophos.xg.nat_rule_id + - sophos.xg.in_display_interface + - sophos.xg.out_display_interface - syslog5424_pri ignore_missing: true diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log index 5480251c5041..f16aee764345 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log +++ b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log @@ -1,11 +1,11 @@ -<30>device="SFW" date=2020-05-18 time=14:38:48 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=041101618035 log_type="Anti-Spam" log_component="SMTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="firewall@firewallgate.com" to_email_address="Sysadmin@elasticuser.com" email_subject="*ALERT* Sophos XG Firewall" mailid="qkW2Y6-LxBk6U-vH-1590055245" mailsize=19728 spamaction="QUEUED" reason="Email has been accepted by Device and queued for scanning." src_domainname="elasticuser.com" dst_domainname="" src_ip="" src_country_code="" dst_ip="" dst_country_code="" protocol="TCP" src_port=0 dst_port=0 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" -<30>device="SFW" date=2020-05-18 time=14:38:49 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=041105613003 log_type="Anti-Spam" log_component="SMTP" log_subtype="Clean" status="" priority=Information fw_rule_id=22 user_name="" av_policy_name="Default" from_email_address="telekommunikation@constant-big.email" to_email_address="info@pelasticuser.com" email_subject="Telefonservice statt Anrufbeantworter" mailid="device="SFW" date=2020-05-18 time=14:38:50 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=041107413001 log_type="Anti-Spam" log_component="SMTP" log_subtype="Spam" status="" priority=Warning fw_rule_id=22 user_name="" av_policy_name="Spam" from_email_address="ripxfc@17buddies.net" to_email_address="hein.mueck@elasticuser.de" email_subject="nimm dringend Geld" mailid="device="SFW" date=2020-05-18 time=14:38:51 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=045908413004 log_type="Anti-Spam" log_component="SMTPS" log_subtype="Probable Spam" status="" priority=Warning fw_rule_id=22 user_name="" av_policy_name="rule3" from_email_address="SHERIF.TOBGI@ELTOBGI.COM" to_email_address="info@elasticuser.com" email_subject="09F1A19017 - 65T BP LNG Hybrid - TS-V-061-01 - HVAC Package - RFQ - BCD - 27-May-20" mailid="<20200518070235.C1623996C64F9957@ELTOBGI.COM>" mailsize=1032152 spamaction="Prefix Subject" reason="Sender IP address is blacklisted." src_domainname="ELTOBGI.COM" dst_domainname="" src_ip=67.43.156.14 src_country_code=GBR dst_ip=185.8.209.194 dst_country_code=DEU protocol="TCP" src_port=55002 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="RBL" -<30>device="SFW" date=2017-01-31 time=18:34:41 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=041113413005 log_type="Anti-Spam" log_component="SMTP" log_subtype="Outbound Spam" status="" priority=Warning fw_rule_id=0 user_name="gaurav" av_policy_name="Gaurav123" from_email_address="gaurav1@iview.com" to_email_address=" gaurav2@iview.com" email_subject="RPD Spam Test: Spam" mailid="" mailsize=405 spamaction="Accept" reason="" src_domainname=" iview.com" dst_domainname="" src_ip=10.198.47.71 src_country_code=R1 dst_ip=10.198.233.61 dst_country_code=R1 protocol="TCP" src_port=22420 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Spam" -<30>device="SFW" date=2018-06-06 time=11:10:11 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041114413006 log_type="Anti-Spam" log_component="SMTP" log_subtype="Outbound Probable Spam" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="rule 8" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman.local" email_subject="RPD Spam test: Bulk" mailid="" mailsize=439 spamaction="Drop" reason="Mail detected as OUTBOUND PROBABLE SPAM." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=58043 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Spam" -<30>device="SFW" date=2018-06-06 time=12:50:07 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041121613009 log_type="Anti-Spam" log_component="SMTP" log_subtype="DLP" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="postman" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman. local" email_subject="Fwd: TESt" mailid="c0000002-1528269606" mailsize=5041 spamaction="DROP" reason="Email containing confidential data detected. Relevant Data Protection Policy applied." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60134 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="DLP" -<30>device="SFW" date=2018-06-06 time=12:51:34 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041122613010 log_type="Anti-Spam" log_component="SMTP" log_subtype="SPX" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman.local" email_subject="[secure:pankhil]" mailid="c0000003-1528269693" mailsize=442 spamaction="Accept" reason="SPX Template of type Specified by Sender successfully applied on Email." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.16.204 dst_country_code=R1 protocol="TCP" src_port=60298 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" -<30>device="SFW" date=2018-06-06 time=12:53:39 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041123413012 log_type="Anti-Spam" log_component="SMTP" log_subtype="Dos" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="" to_email_address="" email_subject="" mailid="" mailsize=0 spamaction="TMPREJECT" reason="SMTP DoS" src_domainname="" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60392 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" -<30>device="SFW" date=2018-06-06 time=12:56:53 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041102413014 log_type="Anti-Spam" log_component="SMTP" log_subtype="Denied" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="postman" from_email_address="pankhil1@postman.local" to_email_address="pankhil@postman. local" email_subject="Fwd: test sand" mailid="c0000008-1528270010" mailsize=419835 spamaction="DROP" reason="Email is marked Malicious by Sophos Sandstorm." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60608 dst_port=25 sent_bytes=0 recv_bytes=0 -<30>device="SFW" date=2017-01-31 time=18:31:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=041207414001 log_type="Anti-Spam" log_component="POP3" log_subtype="Spam" status="" priority=Warning fw_rule_id=0 user_name="gaurav" av_policy_name="GauravPatel" from_email_address="gaurav1@iview.com" to_email_address="gaurav2@iview. com" email_subject="RPD Spam Test: Spam" mailid="<2a2dd5d4-1a30-617b-27b1-7961ad07cf07@iview.com>" mailsize=574 spamaction="Accept" reason="" src_domainname=" iview.com" dst_domainname="iview.com" src_ip=10.198.47.71 src_country_code=R1 dst_ip=10.198.233.61 dst_country_code=R1 protocol="TCP" src_port=22333 dst_port=110 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2020-05-18 time=14:38:48 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=041101618035 log_type="Anti-Spam" log_component="SMTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="firewall@firewallgate.com" to_email_address="Sysadmin@elasticuser.com" email_subject="*ALERT* Sophos XG Firewall" mailid="qkW2Y6-LxBk6U-vH-1590055245" mailsize=19728 spamaction="QUEUED" reason="Email has been accepted by Device and queued for scanning." src_domainname="elasticuser.com" dst_domainname="" src_ip="" src_country_code="" dst_ip="" dst_country_code="" protocol="TCP" src_port=0 dst_port=0 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2020-05-18 time=14:38:49 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=041105613003 log_type="Anti-Spam" log_component="SMTP" log_subtype="Clean" status="" priority=Information fw_rule_id=22 user_name="" av_policy_name="Default" from_email_address="telekommunikation@constant-big.email" to_email_address="info@pelasticuser.com" email_subject="Telefonservice statt Anrufbeantworter" mailid="device="SFW" date=2020-05-18 time=14:38:50 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=041107413001 log_type="Anti-Spam" log_component="SMTP" log_subtype="Spam" status="" priority=Warning fw_rule_id=22 user_name="" av_policy_name="Spam" from_email_address="ripxfc@17buddies.net" to_email_address="hein.mueck@elasticuser.de" email_subject="nimm dringend Geld" mailid="device="SFW" date=2020-05-18 time=14:38:51 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=045908413004 log_type="Anti-Spam" log_component="SMTPS" log_subtype="Probable Spam" status="" priority=Warning fw_rule_id=22 user_name="" av_policy_name="rule3" from_email_address="SHERIF.TOBGI@ELTOBGI.COM" to_email_address="info@elasticuser.com" email_subject="09F1A19017 - 65T BP LNG Hybrid - TS-V-061-01 - HVAC Package - RFQ - BCD - 27-May-20" mailid="<20200518070235.C1623996C64F9957@ELTOBGI.COM>" mailsize=1032152 spamaction="Prefix Subject" reason="Sender IP address is blacklisted." src_domainname="ELTOBGI.COM" dst_domainname="" src_ip=67.43.156.14 src_country_code=GBR dst_ip=185.8.209.194 dst_country_code=DEU protocol="TCP" src_port=55002 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="RBL" +<30>device="SFW" date=2017-01-31 time=18:34:41 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=041113413005 log_type="Anti-Spam" log_component="SMTP" log_subtype="Outbound Spam" status="" priority=Warning fw_rule_id=0 user_name="gaurav" av_policy_name="Gaurav123" from_email_address="gaurav1@iview.com" to_email_address=" gaurav2@iview.com" email_subject="RPD Spam Test: Spam" mailid="" mailsize=405 spamaction="Accept" reason="" src_domainname=" iview.com" dst_domainname="" src_ip=10.198.47.71 src_country_code=R1 dst_ip=10.198.233.61 dst_country_code=R1 protocol="TCP" src_port=22420 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Spam" +<30>device="SFW" date=2018-06-06 time=11:10:11 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041114413006 log_type="Anti-Spam" log_component="SMTP" log_subtype="Outbound Probable Spam" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="rule 8" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman.local" email_subject="RPD Spam test: Bulk" mailid="" mailsize=439 spamaction="Drop" reason="Mail detected as OUTBOUND PROBABLE SPAM." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=58043 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Spam" +<30>device="SFW" date=2018-06-06 time=12:50:07 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041121613009 log_type="Anti-Spam" log_component="SMTP" log_subtype="DLP" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="postman" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman. local" email_subject="Fwd: TESt" mailid="c0000002-1528269606" mailsize=5041 spamaction="DROP" reason="Email containing confidential data detected. Relevant Data Protection Policy applied." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60134 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="DLP" +<30>device="SFW" date=2018-06-06 time=12:51:34 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041122613010 log_type="Anti-Spam" log_component="SMTP" log_subtype="SPX" status="" priority=Information fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="pankhil1@Postman.local" email_subject="[secure:pankhil]" mailid="c0000003-1528269693" mailsize=442 spamaction="Accept" reason="SPX Template of type Specified by Sender successfully applied on Email." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.16.204 dst_country_code=R1 protocol="TCP" src_port=60298 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2018-06-06 time=12:53:39 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041123413012 log_type="Anti-Spam" log_component="SMTP" log_subtype="Dos" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="" to_email_address="" email_subject="" mailid="" mailsize=0 spamaction="TMPREJECT" reason="SMTP DoS" src_domainname="" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60392 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2018-06-06 time=12:56:53 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=041102413014 log_type="Anti-Spam" log_component="SMTP" log_subtype="Denied" status="" priority=Warning fw_rule_id=0 user_name="" av_policy_name="postman" from_email_address="pankhil1@postman.local" to_email_address="pankhil@postman. local" email_subject="Fwd: test sand" mailid="c0000008-1528270010" mailsize=419835 spamaction="DROP" reason="Email is marked Malicious by Sophos Sandstorm." src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.17.121 dst_country_code=R1 protocol="TCP" src_port=60608 dst_port=25 sent_bytes=0 recv_bytes=0 +<30>device="SFW" date=2017-01-31 time=18:31:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=041207414001 log_type="Anti-Spam" log_component="POP3" log_subtype="Spam" status="" priority=Warning fw_rule_id=0 user_name="gaurav" av_policy_name="GauravPatel" from_email_address="gaurav1@iview.com" to_email_address="gaurav2@iview. com" email_subject="RPD Spam Test: Spam" mailid="<2a2dd5d4-1a30-617b-27b1-7961ad07cf07@iview.com>" mailsize=574 spamaction="Accept" reason="" src_domainname=" iview.com" dst_domainname="iview.com" src_ip=10.198.47.71 src_country_code=R1 dst_ip=10.198.233.61 dst_country_code=R1 protocol="TCP" src_port=22333 dst_port=110 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json index 04f1bad3aac6..3a12b85cdc75 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:48.000-02:00", "client.bytes": 0, "client.port": 0, "destination.bytes": 0, @@ -63,7 +62,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:49.000-02:00", "client.bytes": 0, "client.ip": "89.160.20.156", "client.port": 52742, @@ -91,7 +89,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 748, + "log.offset": 747, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -142,7 +140,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:50.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.port": 51789, @@ -172,7 +169,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "warning", - "log.offset": 1541, + "log.offset": 1539, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -219,7 +216,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:51.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.14", "client.port": 55002, @@ -249,7 +245,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "warning", - "log.offset": 2295, + "log.offset": 2292, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -296,7 +292,6 @@ ] }, { - "@timestamp": "2017-01-31T18:34:41.000-02:00", "client.bytes": 0, "client.ip": "10.198.47.71", "client.port": 22420, @@ -326,7 +321,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 3125, + "log.offset": 3121, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "C44313350024-P29PUA", @@ -367,7 +362,6 @@ ] }, { - "@timestamp": "2018-06-06T11:10:11.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 58043, @@ -397,7 +391,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 3854, + "log.offset": 3849, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -438,7 +432,6 @@ ] }, { - "@timestamp": "2018-06-06T12:50:07.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60134, @@ -468,7 +461,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 4629, + "log.offset": 4623, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -509,7 +502,6 @@ ] }, { - "@timestamp": "2018-06-06T12:51:34.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60298, @@ -537,7 +529,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 5391, + "log.offset": 5384, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -578,7 +570,6 @@ ] }, { - "@timestamp": "2018-06-06T12:53:39.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60392, @@ -607,7 +598,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 6145, + "log.offset": 6137, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -644,7 +635,6 @@ ] }, { - "@timestamp": "2018-06-06T12:56:53.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60608, @@ -674,7 +664,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 6742, + "log.offset": 6733, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -714,7 +704,6 @@ ] }, { - "@timestamp": "2017-01-31T18:31:11.000-02:00", "client.bytes": 0, "client.ip": "10.198.47.71", "client.port": 22333, @@ -744,7 +733,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 7447, + "log.offset": 7437, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "C44313350024-P29PUA", diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log index 22ff5a6791f5..e5271e5d2f4e 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log +++ b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log @@ -1,9 +1,9 @@ -<30>device="SFW" date=2020-05-18 time=14:38:33 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=030906208001 log_type="Anti-Virus" log_component="HTTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=2 user_name="" iap=13 av_policy_name="" virus="Sandstorm" url="http://sophostest.com/Sandstorm/SBTestFile1.pdf" domainname="sophostest.com" src_ip=172.16.34.24 src_country_code=R1 dst_ip=13.226.155.93 dst_country_code=USA protocol="TCP" src_port=57695 dst_port=80 sent_bytes=550 recv_bytes=1616 user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" status_code=403 -<30>device="SFW" date=2020-05-18 time=14:38:34 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=030906208001 log_type="Anti-Virus" log_component="HTTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=2 user_name="" iap=13 av_policy_name="" virus="EICAR-AV-Test" url="http://sophostest.com/eicar/index.html" domainname="sophostest.com" src_ip=172.16.34.24 src_country_code=R1 dst_ip=13.226.155.18 dst_country_code=USA protocol="TCP" src_port=57835 dst_port=80 sent_bytes=541 recv_bytes=553 user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" status_code=403 -<30>device="SFW" date=2020-05-18 time=14:38:35 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=031106210001 log_type="Anti-Virus" log_component="SMTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=22 user_name="" av_policy_name="default-smtp-av" from_email_address="info@farasamed.com" to_email_address="info@elastic-user.local" subject="ZAHLUNG (PROFORMA INVOICE)" mailid="<20200520004312.Horde.lEUeVf2I6PwO5K5TtMndnC7@webmail.sevengayr" mailsize=2254721 virus="TR/AD.AgentTesla.eaz" filename="" quarantine="" src_domainname="farasamed.com" dst_domainname="" src_ip=1.128.3.4 src_country_code=DEU dst_ip=186.8.209.194 dst_country_code=DEU protocol="TCP" src_port=56336 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Infected" -<30>device="SFW" date=2020-05-18 time=14:38:36 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=031106210001 log_type="Anti-Virus" log_component="SMTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=22 user_name="" av_policy_name="default-smtp-av" from_email_address="spedizioni@divella.it" to_email_address="info@elastic-user.local" subject="Re: NEW PRO-FORMA INVOICE" mailid="<20200519072944.AFCA295AF2A037A6@divella.it>" mailsize=537457 virus="Mal/BredoZp-B" filename="" quarantine="" src_domainname="divella.it" dst_domainname="" src_ip=216.160.83.61 src_country_code=USA dst_ip=185.7.209.194 dst_country_code=DEU protocol="TCP" src_port=54693 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Infected" -<30>device="SFW" date=2018-06-06 time=10:51:29 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=036106211001 log_type="Anti-Virus" log_component="POPS" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="pankhil@postman.local" subject="EICAR" mailid="" mailsize=0 virus="EICAR-AV-Test" filename="" quarantine="" src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=56653 dst_port=995 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" -<30>device="SFW" date=2018-06-06 time=10:58:29 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=036206212001 log_type="Anti-Virus" log_component="IMAPS" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="ganga@postman.local" subject="EICAR test email" mailid="<2ca37b7c-e93a-743a-99c4-a0796f0bbb79@postman.local>" mailsize=0 virus="EICAR-AV-Test" filename="" quarantine="" src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=56632 dst_port=993 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" -<30>device="SFW" date=2018-06-21 time=19:50:23 timezone="CEST" device_name="SF01V" device_id=SFDemo-2df0960 log_id=031006209001 log_type="Anti-Virus" log_component="FTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" virus="EICAR-AV-Test" FTP_url="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" FTP_direction="Upload" filename=" /home/ftp-user/ta_test_file_1ta-cl1-46" file_size=0 file_path="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" ftpcommand="STOR" src_ip=10.146.13.49 src_country_code=R1 dst_ip=10.8.142.181 dst_country_code=R1 protocol="TCP" src_port=39910 dst_port=21 dstdomain="" sent_bytes=0 recv_bytes=0 -<30>device="SFW" date=2018-06-21 time=19:50:48 timezone="CEST" device_name="SF01V" device_id=SFDemo-2df0960 log_id=031001609002 log_type="Anti-Virus" log_component="FTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=0 user_name="" virus="" FTP_url="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" FTP_direction="Download" filename="/home/ftp-user /ta_test_file_1ta-cl1-46" file_size=19926248 file_path="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" ftpcommand="RETR" src_ip=10.146.13.49 src_country_code= dst_ip=10.8.142.181 dst_country_code= protocol="TCP" src_port=39936 dst_port=21 dstdomain="" sent_bytes=0 recv_bytes=19926248 - +<30>device="SFW" date=2020-05-18 time=14:38:33 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=030906208001 log_type="Anti-Virus" log_component="HTTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=2 user_name="" iap=13 av_policy_name="" virus="Sandstorm" url="http://sophostest.com/Sandstorm/SBTestFile1.pdf" domainname="sophostest.com" src_ip=172.16.34.24 src_country_code=R1 dst_ip=13.226.155.93 dst_country_code=USA protocol="TCP" src_port=57695 dst_port=80 sent_bytes=550 recv_bytes=1616 user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" status_code=403 +<30>device="SFW" date=2020-05-18 time=14:38:34 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=030906208001 log_type="Anti-Virus" log_component="HTTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=2 user_name="" iap=13 av_policy_name="" virus="EICAR-AV-Test" url="http://sophostest.com/eicar/index.html" domainname="sophostest.com" src_ip=172.16.34.24 src_country_code=R1 dst_ip=13.226.155.18 dst_country_code=USA protocol="TCP" src_port=57835 dst_port=80 sent_bytes=541 recv_bytes=553 user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" status_code=403 +<30>device="SFW" date=2020-05-18 time=14:38:35 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=031106210001 log_type="Anti-Virus" log_component="SMTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=22 user_name="" av_policy_name="default-smtp-av" from_email_address="info@farasamed.com" to_email_address="info@elastic-user.local" subject="ZAHLUNG (PROFORMA INVOICE)" mailid="<20200520004312.Horde.lEUeVf2I6PwO5K5TtMndnC7@webmail.sevengayr" mailsize=2254721 virus="TR/AD.AgentTesla.eaz" filename="" quarantine="" src_domainname="farasamed.com" dst_domainname="" src_ip=1.128.3.4 src_country_code=DEU dst_ip=186.8.209.194 dst_country_code=DEU protocol="TCP" src_port=56336 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Infected" +<30>device="SFW" date=2020-05-18 time=14:38:36 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=031106210001 log_type="Anti-Virus" log_component="SMTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=22 user_name="" av_policy_name="default-smtp-av" from_email_address="spedizioni@divella.it" to_email_address="info@elastic-user.local" subject="Re: NEW PRO-FORMA INVOICE" mailid="<20200519072944.AFCA295AF2A037A6@divella.it>" mailsize=537457 virus="Mal/BredoZp-B" filename="" quarantine="" src_domainname="divella.it" dst_domainname="" src_ip=216.160.83.61 src_country_code=USA dst_ip=185.7.209.194 dst_country_code=DEU protocol="TCP" src_port=54693 dst_port=25 sent_bytes=0 recv_bytes=0 quarantine_reason="Infected" +<30>device="SFW" date=2018-06-06 time=10:51:29 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=036106211001 log_type="Anti-Virus" log_component="POPS" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="pankhil@postman.local" subject="EICAR" mailid="" mailsize=0 virus="EICAR-AV-Test" filename="" quarantine="" src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=56653 dst_port=995 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2018-06-06 time=10:58:29 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=036206212001 log_type="Anti-Virus" log_component="IMAPS" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" av_policy_name="None" from_email_address="pankhil@postman.local" to_email_address="ganga@postman.local" subject="EICAR test email" mailid="<2ca37b7c-e93a-743a-99c4-a0796f0bbb79@postman.local>" mailsize=0 virus="EICAR-AV-Test" filename="" quarantine="" src_domainname="postman.local" dst_domainname="" src_ip=10.198.16.121 src_country_code=R1 dst_ip=10.198.234.240 dst_country_code=R1 protocol="TCP" src_port=56632 dst_port=993 sent_bytes=0 recv_bytes=0 quarantine_reason="Other" +<30>device="SFW" date=2018-06-21 time=19:50:23 timezone="CEST" device_name="SF01V" device_id=SFDemo-2df0960 log_id=031006209001 log_type="Anti-Virus" log_component="FTP" log_subtype="Virus" status="" priority=Critical fw_rule_id=0 user_name="" virus="EICAR-AV-Test" FTP_url="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" FTP_direction="Upload" filename=" /home/ftp-user/ta_test_file_1ta-cl1-46" file_size=0 file_path="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" ftpcommand="STOR" src_ip=10.146.13.49 src_country_code=R1 dst_ip=10.8.142.181 dst_country_code=R1 protocol="TCP" src_port=39910 dst_port=21 dstdomain="" sent_bytes=0 recv_bytes=0 +<30>device="SFW" date=2018-06-21 time=19:50:48 timezone="CEST" device_name="SF01V" device_id=SFDemo-2df0960 log_id=031001609002 log_type="Anti-Virus" log_component="FTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=0 user_name="" virus="" FTP_url="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" FTP_direction="Download" filename="/home/ftp-user /ta_test_file_1ta-cl1-46" file_size=19926248 file_path="/var/www//home/ftp-user/ta_test_file_1ta-cl1-46" ftpcommand="RETR" src_ip=10.146.13.49 src_country_code= dst_ip=10.8.142.181 dst_country_code= protocol="TCP" src_port=39936 dst_port=21 dstdomain="" sent_bytes=0 recv_bytes=19926248 + diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json index 70d803619d12..e21ac56d23d1 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:33.000-02:00", "client.bytes": 550, "client.ip": "172.16.34.24", "client.port": 57695, @@ -74,7 +73,6 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" }, { - "@timestamp": "2020-05-18T14:38:34.000-02:00", "client.bytes": 541, "client.ip": "172.16.34.24", "client.port": 57835, @@ -104,7 +102,7 @@ "http.response.status_code": 403, "input.type": "log", "log.level": "critical", - "log.offset": 673, + "log.offset": 672, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -148,7 +146,6 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" }, { - "@timestamp": "2020-05-18T14:38:35.000-02:00", "client.bytes": 0, "client.ip": "1.128.3.4", "client.port": 56336, @@ -178,7 +175,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "critical", - "log.offset": 1340, + "log.offset": 1338, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -224,7 +221,6 @@ "url.domain": "farasamed.com" }, { - "@timestamp": "2020-05-18T14:38:36.000-02:00", "client.bytes": 0, "client.ip": "216.160.83.61", "client.port": 54693, @@ -254,7 +250,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "critical", - "log.offset": 2113, + "log.offset": 2110, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -307,7 +303,6 @@ "url.domain": "divella.it" }, { - "@timestamp": "2018-06-06T10:51:29.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 56653, @@ -337,7 +332,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 2862, + "log.offset": 2858, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -381,7 +376,6 @@ "url.domain": "postman.local" }, { - "@timestamp": "2018-06-06T10:58:29.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 56632, @@ -411,7 +405,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 3578, + "log.offset": 3573, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", @@ -455,7 +449,6 @@ "url.domain": "postman.local" }, { - "@timestamp": "2018-06-21T19:50:23.000-02:00", "client.bytes": 0, "client.ip": "10.146.13.49", "client.port": 39910, @@ -487,7 +480,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 4304, + "log.offset": 4298, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "SFDemo-2df0960", @@ -527,7 +520,6 @@ ] }, { - "@timestamp": "2018-06-21T19:50:48.000-02:00", "client.bytes": 0, "client.ip": "10.146.13.49", "client.port": 39936, @@ -557,7 +549,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 4954, + "log.offset": 4947, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "SFDemo-2df0960", diff --git a/x-pack/filebeat/module/sophos/xg/test/atp.log b/x-pack/filebeat/module/sophos/xg/test/atp.log index 10f65b6bd5af..315085205769 100644 --- a/x-pack/filebeat/module/sophos/xg/test/atp.log +++ b/x-pack/filebeat/module/sophos/xg/test/atp.log @@ -1,5 +1,5 @@ -<30>device="SFW" date=2017-01-31 time=18:44:31 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=086304418010 log_type="ATP" log_component="Firewall" log_subtype="Drop" priority=Warning user_name="jsmith" protocol="TCP" src_port=22623 dst_port=80 sourceip=10.198.47.71 destinationip=46.161.30.47 url=46.161.30.47 threatname=C2/Generic-A eventid=C366ACFB-7A6F-4870-B359-A6CFDA8C85F7 eventtype="Standard" login_user="" process_user="" ep_uuid= execution_path="" -<30>device="SFW" date=2020-05-18 time=14:38:34 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=086504418010 log_type="ATP" log_component="Web" log_subtype="Drop" priority=Warning user_name="" protocol="TCP" src_port=57579 dst_port=80 sourceip=172.16.34.24 destinationip=13.226.155.22 url=http://sophostest.com/callhome/index.html threatname=C2/Generic-A eventid=E91DAD80-BDE4-4682-B7E8-FE394B70A36C eventtype="Standard" login_user="" process_user="" ep_uuid="" execution_path="" -<30>device="SFW" date=2020-05-18 time=14:38:35 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=086504418010 log_type="ATP" log_component="Web" log_subtype="Drop" priority=Warning user_name="" protocol="TCP" src_port=57540 dst_port=80 sourceip=172.16.34.24 destinationip=13.226.155.22 url=http://sophostest.com/callhome/index.html threatname=C2/Generic-A eventid=34AC8531-E7C0-4368-9978-5740952EE9AB eventtype="Standard" login_user="" process_user="" ep_uuid="" execution_path="" -<30>device="SFW" date=2018-06-05 time=08:49:00 timezone="BST" device_name="XG310" device_id=C30006T22TGR89B log_id=086320518009 log_type="ATP" log_component="Firewall" log_subtype="Alert" priority=Notice user_name="" protocol="ICMP" src_port=0 dst_port=0 sourceip=10.198.32.89 destinationip=82.211.30.202 url=82.211.30.202 threatname=C2/Generic-A eventid=C7E26E6F-0097-4EA2-89DE-C31C40636CB2 eventtype="Standard" login_user="" process_user="" ep_uuid= execution_path="" - +<30>device="SFW" date=2017-01-31 time=18:44:31 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=086304418010 log_type="ATP" log_component="Firewall" log_subtype="Drop" priority=Warning user_name="jsmith" protocol="TCP" src_port=22623 dst_port=80 sourceip=10.198.47.71 destinationip=46.161.30.47 url=46.161.30.47 threatname=C2/Generic-A eventid=C366ACFB-7A6F-4870-B359-A6CFDA8C85F7 eventtype="Standard" login_user="" process_user="" ep_uuid= execution_path="" +<30>device="SFW" date=2020-05-18 time=14:38:34 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=086504418010 log_type="ATP" log_component="Web" log_subtype="Drop" priority=Warning user_name="" protocol="TCP" src_port=57579 dst_port=80 sourceip=172.16.34.24 destinationip=13.226.155.22 url=http://sophostest.com/callhome/index.html threatname=C2/Generic-A eventid=E91DAD80-BDE4-4682-B7E8-FE394B70A36C eventtype="Standard" login_user="" process_user="" ep_uuid="" execution_path="" +<30>device="SFW" date=2020-05-18 time=14:38:35 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=086504418010 log_type="ATP" log_component="Web" log_subtype="Drop" priority=Warning user_name="" protocol="TCP" src_port=57540 dst_port=80 sourceip=172.16.34.24 destinationip=13.226.155.22 url=http://sophostest.com/callhome/index.html threatname=C2/Generic-A eventid=34AC8531-E7C0-4368-9978-5740952EE9AB eventtype="Standard" login_user="" process_user="" ep_uuid="" execution_path="" +<30>device="SFW" date=2018-06-05 time=08:49:00 timezone="BST" device_name="XG310" device_id=C30006T22TGR89B log_id=086320518009 log_type="ATP" log_component="Firewall" log_subtype="Alert" priority=Notice user_name="" protocol="ICMP" src_port=0 dst_port=0 sourceip=10.198.32.89 destinationip=82.211.30.202 url=82.211.30.202 threatname=C2/Generic-A eventid=C7E26E6F-0097-4EA2-89DE-C31C40636CB2 eventtype="Standard" login_user="" process_user="" ep_uuid= execution_path="" + diff --git a/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json index 8bfa784dcae3..61f202c8826b 100644 --- a/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2017-01-31T18:44:31.000-02:00", "client.ip": "10.198.47.71", "client.port": 22623, "destination.ip": "46.161.30.47", @@ -65,7 +64,6 @@ "url.original": "46.161.30.47" }, { - "@timestamp": "2020-05-18T14:38:34.000-02:00", "client.ip": "172.16.34.24", "client.port": 57579, "destination.ip": "13.226.155.22", @@ -92,7 +90,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "warning", - "log.offset": 489, + "log.offset": 488, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -130,7 +128,6 @@ "url.scheme": "http" }, { - "@timestamp": "2020-05-18T14:38:35.000-02:00", "client.ip": "172.16.34.24", "client.port": 57540, "destination.ip": "13.226.155.22", @@ -157,7 +154,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "warning", - "log.offset": 991, + "log.offset": 989, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -195,7 +192,6 @@ "url.scheme": "http" }, { - "@timestamp": "2018-06-05T08:49:00.000-02:00", "client.ip": "10.198.32.89", "client.port": 0, "destination.ip": "82.211.30.202", @@ -222,7 +218,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "notification", - "log.offset": 1493, + "log.offset": 1490, "network.transport": "icmp", "observer.product": "XG", "observer.serial_number": "C30006T22TGR89B", diff --git a/x-pack/filebeat/module/sophos/xg/test/cfilter.log b/x-pack/filebeat/module/sophos/xg/test/cfilter.log index 2cbc3304fe39..03f021b90088 100644 --- a/x-pack/filebeat/module/sophos/xg/test/cfilter.log +++ b/x-pack/filebeat/module/sophos/xg/test/cfilter.log @@ -1,10 +1,10 @@ -<30>device="SFW" date=2017-01-31 time=14:03:33 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="jsmith" user_gp="Open Group" iap=1 category="Entertainment" category_type="Unproductive" url="https://r8---sn-ci5gup-qxas.googlevideo.com/" contenttype="" override_token="" httpresponsecode="" src_ip=10.198.47.71 dst_ip=182.79.221.19 protocol="TCP" src_port=9444 dst_port=443 sent_bytes=0 recv_bytes=319007 domain=r8---sn-ci5gup-qxas.googlevideo.com exceptions= activityname="" reason="" -<30>device="SFW" date=2017-02-01 time=18:20:21 timezone="IST" device_name="SG115" device_id=S110000E28BA631 log_id=050902616002 log_type="Content Filtering" log_component="HTTP" log_subtype="Denied" status="" priority=Information fw_rule_id=1 user_name="" user_gp="" iap=13 category="Religion & Spirituality" category_type="Unproductive" url="http://hanuman.com/" contenttype="" override_token="" httpresponsecode="" src_ip=216.160.83.57 dst_ip=216.58.197.44 protocol="TCP" src_port=46719 dst_port=80 sent_bytes=0 recv_bytes=0 domain=hanuman.com exceptions= activityname="" -<30>device="SFW" date=2017-02-01 time=18:13:29 timezone="IST" device_name="SG115" device_id=S110016E28BA631 log_id=054402617051 log_type="Content Filtering" log_component="Application" log_subtype="Denied" priority=Information fw_rule_id=1 user_name="" user_gp="" application_filter_policy=8 category="Mobile Applications" application_name="Gtalk Android" application_risk=4 application_technology="Client Server" application_category="Mobile Applications" src_ip=216.160.83.57 src_country_code=DEU dst_ip=74.125.130.188 dst_country_code=USA protocol="TCP" src_port=49128 dst_port=5228 sent_bytes=0 recv_bytes=0 status="Deny" message="" -<30>device="SFW" date=2020-05-18 time=14:38:51 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="" user_gp="" iap=13 category="Information Technology" category_type="Acceptable" url="https://his-eur1-neur1.servicebus.windows.net/$servicebus/websocket" contenttype="" override_token="" httpresponsecode="" src_ip=172.17.34.10 dst_ip=13.79.168.201 protocol="TCP" src_port=62851 dst_port=443 sent_bytes=259 recv_bytes=168 domain=his-eur1-neur1.servicebus.windows.net exceptions="" activityname="" reason="" user_agent="" status_code="400" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=80042000 application="" app_is_cloud=0 override_name="" override_authorizer="" -<30>device="SFW" date=2020-05-18 time=14:38:52 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=050902616002 log_type="Content Filtering" log_component="HTTP" log_subtype="Denied" status="" priority=Information fw_rule_id=51 user_name="" user_gp="" iap=2 category="IPAddress" category_type="Acceptable" url="https://40.90.137.127/" contenttype="" override_token="" httpresponsecode="" src_ip=172.16.34.15 dst_ip=40.90.137.127 protocol="TCP" src_port=60471 dst_port=443 sent_bytes=0 recv_bytes=0 domain=40.90.137.127 exceptions="" activityname="" reason="" user_agent="" status_code="200" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=642960832 application="" app_is_cloud=0 override_name="" override_authorizer="" -<30>device="SFW" date=2020-05-18 time=14:38:53 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="" user_gp="" iap=13 category="Information Technology" category_type="Acceptable" url="http://update.eset.com/eset_upd/ep7/dll/update.ver.signed" contenttype="" override_token="" httpresponsecode="" src_ip=1.128.3.4 dst_ip=91.228.167.133 protocol="TCP" src_port=65391 dst_port=80 sent_bytes=980 recv_bytes=295 domain=update.eset.com exceptions=av,https,sandstorm activityname="" reason="" user_agent="EFSW Update (Windows; U; 64bit; BPC 7.1.12010.0; OS: 10.0.17763 SP 0.0 NT; TDB 45511; CL 1.1.1; x64s; APP efsw; PX 1; PUA 1; CD 1; RA 1; PEV 0; UNS 1; UBR 1158; HVCI 0; SHA256 1; WU 3; HWF: 01009DAA-757A-D666-EFD2-92DD0D501284; PLOC de_de; PCODE 211.0.0; " status_code="304" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=248426360 application="" app_is_cloud=0 override_name="" override_authorizer="" -<30>device="SFW" date=2016-12-02 time=18:50:20 timezone="GMT" device_name="SF01V" device_id=1234567890123456 log_id=058420116010 log_type="Content Filtering" log_component="Web Content Policy" log_subtype="Alert" user="gi123456" src_ip=10.108.108.49 transaction_id="e4a127f7-a850-477c-920e-a471b38727c1" dictionary_name="complicated_Custom" site_category=Information Technology website="ta-web-static-testing.qa. astaro.de" direction="in" action="Deny" file_name="cgi_echo.pl" context_match="Not" context_prefix="blah blah hello " context_suffix=" hello blah " -<30>device="SFW" date=2016-12-02 time=18:50:20 timezone="GMT" device_name="SFVUNL" device_id=C01001K234RXPA1 log_id=050927616005 log_type="Content Filtering" log_component="HTTP" log_subtype="Warned" status="" priority=Information fw_rule_id=2 user_name="rich" user_gp="Clientless Open Group" iap=13 category="Search Engines" category_type="Acceptable" url="http://www.google.com/" contenttype="" override_token="" httpresponsecode="" src_ip=192.168.73.220 dst_ip=64.233.189.147 protocol="TCP" src_port=37832 dst_port=80 sent_bytes=0 recv_bytes=0 domain=www.google.com exceptions= activityname=" Search" reason="" -<30>device="SFW" date=2016-12-02 time=18:50:22 timezone="GMT" device_name="SFVUNL" device_id=C01001K234RXPA1 log_id=050901616006 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="rich" user_gp="Clientless Open Group" iap=13 category="Search Engines" category_type="Acceptable" url="http://www.google.ca/?gfe_rd=cr&ei=ojxHWP3WC4WN8QeRioDABw" contenttype="text/html" override_token="" httpresponsecode="" src_ip=192.168.73.220 dst_ip=64.233.188.94 protocol="TCP" src_port=46322 dst_port=80 sent_bytes=0 recv_bytes=619 domain=www.google.ca exceptions= activityname="Search" reason="not eligible" - +<30>device="SFW" date=2017-01-31 time=14:03:33 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="jsmith" user_gp="Open Group" iap=1 category="Entertainment" category_type="Unproductive" url="https://r8---sn-ci5gup-qxas.googlevideo.com/" contenttype="" override_token="" httpresponsecode="" src_ip=10.198.47.71 dst_ip=182.79.221.19 protocol="TCP" src_port=9444 dst_port=443 sent_bytes=0 recv_bytes=319007 domain=r8---sn-ci5gup-qxas.googlevideo.com exceptions= activityname="" reason="" +<30>device="SFW" date=2017-02-01 time=18:20:21 timezone="IST" device_name="SG115" device_id=S110000E28BA631 log_id=050902616002 log_type="Content Filtering" log_component="HTTP" log_subtype="Denied" status="" priority=Information fw_rule_id=1 user_name="" user_gp="" iap=13 category="Religion & Spirituality" category_type="Unproductive" url="http://hanuman.com/" contenttype="" override_token="" httpresponsecode="" src_ip=216.160.83.57 dst_ip=216.58.197.44 protocol="TCP" src_port=46719 dst_port=80 sent_bytes=0 recv_bytes=0 domain=hanuman.com exceptions= activityname="" +<30>device="SFW" date=2017-02-01 time=18:13:29 timezone="IST" device_name="SG115" device_id=S110016E28BA631 log_id=054402617051 log_type="Content Filtering" log_component="Application" log_subtype="Denied" priority=Information fw_rule_id=1 user_name="" user_gp="" application_filter_policy=8 category="Mobile Applications" application_name="Gtalk Android" application_risk=4 application_technology="Client Server" application_category="Mobile Applications" src_ip=216.160.83.57 src_country_code=DEU dst_ip=74.125.130.188 dst_country_code=USA protocol="TCP" src_port=49128 dst_port=5228 sent_bytes=0 recv_bytes=0 status="Deny" message="" +<30>device="SFW" date=2020-05-18 time=14:38:51 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="" user_gp="" iap=13 category="Information Technology" category_type="Acceptable" url="https://his-eur1-neur1.servicebus.windows.net/$servicebus/websocket" contenttype="" override_token="" httpresponsecode="" src_ip=172.17.34.10 dst_ip=13.79.168.201 protocol="TCP" src_port=62851 dst_port=443 sent_bytes=259 recv_bytes=168 domain=his-eur1-neur1.servicebus.windows.net exceptions="" activityname="" reason="" user_agent="" status_code="400" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=80042000 application="" app_is_cloud=0 override_name="" override_authorizer="" +<30>device="SFW" date=2020-05-18 time=14:38:52 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=050902616002 log_type="Content Filtering" log_component="HTTP" log_subtype="Denied" status="" priority=Information fw_rule_id=51 user_name="" user_gp="" iap=2 category="IPAddress" category_type="Acceptable" url="https://40.90.137.127/" contenttype="" override_token="" httpresponsecode="" src_ip=172.16.34.15 dst_ip=40.90.137.127 protocol="TCP" src_port=60471 dst_port=443 sent_bytes=0 recv_bytes=0 domain=40.90.137.127 exceptions="" activityname="" reason="" user_agent="" status_code="200" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=642960832 application="" app_is_cloud=0 override_name="" override_authorizer="" +<30>device="SFW" date=2020-05-18 time=14:38:53 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=050901616001 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="" user_gp="" iap=13 category="Information Technology" category_type="Acceptable" url="http://update.eset.com/eset_upd/ep7/dll/update.ver.signed" contenttype="" override_token="" httpresponsecode="" src_ip=1.128.3.4 dst_ip=91.228.167.133 protocol="TCP" src_port=65391 dst_port=80 sent_bytes=980 recv_bytes=295 domain=update.eset.com exceptions=av,https,sandstorm activityname="" reason="" user_agent="EFSW Update (Windows; U; 64bit; BPC 7.1.12010.0; OS: 10.0.17763 SP 0.0 NT; TDB 45511; CL 1.1.1; x64s; APP efsw; PX 1; PUA 1; CD 1; RA 1; PEV 0; UNS 1; UBR 1158; HVCI 0; SHA256 1; WU 3; HWF: 01009DAA-757A-D666-EFD2-92DD0D501284; PLOC de_de; PCODE 211.0.0; " status_code="304" transactionid="" referer="" download_file_name="" download_file_type="" upload_file_name="" upload_file_type="" con_id=248426360 application="" app_is_cloud=0 override_name="" override_authorizer="" +<30>device="SFW" date=2016-12-02 time=18:50:20 timezone="GMT" device_name="SF01V" device_id=1234567890123456 log_id=058420116010 log_type="Content Filtering" log_component="Web Content Policy" log_subtype="Alert" user="gi123456" src_ip=10.108.108.49 transaction_id="e4a127f7-a850-477c-920e-a471b38727c1" dictionary_name="complicated_Custom" site_category=Information Technology website="ta-web-static-testing.qa. astaro.de" direction="in" action="Deny" file_name="cgi_echo.pl" context_match="Not" context_prefix="blah blah hello " context_suffix=" hello blah " +<30>device="SFW" date=2016-12-02 time=18:50:20 timezone="GMT" device_name="SFVUNL" device_id=C01001K234RXPA1 log_id=050927616005 log_type="Content Filtering" log_component="HTTP" log_subtype="Warned" status="" priority=Information fw_rule_id=2 user_name="rich" user_gp="Clientless Open Group" iap=13 category="Search Engines" category_type="Acceptable" url="http://www.google.com/" contenttype="" override_token="" httpresponsecode="" src_ip=192.168.73.220 dst_ip=64.233.189.147 protocol="TCP" src_port=37832 dst_port=80 sent_bytes=0 recv_bytes=0 domain=www.google.com exceptions= activityname=" Search" reason="" +<30>device="SFW" date=2016-12-02 time=18:50:22 timezone="GMT" device_name="SFVUNL" device_id=C01001K234RXPA1 log_id=050901616006 log_type="Content Filtering" log_component="HTTP" log_subtype="Allowed" status="" priority=Information fw_rule_id=2 user_name="rich" user_gp="Clientless Open Group" iap=13 category="Search Engines" category_type="Acceptable" url="http://www.google.ca/?gfe_rd=cr&ei=ojxHWP3WC4WN8QeRioDABw" contenttype="text/html" override_token="" httpresponsecode="" src_ip=192.168.73.220 dst_ip=64.233.188.94 protocol="TCP" src_port=46322 dst_port=80 sent_bytes=0 recv_bytes=619 domain=www.google.ca exceptions= activityname="Search" reason="not eligible" + diff --git a/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json index 6169a070cd57..aa00ab04538c 100644 --- a/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2017-01-31T14:03:33.000-02:00", "client.ip": "10.198.47.71", "client.port": 9444, "destination.ip": "182.79.221.19", @@ -70,7 +69,6 @@ "url.scheme": "https" }, { - "@timestamp": "2017-02-01T18:20:21.000-02:00", "client.ip": "216.160.83.57", "client.port": 46719, "destination.ip": "216.58.197.44", @@ -97,7 +95,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 654, + "log.offset": 653, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "S110000E28BA631", @@ -146,7 +144,6 @@ "url.scheme": "http" }, { - "@timestamp": "2017-02-01T18:13:29.000-02:00", "client.ip": "216.160.83.57", "client.port": 49128, "destination.ip": "74.125.130.188", @@ -173,7 +170,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 1229, + "log.offset": 1227, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "S110016E28BA631", @@ -223,7 +220,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:51.000-02:00", "client.ip": "172.17.34.10", "client.port": 62851, "destination.ip": "13.79.168.201", @@ -249,7 +245,7 @@ "http.response.status_code": "400", "input.type": "log", "log.level": "informational", - "log.offset": 1867, + "log.offset": 1864, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -291,7 +287,6 @@ "url.scheme": "https" }, { - "@timestamp": "2020-05-18T14:38:52.000-02:00", "client.ip": "172.16.34.15", "client.port": 60471, "destination.ip": "40.90.137.127", @@ -319,7 +314,7 @@ "http.response.status_code": "200", "input.type": "log", "log.level": "informational", - "log.offset": 2762, + "log.offset": 2758, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -361,7 +356,6 @@ "url.scheme": "https" }, { - "@timestamp": "2020-05-18T14:38:53.000-02:00", "client.ip": "1.128.3.4", "client.port": 65391, "destination.ip": "91.228.167.133", @@ -387,7 +381,7 @@ "http.response.status_code": "304", "input.type": "log", "log.level": "informational", - "log.offset": 3571, + "log.offset": 3566, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -434,7 +428,6 @@ "user_agent.original": "EFSW Update (Windows; U; 64bit; BPC 7.1.12010.0; OS: 10.0.17763 SP 0.0 NT; TDB 45511; CL 1.1.1; x64s; APP efsw; PX 1; PUA 1; CD 1; RA 1; PEV 0; UNS 1; UBR 1158; HVCI 0; SHA256 1; WU 3; HWF: 01009DAA-757A-D666-EFD2-92DD0D501284; PLOC de_de; PCODE 211.0.0; " }, { - "@timestamp": "2016-12-02T18:50:20.000-02:00", "client.ip": "10.108.108.49", "event.action": "alert", "event.category": [ @@ -452,7 +445,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "alert", - "log.offset": 4703, + "log.offset": 4697, "observer.product": "XG", "observer.serial_number": "1234567890123456", "observer.type": "firewall", @@ -488,7 +481,6 @@ ] }, { - "@timestamp": "2016-12-02T18:50:20.000-02:00", "client.ip": "192.168.73.220", "client.port": 37832, "destination.ip": "64.233.189.147", @@ -513,7 +505,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 5265, + "log.offset": 5258, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "C01001K234RXPA1", @@ -559,7 +551,6 @@ "url.scheme": "http" }, { - "@timestamp": "2016-12-02T18:50:22.000-02:00", "client.ip": "192.168.73.220", "client.port": 46322, "destination.ip": "64.233.188.94", @@ -584,7 +575,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 5880, + "log.offset": 5872, "network.transport": "tcp", "observer.product": "XG", "observer.serial_number": "C01001K234RXPA1", diff --git a/x-pack/filebeat/module/sophos/xg/test/event.log b/x-pack/filebeat/module/sophos/xg/test/event.log index 8ec039f86e22..80fe35ee11f5 100644 --- a/x-pack/filebeat/module/sophos/xg/test/event.log +++ b/x-pack/filebeat/module/sophos/xg/test/event.log @@ -1,20 +1,20 @@ -<30>device="SFW" date=2020-05-18 time=14:38:57 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062910617701 log_type="Event" log_component="Firewall Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="Open Group" auth_client="CTA" auth_mechanism="AD" reason="" src_ip=172.17.35.116 message="User elastic.user@elastic.test.com of group Open Group logged in successfully to Firewall through AD authentication mechanism from 172.17.35.116" name="elastic.user@elastic.test.com" src_mac= -<30>device="SFW" date=2020-05-18 time=14:38:58 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062511418055 log_type="Event" log_component="IPSec" log_subtype="System" status="Failed" priority=Warning user_name="elastic.user@elastic.test.com" connectionname="Location-1" connectiontype="0" localinterfaceip=214.167.51.66 localgateway="" localnetwork="172.17.32.0/19" remoteinterfaceip=89.160.20.112 remotenetwork="10.84.234.5/32" message="location-1 - IKE message retransmission timed out (Remote: 89.160.20.112)" -<30>device="SFW" date=2020-05-18 time=14:38:59 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062511318057 log_type="Event" log_component="IPSec" log_subtype="System" status="Expire" priority=Error user_name="" connectionname="" connectiontype="0" localinterfaceip="" localgateway="" localnetwork="" remoteinterfaceip="" remotenetwork="" message="IKE_SA timed out before it could be established" -<30>device="SFW" date=2020-05-18 time=14:39:00 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063210617704 log_type="Event" log_component="My Account Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="" auth_client="N/A" auth_mechanism="Local" reason="" src_ip=67.43.156.13 message="User elastic.user@elastic.test.com logged in successfully to MyAccount through Local authentication mechanism" name="" src_mac= -<30>device="SFW" date=2020-05-18 time=14:39:01 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=064011517819 log_type="Event" log_component="Anti-Virus" log_subtype="System" priority=Notice status="Successful" oldversion=1.0.407794 newversion=1.0.407795 message="Avira AV definitions upgraded from 1.0.407794 to 1.0.407795." -<30>device="SFW" date=2020-05-18 time=14:39:02 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=063411660022 log_type="Event" log_component="DHCP Server" log_subtype="System" status="Expire" priority=Information ipaddress="192.168.110.10" client_physical_address="-" client_host_name="" message="Lease 192.168.110.10 expired" raw_data="192.168.110.10" -<30>device="SFW" date=2020-05-18 time=14:39:03 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063110617710 log_type="Event" log_component="SSL VPN Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="" auth_client="N/A" auth_mechanism="AD" reason="" src_ip=81.2.69.145 message="User elastic.user@elastic.test.com authenticated successfully to login to SSLVPN through AD authentication mechanism" name="" src_mac= -<30>device="SFW" date=2020-05-18 time=14:39:04 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062811617824 log_type="Event" log_component="SSL VPN" log_subtype="System" priority=Information Mode="Remote Access" sessionid="" starttime=0 user_name="elastic.user@elastic.test.com" ipaddress=10.82.234.5 sent_bytes=0 recv_bytes=0 status="Established" message="SSL VPN User 'elastic.user@elastic.test.com' connected " timestamp=1589960866 connectionname="" remote_ip=10.82.234.12 -<30>device="SFW" date=2020-05-18 time=14:39:05 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063010517708 log_type="Event" log_component="VPN Authentication" log_subtype="Authentication" status="Failed" priority=Notice user_name="hendrikl" usergroupname="" auth_client="N/A" auth_mechanism="AD,AD,Local" reason="wrong credentials" src_ip=1.128.3.4 message="User elastic01 failed to login to VPN through AD,AD,Local authentication mechanism because of wrong credentials" name="" src_mac= -<30>device="SFW" date=2020-05-18 time=14:39:06 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=066911518017 log_type="Event" log_component="ATP" log_subtype="System" priority=Notice status="Successful" oldversion=1.0.0297 newversion=1.0.0298 message="ATP definitions upgraded from 1.0.0297 to 1.0.0298." -<30>device="SFW" date=2020-05-18 time=14:39:07 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=062009617502 log_type="Event" log_component="GUI" log_subtype="Admin" status="Successful" priority=Information user_name="admin" src_ip=10.83.234.5 SysLog_SERVER_NAME='Logstash' message="SysLog Server 'Logstash' settings were changed by 'admin' from '10.83.234.5' using 'GUI'" -<30>device="SFW" date=2020-05-18 time=14:39:08 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062109517507 log_type="Event" log_component="CLI" log_subtype="Admin" status="Failed" priority=Notice user_name="root" src_ip=175.16.199.1 message="User 'root' failed to login from '175.16.199.1' using ssh because of wrong credentials" -<30>device="SFW" date=2020-05-18 time=14:39:09 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063911517818 log_type="Event" log_component="IPS" log_subtype="System" priority=Notice status="Successful" oldversion=9.17.09 newversion=9.17.10 message="IPS definitions upgraded from 9.17.09 to 9.17.10." -<30>device="SFW" date=2020-05-18 time=14:39:10 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063311617923 log_type="Event" log_component="Appliance" log_subtype="System" priority=Information backup_mode='appliance' message="Scheduled backup to appliance is successful." -<30>device="SFW" date=2020-05-18 time=14:39:20 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=062910617703 log_type="Event" log_component="Firewall Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="VPN.SSL.Users.elastic" auth_client="IPSec" auth_mechanism="N/A" reason="" src_ip=10.84.234.38 src_mac="" start_time=1591086575 sent_bytes=0 recv_bytes=0 message="User elastic.user@elastic.test.com was logged out of firewall" name="elastic.user@elastic.test.com" timestamp=1591086576 -<30>device="SFW" date=2017-03-16 time=12:56:01 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618014 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Connected" eventtime="2017-03-16 12:56:01 IST" duration=164000 branch_name=Gaurav Patel recv_bytes=0 sent_bytes=0 message="A350196C47072B0/Gaurav Patel is now re-connected after 164000 ms" -<30>device="SFW" date=2017-03-16 time=12:53:27 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618015 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Disconnected" eventtime="2017-03-16 12:53:27 IST" duration=0 branch_name=Gaurav Patel recv_bytes=31488 sent_bytes=22368 message="A350196C47072B0/Gaurav Patel is now disconnected" -<30>device="SFW" date=2017-03-16 time=12:46:26 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618016 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Interim" eventtime="2017-03-16 12:46:26 IST" duration=0 branch_name=NY recv_bytes=0 sent_bytes=0 message="A350196C47072B0/NY transfered bytes TX: 0 RX: 0" -<30>device="SFW" date=2018-06-06 time=11:12:10 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=063711517815 log_type="Event" log_component="DDNS" log_subtype="System" status="Success" priority=Notice host=test1. customtest.dyndns.org updatedip=10.198.232.86 reason="" message="DDNS update for host test1.customtest.dyndns.org was Successful. Updated with IP 10.198.232.86." - +<30>device="SFW" date=2020-05-18 time=14:38:57 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062910617701 log_type="Event" log_component="Firewall Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="Open Group" auth_client="CTA" auth_mechanism="AD" reason="" src_ip=172.17.35.116 message="User elastic.user@elastic.test.com of group Open Group logged in successfully to Firewall through AD authentication mechanism from 172.17.35.116" name="elastic.user@elastic.test.com" src_mac= +<30>device="SFW" date=2020-05-18 time=14:38:58 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062511418055 log_type="Event" log_component="IPSec" log_subtype="System" status="Failed" priority=Warning user_name="elastic.user@elastic.test.com" connectionname="Location-1" connectiontype="0" localinterfaceip=214.167.51.66 localgateway="" localnetwork="172.17.32.0/19" remoteinterfaceip=89.160.20.112 remotenetwork="10.84.234.5/32" message="location-1 - IKE message retransmission timed out (Remote: 89.160.20.112)" +<30>device="SFW" date=2020-05-18 time=14:38:59 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062511318057 log_type="Event" log_component="IPSec" log_subtype="System" status="Expire" priority=Error user_name="" connectionname="" connectiontype="0" localinterfaceip="" localgateway="" localnetwork="" remoteinterfaceip="" remotenetwork="" message="IKE_SA timed out before it could be established" +<30>device="SFW" date=2020-05-18 time=14:39:00 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063210617704 log_type="Event" log_component="My Account Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="" auth_client="N/A" auth_mechanism="Local" reason="" src_ip=67.43.156.13 message="User elastic.user@elastic.test.com logged in successfully to MyAccount through Local authentication mechanism" name="" src_mac= +<30>device="SFW" date=2020-05-18 time=14:39:01 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=064011517819 log_type="Event" log_component="Anti-Virus" log_subtype="System" priority=Notice status="Successful" oldversion=1.0.407794 newversion=1.0.407795 message="Avira AV definitions upgraded from 1.0.407794 to 1.0.407795." +<30>device="SFW" date=2020-05-18 time=14:39:02 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=063411660022 log_type="Event" log_component="DHCP Server" log_subtype="System" status="Expire" priority=Information ipaddress="192.168.110.10" client_physical_address="-" client_host_name="" message="Lease 192.168.110.10 expired" raw_data="192.168.110.10" +<30>device="SFW" date=2020-05-18 time=14:39:03 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063110617710 log_type="Event" log_component="SSL VPN Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="" auth_client="N/A" auth_mechanism="AD" reason="" src_ip=81.2.69.145 message="User elastic.user@elastic.test.com authenticated successfully to login to SSLVPN through AD authentication mechanism" name="" src_mac= +<30>device="SFW" date=2020-05-18 time=14:39:04 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062811617824 log_type="Event" log_component="SSL VPN" log_subtype="System" priority=Information Mode="Remote Access" sessionid="" starttime=0 user_name="elastic.user@elastic.test.com" ipaddress=10.82.234.5 sent_bytes=0 recv_bytes=0 status="Established" message="SSL VPN User 'elastic.user@elastic.test.com' connected " timestamp=1589960866 connectionname="" remote_ip=10.82.234.12 +<30>device="SFW" date=2020-05-18 time=14:39:05 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063010517708 log_type="Event" log_component="VPN Authentication" log_subtype="Authentication" status="Failed" priority=Notice user_name="hendrikl" usergroupname="" auth_client="N/A" auth_mechanism="AD,AD,Local" reason="wrong credentials" src_ip=1.128.3.4 message="User elastic01 failed to login to VPN through AD,AD,Local authentication mechanism because of wrong credentials" name="" src_mac= +<30>device="SFW" date=2020-05-18 time=14:39:06 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=066911518017 log_type="Event" log_component="ATP" log_subtype="System" priority=Notice status="Successful" oldversion=1.0.0297 newversion=1.0.0298 message="ATP definitions upgraded from 1.0.0297 to 1.0.0298." +<30>device="SFW" date=2020-05-18 time=14:39:07 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=062009617502 log_type="Event" log_component="GUI" log_subtype="Admin" status="Successful" priority=Information user_name="admin" src_ip=10.83.234.5 SysLog_SERVER_NAME='Logstash' message="SysLog Server 'Logstash' settings were changed by 'admin' from '10.83.234.5' using 'GUI'" +<30>device="SFW" date=2020-05-18 time=14:39:08 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=062109517507 log_type="Event" log_component="CLI" log_subtype="Admin" status="Failed" priority=Notice user_name="root" src_ip=175.16.199.1 message="User 'root' failed to login from '175.16.199.1' using ssh because of wrong credentials" +<30>device="SFW" date=2020-05-18 time=14:39:09 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063911517818 log_type="Event" log_component="IPS" log_subtype="System" priority=Notice status="Successful" oldversion=9.17.09 newversion=9.17.10 message="IPS definitions upgraded from 9.17.09 to 9.17.10." +<30>device="SFW" date=2020-05-18 time=14:39:10 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=063311617923 log_type="Event" log_component="Appliance" log_subtype="System" priority=Information backup_mode='appliance' message="Scheduled backup to appliance is successful." +<30>device="SFW" date=2020-05-18 time=14:39:20 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=062910617703 log_type="Event" log_component="Firewall Authentication" log_subtype="Authentication" status="Successful" priority=Information user_name="elastic.user@elastic.test.com" usergroupname="VPN.SSL.Users.elastic" auth_client="IPSec" auth_mechanism="N/A" reason="" src_ip=10.84.234.38 src_mac="" start_time=1591086575 sent_bytes=0 recv_bytes=0 message="User elastic.user@elastic.test.com was logged out of firewall" name="elastic.user@elastic.test.com" timestamp=1591086576 +<30>device="SFW" date=2017-03-16 time=12:56:01 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618014 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Connected" eventtime="2017-03-16 12:56:01 IST" duration=164000 branch_name=Gaurav Patel recv_bytes=0 sent_bytes=0 message="A350196C47072B0/Gaurav Patel is now re-connected after 164000 ms" +<30>device="SFW" date=2017-03-16 time=12:53:27 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618015 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Disconnected" eventtime="2017-03-16 12:53:27 IST" duration=0 branch_name=Gaurav Patel recv_bytes=31488 sent_bytes=22368 message="A350196C47072B0/Gaurav Patel is now disconnected" +<30>device="SFW" date=2017-03-16 time=12:46:26 timezone="IST" device_name="XG125w" device_id=S1601E1F9FCB7EE log_id=066811618016 log_type="Event" log_component="RED" log_subtype="System" priority=Information red_id=A350196C47072B0 status="Interim" eventtime="2017-03-16 12:46:26 IST" duration=0 branch_name=NY recv_bytes=0 sent_bytes=0 message="A350196C47072B0/NY transfered bytes TX: 0 RX: 0" +<30>device="SFW" date=2018-06-06 time=11:12:10 timezone="IST" device_name="SG430" device_id=S4000806149EE49 log_id=063711517815 log_type="Event" log_component="DDNS" log_subtype="System" status="Success" priority=Notice host=test1. customtest.dyndns.org updatedip=10.198.232.86 reason="" message="DDNS update for host test1.customtest.dyndns.org was Successful. Updated with IP 10.198.232.86." + diff --git a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json index 179a156aaf58..27e381dabcec 100644 --- a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:57.000-02:00", "client.ip": "172.17.35.116", "event.category": [ "authentication" @@ -57,7 +56,6 @@ "user.name": "elastic.user@elastic.test.com" }, { - "@timestamp": "2020-05-18T14:38:58.000-02:00", "client.ip": "89.160.20.112", "destination.as.number": 721, "destination.as.organization.name": "DoD Network Information Center", @@ -73,7 +71,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "warning", - "log.offset": 597, + "log.offset": 596, "message": "location-1 - IKE message retransmission timed out (Remote: 89.160.20.112)", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -121,7 +119,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:59.000-02:00", "event.code": "062511318057", "event.dataset": "sophos.xg", "event.kind": "event", @@ -133,7 +130,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "error", - "log.offset": 1134, + "log.offset": 1132, "message": "IKE_SA timed out before it could be established", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -158,7 +155,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:00.000-02:00", "client.ip": "67.43.156.13", "event.category": [ "authentication" @@ -179,7 +175,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 1554, + "log.offset": 1551, "message": "User elastic.user@elastic.test.com logged in successfully to MyAccount through Local authentication mechanism", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -219,7 +215,6 @@ "user.name": "elastic.user@elastic.test.com" }, { - "@timestamp": "2020-05-18T14:39:01.000-02:00", "event.category": [ "host", "malware" @@ -238,7 +233,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "notification", - "log.offset": 2081, + "log.offset": 2077, "message": "Avira AV definitions upgraded from 1.0.407794 to 1.0.407795.", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -264,7 +259,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:02.000-02:00", "event.code": "063411660022", "event.dataset": "sophos.xg", "event.kind": "event", @@ -276,7 +270,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 2429, + "log.offset": 2424, "message": "Lease 192.168.110.10 expired", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -302,7 +296,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:03.000-02:00", "client.ip": "81.2.69.145", "event.category": [ "authentication" @@ -323,7 +316,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 2803, + "log.offset": 2797, "message": "User elastic.user@elastic.test.com authenticated successfully to login to SSLVPN through AD authentication mechanism", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -365,7 +358,6 @@ "user.name": "elastic.user@elastic.test.com" }, { - "@timestamp": "2020-05-20T05:47:46.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "062811617824", @@ -379,7 +371,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 3330, + "log.offset": 3323, "message": "SSL VPN User 'elastic.user@elastic.test.com' connected ", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -414,7 +406,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:05.000-02:00", "client.ip": "1.128.3.4", "event.category": [ "authentication" @@ -431,7 +422,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "notification", - "log.offset": 3829, + "log.offset": 3821, "message": "User elastic01 failed to login to VPN through AD,AD,Local authentication mechanism because of wrong credentials", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -468,7 +459,6 @@ "user.name": "hendrikl" }, { - "@timestamp": "2020-05-18T14:39:06.000-02:00", "event.code": "066911518017", "event.dataset": "sophos.xg", "event.kind": "event", @@ -480,7 +470,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "notification", - "log.offset": 4341, + "log.offset": 4332, "message": "ATP definitions upgraded from 1.0.0297 to 1.0.0298.", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -506,7 +496,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:07.000-02:00", "client.ip": "10.83.234.5", "event.code": "062009617502", "event.dataset": "sophos.xg", @@ -519,7 +508,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 4669, + "log.offset": 4659, "message": "SysLog Server 'Logstash' settings were changed by 'admin' from '10.83.234.5' using 'GUI'", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -552,7 +541,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:08.000-02:00", "client.ip": "175.16.199.1", "event.code": "062109517507", "event.dataset": "sophos.xg", @@ -566,7 +554,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "notification", - "log.offset": 5064, + "log.offset": 5053, "message": "User 'root' failed to login from '175.16.199.1' using ssh because of wrong credentials", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -606,7 +594,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:09.000-02:00", "event.code": "063911517818", "event.dataset": "sophos.xg", "event.kind": "event", @@ -618,7 +605,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "notification", - "log.offset": 5418, + "log.offset": 5406, "message": "IPS definitions upgraded from 9.17.09 to 9.17.10.", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -644,7 +631,6 @@ ] }, { - "@timestamp": "2020-05-18T14:39:10.000-02:00", "event.code": "063311617923", "event.dataset": "sophos.xg", "event.kind": "event", @@ -656,7 +642,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 5742, + "log.offset": 5729, "message": "Scheduled backup to appliance is successful.", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -680,7 +666,6 @@ ] }, { - "@timestamp": "2020-06-02T06:29:36.000-02:00", "client.bytes": 0, "client.ip": "10.84.234.38", "destination.bytes": 0, @@ -705,7 +690,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 6040, + "log.offset": 6026, "message": "User elastic.user@elastic.test.com was logged out of firewall", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -744,7 +729,6 @@ "user.name": "elastic.user@elastic.test.com" }, { - "@timestamp": "2017-03-16T12:56:01.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "066811618014", @@ -761,7 +745,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 6638, + "log.offset": 6623, "message": "A350196C47072B0/Gaurav Patel is now re-connected after 164000 ms", "observer.product": "XG", "observer.serial_number": "S1601E1F9FCB7EE", @@ -790,7 +774,6 @@ ] }, { - "@timestamp": "2017-03-16T12:53:27.000-02:00", "client.bytes": 22368, "destination.bytes": 31488, "event.code": "066811618015", @@ -807,7 +790,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 7067, + "log.offset": 7051, "message": "A350196C47072B0/Gaurav Patel is now disconnected", "observer.product": "XG", "observer.serial_number": "S1601E1F9FCB7EE", @@ -836,7 +819,6 @@ ] }, { - "@timestamp": "2017-03-16T12:46:26.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "066811618016", @@ -853,7 +835,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 7486, + "log.offset": 7469, "message": "A350196C47072B0/NY transfered bytes TX: 0 RX: 0", "observer.product": "XG", "observer.serial_number": "S1601E1F9FCB7EE", @@ -882,7 +864,6 @@ ] }, { - "@timestamp": "2018-06-06T11:12:10.000-02:00", "event.code": "063711517815", "event.dataset": "sophos.xg", "event.kind": "event", @@ -894,7 +875,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "notification", - "log.offset": 7881, + "log.offset": 7863, "message": "DDNS update for host test1.customtest.dyndns.org was Successful. Updated with IP 10.198.232.86.", "observer.product": "XG", "observer.serial_number": "S4000806149EE49", diff --git a/x-pack/filebeat/module/sophos/xg/test/firewall.log b/x-pack/filebeat/module/sophos/xg/test/firewall.log index 920661cc9c28..1abc96cc5225 100644 --- a/x-pack/filebeat/module/sophos/xg/test/firewall.log +++ b/x-pack/filebeat/module/sophos/xg/test/firewall.log @@ -1,21 +1,22 @@ -<30>device="SFW" date=2020-05-18 time=14:38:37 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=11 fw_rule_id=21 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="HTTP" application_risk=1 application_technology="Browser Based" application_category="General Internet" in_interface="Port1" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=1.128.3.4 src_country_code=R1 dst_ip=91.228.167.86 dst_country_code=SVK protocol="TCP" src_port=62841 dst_port=80 sent_pkts=6 recv_pkts=5 sent_bytes=459 recv_bytes=606 tran_src_ip=213.167.51.66 tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="LAN" srczone="LAN" dstzonetype="WAN" dstzone="WAN" dir_disp="" connevent="Stop" connid="1617925280" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:38 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=67 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=15 appfilter_policy_id=0 application="DNS" application_risk=1 application_technology="Network Protocol" application_category="Infrastructure" in_interface="Port3.400" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=67.43.156.12 src_country_code=R1 dst_ip=91.228.165.117 dst_country_code=SVK protocol="UDP" src_port=49144 dst_port=53 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=185.8.209.194 tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="DMZ" srczone="DMZ" dstzonetype="WAN" dstzone="WAN" dir_disp="" connevent="Start" connid="3360392048" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:39 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="Port2" src_mac=24:01:c7:07:2b:a2 src_ip=172.17.35.113 src_country_code="" dst_ip=172.20.4.52 dst_country_code="" protocol="TCP" src_port=53287 dst_port=4980 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:40 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="elastic@user.local" user_gp="elastic.group.local" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="tun0" out_interface="Port1" src_mac="" src_ip=10.82.234.6 src_country_code="" dst_ip=192.168.0.1 dst_country_code="" protocol="TCP" src_port=60102 dst_port=53 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:41 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010302602002 log_type="Firewall" log_component="Appliance Access" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2" out_interface="" src_mac=c4:f7:d5:b5:47:f4 src_ip=67.43.156.12 src_country_code="" dst_ip=185.7.209.207 dst_country_code="" protocol="TCP" src_port=55039 dst_port=18 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:42 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="elastic@user.local" user_gp="elastic.group.local" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="Port2" src_mac=24:01:c7:07:2b:a2 src_ip=172.17.35.101 src_country_code="" dst_ip=192.168.5.11 dst_country_code="" protocol="TCP" src_port=51826 dst_port=1109 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:43 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010402403001 log_type="Firewall" log_component="DoS Attack" log_subtype="Denied" status="Deny" priority=Warning duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=34:db:fd:83:d8:09 src_ip=172.16.36.105 src_country_code="" dst_ip=10.84.234.14 dst_country_code="" protocol="UDP" src_port=3389 dst_port=64465 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:44 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=012802605201 log_type="Firewall" log_component="SSL VPN" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="tun0" out_interface="" src_mac="" src_ip=10.82.234.9 src_country_code="" dst_ip=10.82.234.11 dst_country_code="" protocol="TCP" src_port=58331 dst_port=56267 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:45 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=61 policy_type=2 user_name="elastic@user.local" user_gp="elastic.group.local" iap=0 ips_policy_id=11 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="ipsec0" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=10.84.234.7 src_country_code=R1 dst_ip=172.16.34.50 dst_country_code=R1 protocol="TCP" src_port=58543 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="VPN" srczone="VPN" dstzonetype="VPN" dstzone="VPN" dir_disp="" connevent="Start" connid="1615935064" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-05-18 time=14:38:45 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=018201500005 log_type="Firewall" log_component="ICMP ERROR MESSAGE" log_subtype="Allowed" status="Allow" priority=Notice duration=0 fw_rule_id=60 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=17 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=34:db:fd:83:d8:09 src_ip=192.168.1.254 src_country_code="" dst_ip=172.17.32.19 dst_country_code="" protocol="ICMP" icmp_type=3 icmp_code=1 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connevent="Interim" connid="2685668438" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2020-06-05 time=12:38:53 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=10 fw_rule_id=60 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=17 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="ipsec0" out_interface="Port1" src_mac=00:00:00:00:00:00 src_ip=172.17.35.119 src_country_code=R1 dst_ip=172.16.34.10 dst_country_code=R1 protocol="TCP" src_port=61925 dst_port=88 sent_pkts=6 recv_pkts=6 sent_bytes=1802 recv_bytes=1732 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0srczonetype="VPN" srczone="VPN" dstzonetype="LAN" dstzone="LAN" dir_disp="" connevent="Stop" connid="1617126256" vconnid="" hb_health="NoHeartbeat" message="" appresolvedby="Signature" app_is_cloud=0" -<30>device="SFW" date=2018-05-30 time=13:26:37 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010202601001 log_type="Firewall" log_component="Invalid Traffic" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.32.19 src_country_code= dst_ip=175.16.199.1 dst_country_code= protocol="UDP" src_port=1353 dst_port=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="Invalid UDP destination." appresolvedby=" Signature" -<30>device="SFW" date=2018-06-04 time=17:20:24 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=011402601301 log_type="Firewall" log_component="Fragmented Traffic" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=0.0.0.0 src_country_code= dst_ip=0.0.0.0 dst_country_code= protocol="0" src_port=0 dst_port=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" -<30>device="SFW" date=2018-05-30 time=14:01:32 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010302602002 log_type="Firewall" log_component="Appliance Access" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=2 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2.611" out_interface="" src_mac=c8:5b:76:ab:72:d3 src_ip=10.198.38.184 src_country_code= dst_ip=10.198.39.255 dst_country_code= protocol="UDP" src_port=137 dst_port=137 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" -<30>device="SFW" date=2018-05-30 time=14:17:17 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010402403001 log_type="Firewall" log_component="DoS Attack" log_subtype="Denied" status="Deny" priority=Warning duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=b8:97:5a:5b:0f:fd src_ip=10.198.32.19 src_country_code= dst_ip=10.198.32.48 dst_country_code= protocol="TCP" src_port=41960 dst_port=22 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby=" Signature" -<30>device="SFW" date=2018-06-05 time=14:30:31 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010502604001 log_type="Firewall" log_component="ICMP Redirection" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.37.23 src_country_code= dst_ip=10.198.36.48 dst_country_code= protocol="ICMP" icmp_type=5 icmp_code=1 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby=" Signature" -<30>device="SFW" date=2018-05-31 time=17:05:14 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010602605001 log_type="Firewall" log_component="Source Routed" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=1 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.12.19 src_country_code= dst_ip=175.16.199.1 dst_country_code= protocol="TCP" src_port=1571 dst_port=80 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" -<30>device="SFW" date=2018-05-30 time=15:09:51 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=011702605051 log_type="Firewall" log_component="MAC Filter" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2.531" out_interface="" src_mac=1e:3a:5a:5b:23:ab src_ip=fe80::59f5:3ce8:c98e:5062 src_country_code= dst_ip=ff02::1:2 dst_country_code= protocol="UDP" src_port=546 dst_port=547 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" -<30>device="SFW" date=2018-06-01 time=10:57:55 timezone="BST" device_name="XG310" device_id=SFDemo-9a04c43 log_id=016602600006 log_type="Firewall" log_component="Heartbeat" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=16 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port3.611" out_interface="" src_mac=08:00:27:4c:49:e3 src_ip=10.198.37.57 src_country_code= dst_ip=10.198.32.19 dst_country_code= protocol="ICMP" icmp_type=8 icmp_code=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="Red" message="" appresolvedby="Signature" app_is_cloud=0 -<30>device="SFW" date=2018-06-01 time=10:55:41 timezone="BST" device_name="XG310" device_id=SFDemo-9a04c43 log_id=016602600003 log_type="Firewall" log_component="Heartbeat" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=16 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port3.611" out_interface="" src_mac=08:00:27:4c:49:e3 src_ip=10.198.37.57 src_country_code= dst_ip=72.163.4.185 dst_country_code= protocol="ICMP" icmp_type=8 icmp_code=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="Red" message="" appresolvedby="Signature" app_is_cloud=0 - +<30>device="SFW" date=2020-05-18 time=14:38:37 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=11 fw_rule_id=21 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="HTTP" application_risk=1 application_technology="Browser Based" application_category="General Internet" in_interface="Port1" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=1.128.3.4 src_country_code=R1 dst_ip=91.228.167.86 dst_country_code=SVK protocol="TCP" src_port=62841 dst_port=80 sent_pkts=6 recv_pkts=5 sent_bytes=459 recv_bytes=606 tran_src_ip=213.167.51.66 tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="LAN" srczone="LAN" dstzonetype="WAN" dstzone="WAN" dir_disp="" connevent="Stop" connid="1617925280" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:38 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=67 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=15 appfilter_policy_id=0 application="DNS" application_risk=1 application_technology="Network Protocol" application_category="Infrastructure" in_interface="Port3.400" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=67.43.156.12 src_country_code=R1 dst_ip=91.228.165.117 dst_country_code=SVK protocol="UDP" src_port=49144 dst_port=53 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=185.8.209.194 tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="DMZ" srczone="DMZ" dstzonetype="WAN" dstzone="WAN" dir_disp="" connevent="Start" connid="3360392048" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:39 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="Port2" src_mac=24:01:c7:07:2b:a2 src_ip=172.17.35.113 src_country_code="" dst_ip=172.20.4.52 dst_country_code="" protocol="TCP" src_port=53287 dst_port=4980 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:40 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="elastic@user.local" user_gp="elastic.group.local" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="tun0" out_interface="Port1" src_mac="" src_ip=10.82.234.6 src_country_code="" dst_ip=192.168.0.1 dst_country_code="" protocol="TCP" src_port=60102 dst_port=53 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:41 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010302602002 log_type="Firewall" log_component="Appliance Access" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2" out_interface="" src_mac=c4:f7:d5:b5:47:f4 src_ip=67.43.156.12 src_country_code="" dst_ip=185.7.209.207 dst_country_code="" protocol="TCP" src_port=55039 dst_port=18 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:42 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010102600002 log_type="Firewall" log_component="Firewall Rule" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=29 policy_type=1 user_name="elastic@user.local" user_gp="elastic.group.local" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="Port2" src_mac=24:01:c7:07:2b:a2 src_ip=172.17.35.101 src_country_code="" dst_ip=192.168.5.11 dst_country_code="" protocol="TCP" src_port=51826 dst_port=1109 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:43 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010402403001 log_type="Firewall" log_component="DoS Attack" log_subtype="Denied" status="Deny" priority=Warning duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=34:db:fd:83:d8:09 src_ip=172.16.36.105 src_country_code="" dst_ip=10.84.234.14 dst_country_code="" protocol="UDP" src_port=3389 dst_port=64465 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:44 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=012802605201 log_type="Firewall" log_component="SSL VPN" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="tun0" out_interface="" src_mac="" src_ip=10.82.234.9 src_country_code="" dst_ip=10.82.234.11 dst_country_code="" protocol="TCP" src_port=58331 dst_port=56267 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:45 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=61 policy_type=2 user_name="elastic@user.local" user_gp="elastic.group.local" iap=0 ips_policy_id=11 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="ipsec0" out_interface="Port2" src_mac=00:00:00:00:00:00 src_ip=10.84.234.7 src_country_code=R1 dst_ip=172.16.34.50 dst_country_code=R1 protocol="TCP" src_port=58543 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="VPN" srczone="VPN" dstzonetype="VPN" dstzone="VPN" dir_disp="" connevent="Start" connid="1615935064" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-05-18 time=14:38:45 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=018201500005 log_type="Firewall" log_component="ICMP ERROR MESSAGE" log_subtype="Allowed" status="Allow" priority=Notice duration=0 fw_rule_id=60 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=17 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=34:db:fd:83:d8:09 src_ip=192.168.1.254 src_country_code="" dst_ip=172.17.32.19 dst_country_code="" protocol="ICMP" icmp_type=3 icmp_code=1 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip="" tran_src_port=0 tran_dst_ip="" tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connevent="Interim" connid="2685668438" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2020-06-05 time=12:38:53 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=10 fw_rule_id=60 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=17 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="ipsec0" out_interface="Port1" src_mac=00:00:00:00:00:00 src_ip=172.17.35.119 src_country_code=R1 dst_ip=172.16.34.10 dst_country_code=R1 protocol="TCP" src_port=61925 dst_port=88 sent_pkts=6 recv_pkts=6 sent_bytes=1802 recv_bytes=1732 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0srczonetype="VPN" srczone="VPN" dstzonetype="LAN" dstzone="LAN" dir_disp="" connevent="Stop" connid="1617126256" vconnid="" hb_health="NoHeartbeat" message="" appresolvedby="Signature" app_is_cloud=0" +<30>device="SFW" date=2018-05-30 time=13:26:37 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010202601001 log_type="Firewall" log_component="Invalid Traffic" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.32.19 src_country_code= dst_ip=175.16.199.1 dst_country_code= protocol="UDP" src_port=1353 dst_port=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="Invalid UDP destination." appresolvedby=" Signature" +<30>device="SFW" date=2018-06-04 time=17:20:24 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=011402601301 log_type="Firewall" log_component="Fragmented Traffic" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=0.0.0.0 src_country_code= dst_ip=0.0.0.0 dst_country_code= protocol="0" src_port=0 dst_port=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" +<30>device="SFW" date=2018-05-30 time=14:01:32 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010302602002 log_type="Firewall" log_component="Appliance Access" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=2 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2.611" out_interface="" src_mac=c8:5b:76:ab:72:d3 src_ip=10.198.38.184 src_country_code= dst_ip=10.198.39.255 dst_country_code= protocol="UDP" src_port=137 dst_port=137 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" +<30>device="SFW" date=2018-05-30 time=14:17:17 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010402403001 log_type="Firewall" log_component="DoS Attack" log_subtype="Denied" status="Deny" priority=Warning duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port1" out_interface="" src_mac=b8:97:5a:5b:0f:fd src_ip=10.198.32.19 src_country_code= dst_ip=10.198.32.48 dst_country_code= protocol="TCP" src_port=41960 dst_port=22 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby=" Signature" +<30>device="SFW" date=2018-06-05 time=14:30:31 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010502604001 log_type="Firewall" log_component="ICMP Redirection" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.37.23 src_country_code= dst_ip=10.198.36.48 dst_country_code= protocol="ICMP" icmp_type=5 icmp_code=1 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby=" Signature" +<30>device="SFW" date=2018-05-31 time=17:05:14 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=010602605001 log_type="Firewall" log_component="Source Routed" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=1 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="" out_interface="" src_mac= src_ip=10.198.12.19 src_country_code= dst_ip=175.16.199.1 dst_country_code= protocol="TCP" src_port=1571 dst_port=80 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" +<30>device="SFW" date=2018-05-30 time=15:09:51 timezone="IST" device_name="XG125w" device_id=SFDemo-763180a log_id=011702605051 log_type="Firewall" log_component="MAC Filter" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=0 policy_type=0 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port2.531" out_interface="" src_mac=1e:3a:5a:5b:23:ab src_ip=fe80::59f5:3ce8:c98e:5062 src_country_code= dst_ip=ff02::1:2 dst_country_code= protocol="UDP" src_port=546 dst_port=547 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" +<30>device="SFW" date=2018-06-01 time=10:57:55 timezone="BST" device_name="XG310" device_id=SFDemo-9a04c43 log_id=016602600006 log_type="Firewall" log_component="Heartbeat" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=16 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port3.611" out_interface="" src_mac=08:00:27:4c:49:e3 src_ip=10.198.37.57 src_country_code= dst_ip=10.198.32.19 dst_country_code= protocol="ICMP" icmp_type=8 icmp_code=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="Red" message="" appresolvedby="Signature" app_is_cloud=0 +<30>device="SFW" date=2018-06-01 time=10:55:41 timezone="BST" device_name="XG310" device_id=SFDemo-9a04c43 log_id=016602600003 log_type="Firewall" log_component="Heartbeat" log_subtype="Denied" status="Deny" priority=Information duration=0 fw_rule_id=16 policy_type=1 user_name="" user_gp="" iap=2 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" in_interface="Port3.611" out_interface="" src_mac=08:00:27:4c:49:e3 src_ip=10.198.37.57 src_country_code= dst_ip=72.163.4.185 dst_country_code= protocol="ICMP" icmp_type=8 icmp_code=0 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip= tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="" srczone="" dstzonetype="" dstzone="" dir_disp="" connid="" vconnid="" hb_health="Red" message="" appresolvedby="Signature" app_is_cloud=0 +<01>Feb 11 13:12:45 _gateway device="SFW" date=2021-02-11 time=13:12:45 timezone="CET" device_name="XG210" device_id=dem-dev log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=9 nat_rule_id=16 policy_type=1 user_name="" user_gp="" iap=0 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" vlan_id="" ether_type=Unknown (0x0000) bridge_name="" bridge_display_name="" in_interface="Port2.109" in_display_interface="CD21-IPs_WAN" out_interface="Port5.200" out_display_interface="Port5" src_mac=11:22:33:44:55:66 dst_mac=66:55:44:33:22:11 src_ip=1.2.3.4 src_country_code=ESP dst_ip=4.3.2.1 dst_country_code=GB protocol="TCP" src_port=33370 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=2.4.6.8 tran_src_port=0 tran_dst_ip=8.6.4.2 tran_dst_port=0 srczonetype="WAN" srczone="WAN" dstzonetype="DMZ" dstzone="Zone 9" dir_disp="" connevent="Start" connid="3933925696" vconnid="" hb_health="No Heartbeat" message="" appresolvedby="Signature" app_is_cloud=0 +<01>device="SFW" date=2020-06-05 time=03:45:23 timezone="CEST" device_name="SF01V" device_id=SFDemo-ta-vm-55 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=Information duration=0 fw_rule_id=5 nat_rule_id=2 policy_type=1 user_name="" user_gp="" iap=13 ips_policy_id=0 appfilter_policy_id=0 application="" application_risk=0 application_technology="" application_category="" vlan_id="" ether_type=Unknown (0x0000) bridge_name="" bridge_display_name="" in_interface="Port2" in_display_interface="Port2" out_interface="Port1" out_display_interface="Port1" src_mac=00:50:56:99:51:94 dst_mac=00:50:56:99:3D:AC src_ip=10.146.13.30 src_country_code= dst_ip=10.8.142.181 dst_country_code= protocol="TCP" src_port=45294 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=10.8.13.110 tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype="LAN" srczone="LAN" dstzonetype="WAN" dstzone="WAN" dir_disp="" connevent="Start" connid="2674291981" vconnid="" hb_health="No Heartbeat"message="" appresolvedby="Signature" app_is_cloud=0 log_occurrence=1 diff --git a/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json index deb91f6a5a39..4f2f390525c1 100644 --- a/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:37.000-02:00", "client.bytes": 459, "client.ip": "1.128.3.4", "client.mac": "00:00:00:00:00:00", @@ -102,7 +101,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:38.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.mac": "00:00:00:00:00:00", @@ -138,7 +136,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 983, + "log.offset": 982, "network.bytes": 0, "network.direction": "outbound", "network.packets": 0, @@ -208,7 +206,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:39.000-02:00", "client.bytes": 0, "client.ip": "172.17.35.113", "client.mac": "24:01:c7:07:2b:a2", @@ -243,7 +240,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 1971, + "log.offset": 1969, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -295,7 +292,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:40.000-02:00", "client.bytes": 0, "client.ip": "10.82.234.6", "client.nat.port": 0, @@ -329,7 +325,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 2867, + "log.offset": 2864, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -385,7 +381,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:41.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.mac": "c4:f7:d5:b5:47:f4", @@ -420,7 +415,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 3780, + "log.offset": 3776, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -477,7 +472,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:42.000-02:00", "client.bytes": 0, "client.ip": "172.17.35.101", "client.mac": "24:01:c7:07:2b:a2", @@ -512,7 +506,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 4672, + "log.offset": 4667, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -569,7 +563,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:43.000-02:00", "client.bytes": 0, "client.ip": "172.16.36.105", "client.mac": "34:db:fd:83:d8:09", @@ -605,7 +598,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "warning", - "log.offset": 5606, + "log.offset": 5600, "network.bytes": 0, "network.packets": 0, "network.transport": "udp", @@ -656,7 +649,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:44.000-02:00", "client.bytes": 0, "client.ip": "10.82.234.9", "client.nat.port": 0, @@ -690,7 +682,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 6490, + "log.offset": 6483, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -740,7 +732,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:45.000-02:00", "client.bytes": 0, "client.ip": "10.84.234.7", "client.mac": "00:00:00:00:00:00", @@ -776,7 +767,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "informational", - "log.offset": 7358, + "log.offset": 7350, "network.bytes": 0, "network.direction": "internal", "network.packets": 0, @@ -840,7 +831,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:45.000-02:00", "client.bytes": 0, "client.ip": "192.168.1.254", "client.mac": "34:db:fd:83:d8:09", @@ -874,7 +864,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "notification", - "log.offset": 8333, + "log.offset": 8324, "network.bytes": 0, "network.packets": 0, "network.transport": "icmp", @@ -927,7 +917,6 @@ ] }, { - "@timestamp": "2020-06-05T12:38:53.000-02:00", "client.bytes": 1802, "client.ip": "172.17.35.119", "client.mac": "00:00:00:00:00:00", @@ -962,7 +951,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "informational", - "log.offset": 9254, + "log.offset": 9244, "network.bytes": 3534, "network.packets": 12, "network.transport": "tcp", @@ -1018,7 +1007,6 @@ ] }, { - "@timestamp": "2018-05-30T13:26:37.000-02:00", "client.bytes": 0, "client.ip": "10.198.32.19", "client.nat.port": 0, @@ -1060,7 +1048,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 10194, + "log.offset": 10183, "network.bytes": 0, "network.packets": 0, "network.transport": "udp", @@ -1109,7 +1097,6 @@ ] }, { - "@timestamp": "2018-06-04T17:20:24.000-02:00", "client.bytes": 0, "client.ip": "0.0.0.0", "client.nat.port": 0, @@ -1143,7 +1130,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 11059, + "log.offset": 11047, "network.bytes": 0, "network.packets": 0, "network.transport": "0", @@ -1190,7 +1177,6 @@ ] }, { - "@timestamp": "2018-05-30T14:01:32.000-02:00", "client.bytes": 0, "client.ip": "10.198.38.184", "client.mac": "c8:5b:76:ab:72:d3", @@ -1225,7 +1211,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 11887, + "log.offset": 11874, "network.bytes": 0, "network.packets": 0, "network.transport": "udp", @@ -1275,7 +1261,6 @@ ] }, { - "@timestamp": "2018-05-30T14:17:17.000-02:00", "client.bytes": 0, "client.ip": "10.198.32.19", "client.mac": "b8:97:5a:5b:0f:fd", @@ -1311,7 +1296,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 12757, + "log.offset": 12743, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -1361,7 +1346,6 @@ ] }, { - "@timestamp": "2018-06-05T14:30:31.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.23", "client.nat.port": 0, @@ -1393,7 +1377,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 13613, + "log.offset": 13598, "network.bytes": 0, "network.packets": 0, "network.transport": "icmp", @@ -1441,7 +1425,6 @@ ] }, { - "@timestamp": "2018-05-31T17:05:14.000-02:00", "client.bytes": 0, "client.ip": "10.198.12.19", "client.nat.port": 0, @@ -1484,7 +1467,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 14455, + "log.offset": 14439, "network.bytes": 0, "network.packets": 0, "network.transport": "tcp", @@ -1532,7 +1515,6 @@ ] }, { - "@timestamp": "2018-05-30T15:09:51.000-02:00", "client.bytes": 0, "client.ip": "fe80::59f5:3ce8:c98e:5062", "client.mac": "1e:3a:5a:5b:23:ab", @@ -1567,7 +1549,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 15294, + "log.offset": 15277, "network.bytes": 0, "network.packets": 0, "network.transport": "udp", @@ -1617,7 +1599,6 @@ ] }, { - "@timestamp": "2018-06-01T10:57:55.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.57", "client.mac": "08:00:27:4c:49:e3", @@ -1650,7 +1631,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 16166, + "log.offset": 16148, "network.bytes": 0, "network.packets": 0, "network.transport": "icmp", @@ -1701,7 +1682,6 @@ ] }, { - "@timestamp": "2018-06-01T10:55:41.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.57", "client.mac": "08:00:27:4c:49:e3", @@ -1735,7 +1715,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 17032, + "log.offset": 17013, "network.bytes": 0, "network.packets": 0, "network.transport": "icmp", @@ -1784,5 +1764,203 @@ "forwarded", "sophos-xg" ] + }, + { + "client.bytes": 0, + "client.ip": "1.2.3.4", + "client.mac": "11:22:33:44:55:66", + "client.nat.port": 0, + "client.packets": 0, + "client.port": 33370, + "destination.bytes": 0, + "destination.ip": "4.3.2.1", + "destination.mac": "66:55:44:33:22:11", + "destination.nat.ip": "8.6.4.2", + "destination.nat.port": 0, + "destination.packets": 0, + "destination.port": 443, + "event.action": "allowed", + "event.category": [ + "network" + ], + "event.code": "010101600001", + "event.dataset": "sophos.xg", + "event.duration": 0, + "event.end": "2021-02-11T13:12:45.000-02:00", + "event.kind": "event", + "event.module": "sophos", + "event.original": "device=\"SFW\" date=2021-02-11 time=13:12:45 timezone=\"CET\" device_name=\"XG210\" device_id=dem-dev log_id=010101600001 log_type=\"Firewall\" log_component=\"Firewall Rule\" log_subtype=\"Allowed\" status=\"Allow\" priority=Information duration=0 fw_rule_id=9 nat_rule_id=16 policy_type=1 user_name=\"\" user_gp=\"\" iap=0 ips_policy_id=0 appfilter_policy_id=0 application=\"\" application_risk=0 application_technology=\"\" application_category=\"\" vlan_id=\"\" ether_type=Unknown (0x0000) bridge_name=\"\" bridge_display_name=\"\" in_interface=\"Port2.109\" in_display_interface=\"CD21-IPs_WAN\" out_interface=\"Port5.200\" out_display_interface=\"Port5\" src_mac=11:22:33:44:55:66 dst_mac=66:55:44:33:22:11 src_ip=1.2.3.4 src_country_code=ESP dst_ip=4.3.2.1 dst_country_code=GB protocol=\"TCP\" src_port=33370 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=2.4.6.8 tran_src_port=0 tran_dst_ip=8.6.4.2 tran_dst_port=0 srczonetype=\"WAN\" srczone=\"WAN\" dstzonetype=\"DMZ\" dstzone=\"Zone 9\" dir_disp=\"\" connevent=\"Start\" connid=\"3933925696\" vconnid=\"\" hb_health=\"No Heartbeat\" message=\"\" appresolvedby=\"Signature\" app_is_cloud=0", + "event.outcome": "success", + "event.severity": "6", + "event.start": "2021-02-11T13:12:45.000-02:00", + "event.timezone": "-02:00", + "event.type": [ + "allowed", + "connection", + "start" + ], + "fileset.name": "xg", + "host.name": "firewall.localgroup.local", + "input.type": "log", + "log.level": "informational", + "log.offset": 17878, + "network.bytes": 0, + "network.direction": "inbound", + "network.packets": 0, + "network.transport": "tcp", + "observer.egress.interface.name": "Port5.200", + "observer.egress.zone": "DMZ", + "observer.ingress.interface.name": "Port2.109", + "observer.ingress.zone": "WAN", + "observer.product": "XG", + "observer.serial_number": "dem-dev", + "observer.type": "firewall", + "observer.vendor": "Sophos", + "related.hosts": [ + "firewall.localgroup.local" + ], + "related.ip": [ + "1.2.3.4", + "2.4.6.8", + "4.3.2.1", + "8.6.4.2" + ], + "rule.id": "9", + "rule.ruleset": "1", + "server.bytes": 0, + "server.ip": "4.3.2.1", + "server.mac": "66:55:44:33:22:11", + "server.nat.port": 0, + "server.packets": 0, + "server.port": 443, + "service.type": "sophos", + "sophos.xg.app_is_cloud": "0", + "sophos.xg.appfilter_policy_id": "0", + "sophos.xg.application_risk": "0", + "sophos.xg.appresolvedby": "Signature", + "sophos.xg.connevent": "Start", + "sophos.xg.connid": "3933925696", + "sophos.xg.device": "SFW", + "sophos.xg.device_name": "XG210", + "sophos.xg.dst_country_code": "GB", + "sophos.xg.ether_type": "Unknown (0x0000)", + "sophos.xg.hb_health": "No Heartbeat", + "sophos.xg.iap": "0", + "sophos.xg.ips_policy_id": "0", + "sophos.xg.log_component": "Firewall Rule", + "sophos.xg.log_subtype": "Allowed", + "sophos.xg.log_type": "Firewall", + "sophos.xg.message_id": "00001", + "sophos.xg.priority": "Information", + "sophos.xg.src_country_code": "ESP", + "sophos.xg.status": "Allow", + "source.bytes": 0, + "source.ip": "1.2.3.4", + "source.mac": "11:22:33:44:55:66", + "source.nat.ip": "2.4.6.8", + "source.nat.port": 0, + "source.packets": 0, + "source.port": 33370, + "tags": [ + "forwarded", + "sophos-xg" + ] + }, + { + "client.bytes": 0, + "client.ip": "10.146.13.30", + "client.mac": "00:50:56:99:51:94", + "client.nat.port": 0, + "client.packets": 0, + "client.port": 45294, + "destination.bytes": 0, + "destination.ip": "10.8.142.181", + "destination.mac": "00:50:56:99:3D:AC", + "destination.nat.port": 0, + "destination.packets": 0, + "destination.port": 443, + "event.action": "allowed", + "event.category": [ + "network" + ], + "event.code": "010101600001", + "event.dataset": "sophos.xg", + "event.duration": 0, + "event.end": "2020-06-05T03:45:23.000-02:00", + "event.kind": "event", + "event.module": "sophos", + "event.original": "device=\"SFW\" date=2020-06-05 time=03:45:23 timezone=\"CEST\" device_name=\"SF01V\" device_id=SFDemo-ta-vm-55 log_id=010101600001 log_type=\"Firewall\" log_component=\"Firewall Rule\" log_subtype=\"Allowed\" status=\"Allow\" priority=Information duration=0 fw_rule_id=5 nat_rule_id=2 policy_type=1 user_name=\"\" user_gp=\"\" iap=13 ips_policy_id=0 appfilter_policy_id=0 application=\"\" application_risk=0 application_technology=\"\" application_category=\"\" vlan_id=\"\" ether_type=Unknown (0x0000) bridge_name=\"\" bridge_display_name=\"\" in_interface=\"Port2\" in_display_interface=\"Port2\" out_interface=\"Port1\" out_display_interface=\"Port1\" src_mac=00:50:56:99:51:94 dst_mac=00:50:56:99:3D:AC src_ip=10.146.13.30 src_country_code= dst_ip=10.8.142.181 dst_country_code= protocol=\"TCP\" src_port=45294 dst_port=443 sent_pkts=0 recv_pkts=0 sent_bytes=0 recv_bytes=0 tran_src_ip=10.8.13.110 tran_src_port=0 tran_dst_ip= tran_dst_port=0 srczonetype=\"LAN\" srczone=\"LAN\" dstzonetype=\"WAN\" dstzone=\"WAN\" dir_disp=\"\" connevent=\"Start\" connid=\"2674291981\" vconnid=\"\" hb_health=\"No Heartbeat\"message=\"\" appresolvedby=\"Signature\" app_is_cloud=0 log_occurrence=1", + "event.outcome": "success", + "event.severity": "6", + "event.start": "2020-06-05T03:45:23.000-02:00", + "event.timezone": "-02:00", + "event.type": [ + "allowed", + "connection", + "start" + ], + "fileset.name": "xg", + "host.name": "firewall.localgroup.local", + "input.type": "log", + "log.level": "informational", + "log.offset": 19024, + "network.bytes": 0, + "network.direction": "outbound", + "network.packets": 0, + "network.transport": "tcp", + "observer.egress.interface.name": "Port1", + "observer.egress.zone": "WAN", + "observer.ingress.interface.name": "Port2", + "observer.ingress.zone": "LAN", + "observer.product": "XG", + "observer.serial_number": "SFDemo-ta-vm-55", + "observer.type": "firewall", + "observer.vendor": "Sophos", + "related.hosts": [ + "firewall.localgroup.local" + ], + "related.ip": [ + "10.146.13.30", + "10.8.13.110", + "10.8.142.181" + ], + "rule.id": "5", + "rule.ruleset": "1", + "server.bytes": 0, + "server.ip": "10.8.142.181", + "server.mac": "00:50:56:99:3D:AC", + "server.nat.port": 0, + "server.packets": 0, + "server.port": 443, + "service.type": "sophos", + "sophos.xg.app_is_cloud": "0", + "sophos.xg.appfilter_policy_id": "0", + "sophos.xg.application_risk": "0", + "sophos.xg.appresolvedby": "Signature", + "sophos.xg.connevent": "Start", + "sophos.xg.connid": "2674291981", + "sophos.xg.device": "SFW", + "sophos.xg.device_name": "SF01V", + "sophos.xg.ether_type": "Unknown (0x0000)", + "sophos.xg.hb_health": "No Heartbeat\"message=", + "sophos.xg.iap": "13", + "sophos.xg.ips_policy_id": "0", + "sophos.xg.log_component": "Firewall Rule", + "sophos.xg.log_subtype": "Allowed", + "sophos.xg.log_type": "Firewall", + "sophos.xg.message_id": "00001", + "sophos.xg.priority": "Information", + "sophos.xg.status": "Allow", + "source.bytes": 0, + "source.ip": "10.146.13.30", + "source.mac": "00:50:56:99:51:94", + "source.nat.ip": "10.8.13.110", + "source.nat.port": 0, + "source.packets": 0, + "source.port": 45294, + "tags": [ + "forwarded", + "sophos-xg" + ] } ] \ No newline at end of file diff --git a/x-pack/filebeat/module/sophos/xg/test/idp.log b/x-pack/filebeat/module/sophos/xg/test/idp.log index 818b057ba8fb..57d9e84066d2 100644 --- a/x-pack/filebeat/module/sophos/xg/test/idp.log +++ b/x-pack/filebeat/module/sophos/xg/test/idp.log @@ -1,6 +1,6 @@ -<30>device="SFW" date=2020-05-18 time=14:38:54 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=25 user_name="" signature_id=1881 signature_msg="SERVER-WEBAPP bad HTTP 1.1 request - potential worm attack" classification="access to a potentially vulnerable web application" rule_priority=2 src_ip=67.43.156.12 src_country_code=ROU dst_ip=172.16.68.20 dst_country_code=R1 protocol="TCP" src_port=41528 dst_port=80 platform="BSD,Linux,Mac,Other,Solaris,Unix,Windows" category="server-webapp" target="Server" -<30>device="SFW" date=2020-05-18 time=14:38:55 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=23 user_name="" signature_id=1616 signature_msg="PROTOCOL-DNS named version attempt" classification="Attempted Information Leak" rule_priority=1 src_ip=89.160.20.156 src_country_code=CHN dst_ip=67.43.156.12 dst_country_code=R1 protocol="UDP" src_port=58914 dst_port=53 platform="BSD,Linux,Mac,Other,Solaris,Unix,Windows" category="protocol-dns" target="Server" -<30>device="SFW" date=2020-05-18 time=14:38:56 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=25 user_name="" signature_id=53589 signature_msg="SERVER-WEBAPP DrayTek multiple products command injection attempt" classification="Web Application Attack" rule_priority=2 src_ip=67.43.156.12 src_country_code=NLD dst_ip=172.16.68.20 dst_country_code=R1 protocol="TCP" src_port=59476 dst_port=80 platform="Linux,Mac,Other,Unix,Windows" category="server-webapp" target="Server" -<30>device="SFW" date=2018-05-23 time=16:20:34 timezone="BST" device_name="XG750" device_id=SFDemo-f64dd6be log_id=020703406001 log_type="IDP" log_component="Anomaly" log_subtype="Detect" priority=Warning idp_policy_id=1 fw_rule_id=2 user_name="" signature_id=26022 signature_msg="FILE-PDF EmbeddedFile contained within a PDF" classification="A Network Trojan was detected" rule_priority=1 src_ip=10.0.0.168 src_country_code=R1 dst_ip=10.1.1.234 dst_country_code=R1 protocol="TCP" src_port=28938 dst_port=25 platform="Windows" category="Malware Communication" target="Server" -<30>device="SFW" date=2018-05-23 time=16:16:43 timezone="BST" device_name="XG750" device_id=SFDemo-f64dd6be log_id=020704406002 log_type="IDP" log_component="Anomaly" log_subtype="Drop" priority=Warning idp_policy_id=1 fw_rule_id=2 user_name="" signature_id=26022 signature_msg="FILE-PDF EmbeddedFile contained within a PDF" classification="A Network Trojan was detected" rule_priority=1 src_ip=10.0.1.31 src_country_code=R1 dst_ip=10.1.0.115 dst_country_code=R1 protocol="TCP" src_port=40140 dst_port=25 platform="Windows" category="Malware Communication" target="Server" - +<30>device="SFW" date=2020-05-18 time=14:38:54 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=25 user_name="" signature_id=1881 signature_msg="SERVER-WEBAPP bad HTTP 1.1 request - potential worm attack" classification="access to a potentially vulnerable web application" rule_priority=2 src_ip=67.43.156.12 src_country_code=ROU dst_ip=172.16.68.20 dst_country_code=R1 protocol="TCP" src_port=41528 dst_port=80 platform="BSD,Linux,Mac,Other,Solaris,Unix,Windows" category="server-webapp" target="Server" +<30>device="SFW" date=2020-05-18 time=14:38:55 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=23 user_name="" signature_id=1616 signature_msg="PROTOCOL-DNS named version attempt" classification="Attempted Information Leak" rule_priority=1 src_ip=89.160.20.156 src_country_code=CHN dst_ip=67.43.156.12 dst_country_code=R1 protocol="UDP" src_port=58914 dst_port=53 platform="BSD,Linux,Mac,Other,Solaris,Unix,Windows" category="protocol-dns" target="Server" +<30>device="SFW" date=2020-05-18 time=14:38:56 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=020804407002 log_type="IDP" log_component="Signatures" log_subtype="Drop" priority=Warning idp_policy_id=7 fw_rule_id=25 user_name="" signature_id=53589 signature_msg="SERVER-WEBAPP DrayTek multiple products command injection attempt" classification="Web Application Attack" rule_priority=2 src_ip=67.43.156.12 src_country_code=NLD dst_ip=172.16.68.20 dst_country_code=R1 protocol="TCP" src_port=59476 dst_port=80 platform="Linux,Mac,Other,Unix,Windows" category="server-webapp" target="Server" +<30>device="SFW" date=2018-05-23 time=16:20:34 timezone="BST" device_name="XG750" device_id=SFDemo-f64dd6be log_id=020703406001 log_type="IDP" log_component="Anomaly" log_subtype="Detect" priority=Warning idp_policy_id=1 fw_rule_id=2 user_name="" signature_id=26022 signature_msg="FILE-PDF EmbeddedFile contained within a PDF" classification="A Network Trojan was detected" rule_priority=1 src_ip=10.0.0.168 src_country_code=R1 dst_ip=10.1.1.234 dst_country_code=R1 protocol="TCP" src_port=28938 dst_port=25 platform="Windows" category="Malware Communication" target="Server" +<30>device="SFW" date=2018-05-23 time=16:16:43 timezone="BST" device_name="XG750" device_id=SFDemo-f64dd6be log_id=020704406002 log_type="IDP" log_component="Anomaly" log_subtype="Drop" priority=Warning idp_policy_id=1 fw_rule_id=2 user_name="" signature_id=26022 signature_msg="FILE-PDF EmbeddedFile contained within a PDF" classification="A Network Trojan was detected" rule_priority=1 src_ip=10.0.1.31 src_country_code=R1 dst_ip=10.1.0.115 dst_country_code=R1 protocol="TCP" src_port=40140 dst_port=25 platform="Windows" category="Malware Communication" target="Server" + diff --git a/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json index de3cb1b31117..37b56704bb41 100644 --- a/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:54.000-02:00", "client.ip": "67.43.156.12", "client.port": 41528, "destination.ip": "172.16.68.20", @@ -74,7 +73,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:55.000-02:00", "client.ip": "89.160.20.156", "client.port": 58914, "destination.as.number": 35908, @@ -106,7 +104,7 @@ "host.name": "my_fancy_host", "input.type": "log", "log.level": "warning", - "log.offset": 645, + "log.offset": 644, "network.transport": "UDP", "observer.product": "XG", "observer.serial_number": "1234567890123456", @@ -158,7 +156,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:56.000-02:00", "client.ip": "67.43.156.12", "client.port": 59476, "destination.ip": "172.16.68.20", @@ -184,7 +181,7 @@ "host.name": "some_other_host.local", "input.type": "log", "log.level": "warning", - "log.offset": 1242, + "log.offset": 1240, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "1234567890123457", @@ -232,7 +229,6 @@ ] }, { - "@timestamp": "2018-05-23T16:20:34.000-02:00", "client.ip": "10.0.0.168", "client.port": 28938, "destination.ip": "10.1.1.234", @@ -258,7 +254,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 1855, + "log.offset": 1852, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "SFDemo-f64dd6be", @@ -300,7 +296,6 @@ ] }, { - "@timestamp": "2018-05-23T16:16:43.000-02:00", "client.ip": "10.0.1.31", "client.port": 40140, "destination.ip": "10.1.0.115", @@ -326,7 +321,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "warning", - "log.offset": 2432, + "log.offset": 2428, "network.transport": "TCP", "observer.product": "XG", "observer.serial_number": "SFDemo-f64dd6be", diff --git a/x-pack/filebeat/module/sophos/xg/test/sandbox.log b/x-pack/filebeat/module/sophos/xg/test/sandbox.log index bd64715de04c..097b999d89cf 100644 --- a/x-pack/filebeat/module/sophos/xg/test/sandbox.log +++ b/x-pack/filebeat/module/sophos/xg/test/sandbox.log @@ -1,6 +1,6 @@ -<30>device="SFW" date=2017-01-31 time=14:52:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=138301618041 log_type="Sandbox" log_component="Mail" log_subtype="Allowed" priority=Information user_name="" src_ip= filename="" filetype="" filesize=0 sha1sum="" source="" reason="eligible" destination="" subject="" -<30>device="SFW" date=2017-01-31 time=14:52:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=138302218042 log_type="Sandbox" log_component="Mail" log_subtype="Denied" priority=Critical user_name="jsmith@iview.com" src_ip=10.198.47.112 filename="1.exe" filetype="application/octet-stream" filesize=153006 sha1sum="83cd339302bf5e8ed5240ca6383418089c337a81" source="jsmith@iview.com" reason="cached malicious" destination="" subject="" -<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=136501618041 log_type="Sandbox" log_component="Web" log_subtype="Allowed" priority=Information user_name="" src_ip= filename="" filetype="" filesize=0 sha1sum="" source="" reason="eligible" destination="" subject="" -<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136528618043 log_type="Sandbox" log_component="Web" log_subtype="Pending" priority=Information user_name="jsmith" src_ip=10.198.47.112 filename="19.exe" filetype="application/octet-stream" filesize=153010 sha1sum="3ce799580908df9ca0dc649aa8c2d06ab267e8c8" source="10.198.241.50" reason="pending" destination="" subject="" -<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136502218042 log_type="Sandbox" log_component="Web" log_subtype="Denied" priority=Critical user_name="jsmith" src_ip=10.198.47.112 filename="19.exe" filetype="application/octet-stream" filesize=153010 sha1sum="3ce799580908df9ca0dc649aa8c2d06ab267e8c8" source="10.198.241.50" reason="cloud malicious" destination="" subject=" -<30>device="SFW" date=2020-05-18 time=14:38:36 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136502218042 log_type="Sandbox" log_component="Web" log_subtype="Denied" priority=Critical user_name="" src_ip=172.16.34.24 filename="SBTestFile1.pdf" filetype="application/pdf" filesize=1124 sha1sum="d910c4a81122c360fe57f67a04999425a65249db" source="sophostest.com" reason="cached malicious" destination="" subject="" +<30>device="SFW" date=2017-01-31 time=14:52:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=138301618041 log_type="Sandbox" log_component="Mail" log_subtype="Allowed" priority=Information user_name="" src_ip= filename="" filetype="" filesize=0 sha1sum="" source="" reason="eligible" destination="" subject="" +<30>device="SFW" date=2017-01-31 time=14:52:11 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=138302218042 log_type="Sandbox" log_component="Mail" log_subtype="Denied" priority=Critical user_name="jsmith@iview.com" src_ip=10.198.47.112 filename="1.exe" filetype="application/octet-stream" filesize=153006 sha1sum="83cd339302bf5e8ed5240ca6383418089c337a81" source="jsmith@iview.com" reason="cached malicious" destination="" subject="" +<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44313350024-P29PUA log_id=136501618041 log_type="Sandbox" log_component="Web" log_subtype="Allowed" priority=Information user_name="" src_ip= filename="" filetype="" filesize=0 sha1sum="" source="" reason="eligible" destination="" subject="" +<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136528618043 log_type="Sandbox" log_component="Web" log_subtype="Pending" priority=Information user_name="jsmith" src_ip=10.198.47.112 filename="19.exe" filetype="application/octet-stream" filesize=153010 sha1sum="3ce799580908df9ca0dc649aa8c2d06ab267e8c8" source="10.198.241.50" reason="pending" destination="" subject="" +<30>device="SFW" date=2017-01-31 time=15:28:25 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136502218042 log_type="Sandbox" log_component="Web" log_subtype="Denied" priority=Critical user_name="jsmith" src_ip=10.198.47.112 filename="19.exe" filetype="application/octet-stream" filesize=153010 sha1sum="3ce799580908df9ca0dc649aa8c2d06ab267e8c8" source="10.198.241.50" reason="cloud malicious" destination="" subject=" +<30>device="SFW" date=2020-05-18 time=14:38:36 timezone="IST" device_name="CR750iNG-XP" device_id=C44310050024-P29PUA log_id=136502218042 log_type="Sandbox" log_component="Web" log_subtype="Denied" priority=Critical user_name="" src_ip=172.16.34.24 filename="SBTestFile1.pdf" filetype="application/pdf" filesize=1124 sha1sum="d910c4a81122c360fe57f67a04999425a65249db" source="sophostest.com" reason="cached malicious" destination="" subject="" diff --git a/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json index a112d1dc23e7..15343c1e3e27 100644 --- a/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2017-01-31T14:52:11.000-02:00", "event.action": "Allowed", "event.category": [ "network" @@ -46,7 +45,6 @@ ] }, { - "@timestamp": "2017-01-31T14:52:11.000-02:00", "client.ip": "10.198.47.112", "event.action": "Denied", "event.category": [ @@ -72,7 +70,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 343, + "log.offset": 342, "observer.product": "XG", "observer.serial_number": "C44310050024-P29PUA", "observer.type": "firewall", @@ -108,7 +106,6 @@ ] }, { - "@timestamp": "2017-01-31T15:28:25.000-02:00", "event.action": "Allowed", "event.category": [ "network" @@ -131,7 +128,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 809, + "log.offset": 807, "observer.product": "XG", "observer.serial_number": "C44313350024-P29PUA", "observer.type": "firewall", @@ -154,7 +151,6 @@ ] }, { - "@timestamp": "2017-01-31T15:28:25.000-02:00", "client.ip": "10.198.47.112", "event.action": "Pending", "event.category": [ @@ -179,7 +175,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "informational", - "log.offset": 1151, + "log.offset": 1148, "observer.product": "XG", "observer.serial_number": "C44310050024-P29PUA", "observer.type": "firewall", @@ -215,7 +211,6 @@ ] }, { - "@timestamp": "2017-01-31T15:28:25.000-02:00", "client.ip": "10.198.47.112", "event.action": "Denied", "event.category": [ @@ -241,7 +236,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 1599, + "log.offset": 1595, "observer.product": "XG", "observer.serial_number": "C44310050024-P29PUA", "observer.type": "firewall", @@ -277,7 +272,6 @@ ] }, { - "@timestamp": "2020-05-18T14:38:36.000-02:00", "client.ip": "172.16.34.24", "event.action": "Denied", "event.category": [ @@ -303,7 +297,7 @@ "host.name": "firewall.localgroup.local", "input.type": "log", "log.level": "critical", - "log.offset": 2050, + "log.offset": 2045, "observer.product": "XG", "observer.serial_number": "C44310050024-P29PUA", "observer.type": "firewall", diff --git a/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json index f3f6f6a45978..9af985b4a368 100644 --- a/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127626618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -37,7 +36,6 @@ ] }, { - "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127726618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -75,7 +73,6 @@ ] }, { - "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "123526618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -117,7 +114,6 @@ ] }, { - "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127826618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -155,7 +151,6 @@ ] }, { - "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127926618031", "event.dataset": "sophos.xg", "event.kind": "event", diff --git a/x-pack/filebeat/module/sophos/xg/test/waf.log b/x-pack/filebeat/module/sophos/xg/test/waf.log index ed60311864f6..2f99b3b9388e 100644 --- a/x-pack/filebeat/module/sophos/xg/test/waf.log +++ b/x-pack/filebeat/module/sophos/xg/test/waf.log @@ -1,5 +1,5 @@ -<30>device="SFW" date=2020-05-18 time=14:38:46 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=webmail.elasticuser.com sourceip=216.160.83.61 localip=185.8.209.207 ws_protocol="HTTP/1.1" url=/mapi/nspi/ querystring=?MailboxId=642ea57c-90ab-4571-8e05-c6997b2256f8@elastic.user.com cookie="MapiContext=MAPIAAAAAPaw98Xx0uDQ4tL/z/rX59b2x/LI+8z2x/+lhrKGtIO7jbmBsxYNAAAAAAAA;MapiRouting=UlVNOjdmNWY0OGE3LTM5OWItNDc4Yi04ZDgwLWFmZTRmMzAyZTViMDoAitM4bv3XCA==;MapiSequence=10-GtgsIA==;X-BackEndCookie=642ea57c-90ab-4571-8e05-c6997b2256f8=u56Lnp2ejJqByZrHyZ7Mys7Sm8zJnNLLnM3J0sbJxsvSnZzIxs2ans+ezMrLgYHNz83P0s/J0s3Pq87Pxc7PxcrL" referer=- method=POST httpstatus=401 reason="-" extra="-" contenttype="-" useragent="Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.4954; Pro)" host=216.160.83.61 responsetime=11199 bytessent=5669 bytesrcv=1419 fw_rule_id=79 -<30>device="SFW" date=2020-05-18 time=14:38:47 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=webmail.elasticuser.com sourceip=216.160.83.61 localip=185.8.209.207 ws_protocol="HTTP/1.1" url=/mapi/nspi/ querystring=?MailboxId=642ea57c-90ab-4571-8e05-c6997b2256f8@elastic.user.com cookie="MapiContext=MAPIAAAAAPaw98Xx0uDQ4tL/z/rX59b2x/LI+8z2x/+lhrKGtIO7jbmBsw0NAAAAAAAA;MapiRouting=UlVNOjdmNWY0OGE3LTM5OWItNDc4Yi04ZDgwLWFmZTRmMzAyZTViMDpeyft5bv3XCA==;MapiSequence=9-Km2JMg==;X-BackEndCookie=642ea57c-90ab-4571-8e05-c6997b2256f8=u56Lnp2ejJqByZrHyZ7Mys7Sm8zJnNLLnM3J0sbJxsvSnZzIxs2ans+ezMrLgYHNz83P0s/J0s3Pq87Pxc7Oxc3M" referer=- method=POST httpstatus=200 reason="-" extra="-" contenttype="application/mapi-http" useragent="Microsoft Office/16.0 (Windows NT 6.2; Microsoft Outlook 16.0.4954; Pro)" host=216.160.83.61 responsetime=14086 bytessent=1357 bytesrcv=1774 fw_rule_id=79 -<30>device="SFW" date=2020-05-19 time=17:20:29 timezone="IST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="jsmith" server=www.iviewtest.com:8989 sourceip=10.198.235.254 localip=10.198.233.48 ws_protocol="HTTP/1.1" url=/ querystring= cookie="-" referer=- method=GET httpstatus=403 reason="Static URL Hardening" extra="No signature found" contenttype="text/html" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" host=10.198.235.254 responsetime=19310 bytessent=726 bytesrcv=510 fw_rule_id=3 -<30>device="SFW" date=2020-05-19 time=18:03:30 timezone="IST" device_name="XG230" device_id=1234567890123456 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="jsmith" server=www.iviewtest.com:8990 sourceip=10.198.235.254 localip=10.198.233.48 ws_protocol="HTTP/1.1" url=/download/eicarcom2.zip querystring= cookie="; PHPSESSID=jetkd9iadd969hsr77jpj4q974; _pk_id.1.fc3a=3a6250e215194a92.1485866024.1.1485866069.1485866024.; _pk_ses.1.fc3a=*" referer=http://www.iviewtest.com:8990/85-0-Download.html method=GET httpstatus=403 reason="Antivirus" extra="EICAR-AV-Test" contenttype="text/html" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" host=10.198.235.254 responsetime=403214 bytessent=739 bytesrcv=715 fw_rule_id=6 -<30>device="SFW" date=2020-05-20 time=18:03:31 timezone="IST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=- sourceip=89.160.20.112 localip=216.167.51.72 ws_protocol="HTTP/1.0" url=/ querystring="" cookie="-" referer="-" method=GET httpstatus=403 reason="WAF Anomaly" extra="Inbound Anomaly Score Exceeded (Total Score: 7, SQLi=, XSS=): Last Matched Message: Request Missing a User Agent Header" contenttype="text/html" useragent="-" host=89.160.20.112 responsetime=608 bytessent=5353 bytesrcv=295 fw_rule_id=3 +<30>device="SFW" date=2020-05-18 time=14:38:46 timezone="CEST" device_name="XG230" device_id=1234567890123456 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=webmail.elasticuser.com sourceip=216.160.83.61 localip=185.8.209.207 ws_protocol="HTTP/1.1" url=/mapi/nspi/ querystring=?MailboxId=642ea57c-90ab-4571-8e05-c6997b2256f8@elastic.user.com cookie="MapiContext=MAPIAAAAAPaw98Xx0uDQ4tL/z/rX59b2x/LI+8z2x/+lhrKGtIO7jbmBsxYNAAAAAAAA;MapiRouting=UlVNOjdmNWY0OGE3LTM5OWItNDc4Yi04ZDgwLWFmZTRmMzAyZTViMDoAitM4bv3XCA==;MapiSequence=10-GtgsIA==;X-BackEndCookie=642ea57c-90ab-4571-8e05-c6997b2256f8=u56Lnp2ejJqByZrHyZ7Mys7Sm8zJnNLLnM3J0sbJxsvSnZzIxs2ans+ezMrLgYHNz83P0s/J0s3Pq87Pxc7PxcrL" referer=- method=POST httpstatus=401 reason="-" extra="-" contenttype="-" useragent="Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.4954; Pro)" host=216.160.83.61 responsetime=11199 bytessent=5669 bytesrcv=1419 fw_rule_id=79 +<30>device="SFW" date=2020-05-18 time=14:38:47 timezone="CEST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=webmail.elasticuser.com sourceip=216.160.83.61 localip=185.8.209.207 ws_protocol="HTTP/1.1" url=/mapi/nspi/ querystring=?MailboxId=642ea57c-90ab-4571-8e05-c6997b2256f8@elastic.user.com cookie="MapiContext=MAPIAAAAAPaw98Xx0uDQ4tL/z/rX59b2x/LI+8z2x/+lhrKGtIO7jbmBsw0NAAAAAAAA;MapiRouting=UlVNOjdmNWY0OGE3LTM5OWItNDc4Yi04ZDgwLWFmZTRmMzAyZTViMDpeyft5bv3XCA==;MapiSequence=9-Km2JMg==;X-BackEndCookie=642ea57c-90ab-4571-8e05-c6997b2256f8=u56Lnp2ejJqByZrHyZ7Mys7Sm8zJnNLLnM3J0sbJxsvSnZzIxs2ans+ezMrLgYHNz83P0s/J0s3Pq87Pxc7Oxc3M" referer=- method=POST httpstatus=200 reason="-" extra="-" contenttype="application/mapi-http" useragent="Microsoft Office/16.0 (Windows NT 6.2; Microsoft Outlook 16.0.4954; Pro)" host=216.160.83.61 responsetime=14086 bytessent=1357 bytesrcv=1774 fw_rule_id=79 +<30>device="SFW" date=2020-05-19 time=17:20:29 timezone="IST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="jsmith" server=www.iviewtest.com:8989 sourceip=10.198.235.254 localip=10.198.233.48 ws_protocol="HTTP/1.1" url=/ querystring= cookie="-" referer=- method=GET httpstatus=403 reason="Static URL Hardening" extra="No signature found" contenttype="text/html" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" host=10.198.235.254 responsetime=19310 bytessent=726 bytesrcv=510 fw_rule_id=3 +<30>device="SFW" date=2020-05-19 time=18:03:30 timezone="IST" device_name="XG230" device_id=1234567890123456 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="jsmith" server=www.iviewtest.com:8990 sourceip=10.198.235.254 localip=10.198.233.48 ws_protocol="HTTP/1.1" url=/download/eicarcom2.zip querystring= cookie="; PHPSESSID=jetkd9iadd969hsr77jpj4q974; _pk_id.1.fc3a=3a6250e215194a92.1485866024.1.1485866069.1485866024.; _pk_ses.1.fc3a=*" referer=http://www.iviewtest.com:8990/85-0-Download.html method=GET httpstatus=403 reason="Antivirus" extra="EICAR-AV-Test" contenttype="text/html" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" host=10.198.235.254 responsetime=403214 bytessent=739 bytesrcv=715 fw_rule_id=6 +<30>device="SFW" date=2020-05-20 time=18:03:31 timezone="IST" device_name="XG230" device_id=1234567890123457 log_id=075000617071 log_type="WAF" log_component="Web Application Firewall" priority=Information user_name="-" server=- sourceip=89.160.20.112 localip=216.167.51.72 ws_protocol="HTTP/1.0" url=/ querystring="" cookie="-" referer="-" method=GET httpstatus=403 reason="WAF Anomaly" extra="Inbound Anomaly Score Exceeded (Total Score: 7, SQLi=, XSS=): Last Matched Message: Request Missing a User Agent Header" contenttype="text/html" useragent="-" host=89.160.20.112 responsetime=608 bytessent=5353 bytesrcv=295 fw_rule_id=3 diff --git a/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json index 9ed26bd14d00..e944e04898d3 100644 --- a/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2020-05-18T14:38:46.000-02:00", "client.bytes": 1419, "client.ip": "216.160.83.61", "destination.bytes": 401, @@ -75,7 +74,6 @@ "user_agent.original": "Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.4954; Pro)" }, { - "@timestamp": "2020-05-18T14:38:47.000-02:00", "client.bytes": 1774, "client.ip": "216.160.83.61", "destination.bytes": 200, @@ -102,7 +100,7 @@ "http.version": "HTTP/1.1", "input.type": "log", "log.level": "informational", - "log.offset": 993, + "log.offset": 992, "observer.product": "XG", "observer.serial_number": "1234567890123457", "observer.type": "firewall", @@ -151,7 +149,6 @@ "user_agent.original": "Microsoft Office/16.0 (Windows NT 6.2; Microsoft Outlook 16.0.4954; Pro)" }, { - "@timestamp": "2020-05-19T17:20:29.000-02:00", "client.bytes": 510, "client.ip": "10.198.235.254", "destination.bytes": 403, @@ -179,7 +176,7 @@ "http.version": "HTTP/1.1", "input.type": "log", "log.level": "informational", - "log.offset": 2004, + "log.offset": 2002, "observer.product": "XG", "observer.serial_number": "1234567890123457", "observer.type": "firewall", @@ -223,7 +220,6 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" }, { - "@timestamp": "2020-05-19T18:03:30.000-02:00", "client.bytes": 715, "client.ip": "10.198.235.254", "destination.bytes": 403, @@ -252,7 +248,7 @@ "http.version": "HTTP/1.1", "input.type": "log", "log.level": "informational", - "log.offset": 2640, + "log.offset": 2637, "observer.product": "XG", "observer.serial_number": "1234567890123456", "observer.type": "firewall", @@ -299,7 +295,6 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" }, { - "@timestamp": "2020-05-20T18:03:31.000-02:00", "client.bytes": 295, "client.ip": "89.160.20.112", "destination.bytes": 403, @@ -327,7 +322,7 @@ "http.version": "HTTP/1.0", "input.type": "log", "log.level": "informational", - "log.offset": 3453, + "log.offset": 3449, "observer.product": "XG", "observer.serial_number": "1234567890123457", "observer.type": "firewall", diff --git a/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json index d934c831d2ab..d23e1273de3c 100644 --- a/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json @@ -1,6 +1,5 @@ [ { - "@timestamp": "2017-02-01T14:17:35.000-02:00", "event.code": "106025618011", "event.dataset": "sophos.xg", "event.kind": "event", @@ -38,7 +37,6 @@ ] }, { - "@timestamp": "2017-02-01T14:19:47.000-02:00", "event.code": "106025618011", "event.dataset": "sophos.xg", "event.kind": "event", From b89ea6fe60e82ccf91899ad7b62d60e262dc8cef Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 4 Jan 2022 10:29:02 +0100 Subject: [PATCH 137/172] ci: elastic-agent goIntegTest is not available (#29566) --- x-pack/elastic-agent/Jenkinsfile.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/x-pack/elastic-agent/Jenkinsfile.yml b/x-pack/elastic-agent/Jenkinsfile.yml index d2381654009c..96944541255e 100644 --- a/x-pack/elastic-agent/Jenkinsfile.yml +++ b/x-pack/elastic-agent/Jenkinsfile.yml @@ -36,9 +36,6 @@ stages: unitTest: mage: "mage build unitTest" stage: mandatory - goIntegTest: - mage: "mage goIntegTest" - stage: mandatory macos: mage: "mage build unitTest" platforms: ## override default label in this specific stage. From eaa3b32524a9cb9fba83c1de40dfeac3062db7f6 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Tue, 4 Jan 2022 09:39:38 +0000 Subject: [PATCH 138/172] Add kubernetes job name as the controller (#28954) --- CHANGELOG.next.asciidoc | 1 + .../common/kubernetes/metadata/pod_test.go | 55 +++++++++++++++++++ .../common/kubernetes/metadata/resource.go | 3 +- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1d4234fad775..4944d9f47e18 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -26,6 +26,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] +- Add job.name in pods controlled by Jobs {pull}28954[28954] *Auditbeat* diff --git a/libbeat/common/kubernetes/metadata/pod_test.go b/libbeat/common/kubernetes/metadata/pod_test.go index 2ce0ad19877b..ac8106926933 100644 --- a/libbeat/common/kubernetes/metadata/pod_test.go +++ b/libbeat/common/kubernetes/metadata/pod_test.go @@ -252,6 +252,61 @@ func TestPod_Generate(t *testing.T) { }, }, }, + { + name: "test object with owner reference to Job", + input: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + UID: types.UID(uid), + Namespace: namespace, + Labels: map[string]string{ + "foo": "bar", + }, + Annotations: map[string]string{ + "app": "production", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "batch/v1", + Kind: "Job", + Name: "owner", + UID: "005f3b90-4b9d-12f8-acf0-31020a840144", + Controller: &boolean, + }, + }, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + APIVersion: "v1", + }, + Spec: v1.PodSpec{ + NodeName: "testnode", + }, + Status: v1.PodStatus{PodIP: "127.0.0.5"}, + }, + output: common.MapStr{ + "kubernetes": common.MapStr{ + "pod": common.MapStr{ + "name": "obj", + "uid": uid, + "ip": "127.0.0.5", + }, + "namespace": "default", + "job": common.MapStr{ + "name": "owner", + }, + "node": common.MapStr{ + "name": "testnode", + }, + "labels": common.MapStr{ + "foo": "bar", + }, + "annotations": common.MapStr{ + "app": "production", + }, + }, + }, + }, { name: "test object with owner reference to replicaset", input: &v1.Pod{ diff --git a/libbeat/common/kubernetes/metadata/resource.go b/libbeat/common/kubernetes/metadata/resource.go index 152c2be37a3b..95f6ff8f909c 100644 --- a/libbeat/common/kubernetes/metadata/resource.go +++ b/libbeat/common/kubernetes/metadata/resource.go @@ -118,7 +118,8 @@ func (r *Resource) GenerateK8s(kind string, obj kubernetes.Resource, options ... case "Deployment", "ReplicaSet", "StatefulSet", - "DaemonSet": + "DaemonSet", + "Job": safemapstr.Put(meta, strings.ToLower(ref.Kind)+".name", ref.Name) } } From fc7b8fcfd29fc971c6fac8eb506e643b550c7fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 4 Jan 2022 14:24:43 +0100 Subject: [PATCH 139/172] Add more filtering options to journald input (#29294) ## What does this PR do? This PR adds support for `unit`, `transports` and `syslog_identifiers` options for filtering. This PR also introduces a breaking change to `include_matches` option. From now on it does not accept a list of expressions. Now both conjunction (AND) and disjunctions (OR) are supported when applying matches to journals. Collecting entries of two different units: ```yaml - type: journald include_matches.or: - equals: - _SYSTEMD_UNIT=my_unit - _SYSTEMD_UNIT=my_other_unit ``` Collecting entries using syslog transport for a unit ```yaml - type: journald include_matches.and: - equals: - _SYSTEMD_UNIT=my_unit - _TRANSPORT=syslog ``` Although the configuration lets you write complex expressions, systemd does not provide full logical expression support. ## Why is it important? When this change merged, journald input can be marked either beta or GA. Furthermore, now it provides similar filtering capabilities as the good old community Journalbeat did. --- CHANGELOG.next.asciidoc | 3 + .../config/filebeat.inputs.reference.yml.tmpl | 17 +- filebeat/docs/inputs/input-journald.asciidoc | 60 ++++- filebeat/filebeat.reference.yml | 17 +- filebeat/input/journald/config.go | 11 +- filebeat/input/journald/input.go | 33 ++- .../input/journald/input_filtering_test.go | 219 ++++++++++++++++++ filebeat/input/journald/input_parsers_test.go | 4 +- .../journald/pkg/journalfield/default.go | 2 + .../journald/pkg/journalfield/matcher.go | 146 +++++++++++- .../journald/pkg/journalfield/matcher_test.go | 23 ++ x-pack/filebeat/filebeat.reference.yml | 17 +- 12 files changed, 530 insertions(+), 22 deletions(-) create mode 100644 filebeat/input/journald/input_filtering_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 4944d9f47e18..1c73e56a5ecf 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -26,6 +26,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215] - Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870] - Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927] +- Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131] +- `include_matches` option of `journald` input no longer accepts a list of string. {pull}29294[29294] - Add job.name in pods controlled by Jobs {pull}28954[28954] *Auditbeat* @@ -148,6 +150,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868] - Add support for parsers on journald input {pull}29070[29070] - Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087] +- Add support for filtering in journald input with `unit`, `kernel`, `identifiers` and `include_matches`. {pull}29294[29294] - Add new `userAgent` and `beatInfo` template functions for httpjson input {pull}29528[29528] *Heartbeat* diff --git a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl index a1c7166cac06..010e5e36e2fd 100644 --- a/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl +++ b/filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl @@ -566,10 +566,21 @@ filebeat.inputs: #id: service-foo # You may wish to have separate inputs for each service. You can use - # include_matches to specify a list of filter expressions that are + # include_matches.or to specify a list of filter expressions that are # applied as a logical OR. You may specify filter - #include_matches: - #- _SYSTEMD_UNIT=foo.service + #include_matches.or: + #- equals: + #- _SYSTEMD_UNIT=foo.service + + # List of syslog identifiers + #syslog_identifiers: ["audit"] + + # Collect events from the service and messages about the service, + # including coredumps. + #units: ["docker.service"] + + # The list of transports (_TRANSPORT field of journald entries) + #transports: ["audit"] # Parsers are also supported, here is an example of the multiline # parser. diff --git a/filebeat/docs/inputs/input-journald.asciidoc b/filebeat/docs/inputs/input-journald.asciidoc index 32343def2926..bbc4211b0c51 100644 --- a/filebeat/docs/inputs/input-journald.asciidoc +++ b/filebeat/docs/inputs/input-journald.asciidoc @@ -24,8 +24,8 @@ journal. ---- You may wish to have separate inputs for each service. You can use -`include_matches` to specify a list of filter expressions that are applied as a -logical OR. A good way to list the journald fields that are available for +`include_matches` to specify filtering expressions. +A good way to list the https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html[journald fields] that are available for filtering messages is to run `journalctl -o json` to output logs and metadata as JSON. This example collects logs from the `vault.service` systemd unit. @@ -34,7 +34,7 @@ JSON. This example collects logs from the `vault.service` systemd unit. {beatname_lc}.inputs: - type: journald id: service-vault - include_matches: + include_matches.match: - _SYSTEMD_UNIT=vault.service ---- @@ -48,7 +48,7 @@ possible. {beatname_lc}.inputs: - type: journald id: iptables - include_matches: + include_matches.match: - _TRANSPORT=kernel processors: - drop_event: @@ -133,14 +133,64 @@ If you have old log files and want to skip lines, start {beatname_uc} with `seek: tail` specified. Then stop {beatname_uc}, set `seek: cursor`, and restart {beatname_uc}. +[float] +[id="{beatname_lc}-input-{type}-units"] +==== `units` + +Iterate only the entries of the units specified in this option. The iterated entries include +messages from the units, messages about the units by authorized daemons and coredumps. However, +it does not match systemd user units. + +[float] +[id="{beatname_lc}-input-{type}-syslog-identifiers"] +==== `syslog_identifiers` + +Read only the entries with the selected syslog identifiers. + +[float] +[id="{beatname_lc}-input-{type}-transports"] +==== `transports` + +Collect the messages using the specified transports. Example: syslog. + +Valid transports: + +* audit: messages from the kernel audit subsystem +* driver: internally generated messages +* syslog: messages received via the local syslog socket with the syslog protocol +* journal: messages received via the native journal protocol +* stdout: messages from a service's standard output or error output +* kernel: messages from the kernel + [float] [id="{beatname_lc}-input-{type}-include-matches"] ==== `include_matches` -A list of filter expressions used to match fields. The format of the expression +A collection of filter expressions used to match fields. The format of the expression is `field=value`. {beatname_uc} fetches all events that exactly match the expressions. Pattern matching is not supported. +If you configured a filter expression, only entries with this field set will be iterated by the journald reader of Filebeat. +If the filter expressions apply to different fields, only entries with all fields set will be iterated. +If they apply to the same fields, only entries where the field takes one of the specified values will be iterated. + +`match`: List of filter expressions to match fields. +`or`: The filter expressions listed under `or` are connected with a disjunction (or). +`and`: The filter expressions listed under `and` are connected with a conjunction (and). + +Please note that these expressions are limited. You can build complex filtering, but full logical +expressions are not supported. + +The following include matches configuration reads all `systemd` syslog entries: + +["source","yaml",subs="attributes"] +---- +include_matches.and: +- match: + - "journald.process.name=systemd" + - "systemd.transport=syslog" +---- + To reference fields, use one of the following: * The field name used by the systemd journal. For example, diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 912a8f9bcb62..87a50f91a084 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -973,10 +973,21 @@ filebeat.inputs: #id: service-foo # You may wish to have separate inputs for each service. You can use - # include_matches to specify a list of filter expressions that are + # include_matches.or to specify a list of filter expressions that are # applied as a logical OR. You may specify filter - #include_matches: - #- _SYSTEMD_UNIT=foo.service + #include_matches.or: + #- equals: + #- _SYSTEMD_UNIT=foo.service + + # List of syslog identifiers + #syslog_identifiers: ["audit"] + + # Collect events from the service and messages about the service, + # including coredumps. + #units: ["docker.service"] + + # The list of transports (_TRANSPORT field of journald entries) + #transports: ["audit"] # Parsers are also supported, here is an example of the multiline # parser. diff --git a/filebeat/input/journald/config.go b/filebeat/input/journald/config.go index cb3b32e14c97..4e1c0b66da4d 100644 --- a/filebeat/input/journald/config.go +++ b/filebeat/input/journald/config.go @@ -48,7 +48,16 @@ type config struct { CursorSeekFallback journalread.SeekMode `config:"cursor_seek_fallback"` // Matches store the key value pairs to match entries. - Matches []journalfield.Matcher `config:"include_matches"` + Matches journalfield.IncludeMatches `config:"include_matches"` + + // Units stores the units to monitor. + Units []string `config:"units"` + + // Transports stores the list of transports to include in the messages. + Transports []string `config:"transports"` + + // Identifiers stores the syslog identifiers to watch. + Identifiers []string `config:"syslog_identifiers"` // SaveRemoteHostname defines if the original source of the entry needs to be saved. SaveRemoteHostname bool `config:"save_remote_hostname"` diff --git a/filebeat/input/journald/input.go b/filebeat/input/journald/input.go index e9e2f0b40c48..41b6c649f90d 100644 --- a/filebeat/input/journald/input.go +++ b/filebeat/input/journald/input.go @@ -43,7 +43,10 @@ type journald struct { MaxBackoff time.Duration Seek journalread.SeekMode CursorSeekFallback journalread.SeekMode - Matches []journalfield.Matcher + Matches journalfield.IncludeMatches + Units []string + Transports []string + Identifiers []string SaveRemoteHostname bool Parsers parser.Config } @@ -105,6 +108,9 @@ func configure(cfg *common.Config) ([]cursor.Source, cursor.Input, error) { Seek: config.Seek, CursorSeekFallback: config.CursorSeekFallback, Matches: config.Matches, + Units: config.Units, + Transports: config.Transports, + Identifiers: config.Identifiers, SaveRemoteHostname: config.SaveRemoteHostname, Parsers: config.Parsers, }, nil @@ -156,7 +162,8 @@ func (inp *journald) Run( func (inp *journald) open(log *logp.Logger, canceler input.Canceler, src cursor.Source) (*journalread.Reader, error) { backoff := backoff.NewExpBackoff(canceler.Done(), inp.Backoff, inp.MaxBackoff) - reader, err := journalread.Open(log, src.Name(), backoff, withFilters(inp.Matches)) + reader, err := journalread.Open(log, src.Name(), backoff, + withFilters(inp.Matches), withUnits(inp.Units), withTransports(inp.Transports), withSyslogIdentifiers(inp.Identifiers)) if err != nil { return nil, sderr.Wrap(err, "failed to create reader for %{path} journal", src.Name()) } @@ -184,9 +191,27 @@ func initCheckpoint(log *logp.Logger, c cursor.Cursor) checkpoint { return cp } -func withFilters(filters []journalfield.Matcher) func(*sdjournal.Journal) error { +func withFilters(filters journalfield.IncludeMatches) func(*sdjournal.Journal) error { return func(j *sdjournal.Journal) error { - return journalfield.ApplyMatchersOr(j, filters) + return journalfield.ApplyIncludeMatches(j, filters) + } +} + +func withUnits(units []string) func(*sdjournal.Journal) error { + return func(j *sdjournal.Journal) error { + return journalfield.ApplyUnitMatchers(j, units) + } +} + +func withTransports(transports []string) func(*sdjournal.Journal) error { + return func(j *sdjournal.Journal) error { + return journalfield.ApplyTransportMatcher(j, transports) + } +} + +func withSyslogIdentifiers(identifiers []string) func(*sdjournal.Journal) error { + return func(j *sdjournal.Journal) error { + return journalfield.ApplySyslogIdentifierMatcher(j, identifiers) } } diff --git a/filebeat/input/journald/input_filtering_test.go b/filebeat/input/journald/input_filtering_test.go new file mode 100644 index 000000000000..75718b3e5861 --- /dev/null +++ b/filebeat/input/journald/input_filtering_test.go @@ -0,0 +1,219 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build linux && cgo && withjournald +// +build linux,cgo,withjournald + +package journald + +import ( + "context" + "path" + "testing" + + "github.com/elastic/beats/v7/libbeat/common" +) + +func TestInputSyslogIdentifier(t *testing.T) { + tests := map[string]struct { + identifiers []string + expectedMessages []string + }{ + "one identifier": { + identifiers: []string{"sudo"}, + expectedMessages: []string{ + "pam_unix(sudo:session): session closed for user root", + }, + }, + "two identifiers": { + identifiers: []string{"sudo", "systemd"}, + expectedMessages: []string{ + "pam_unix(sudo:session): session closed for user root", + "Started Outputs some log lines.", + }, + }, + } + + for name, testCase := range tests { + t.Run(name, func(t *testing.T) { + env := newInputTestingEnvironment(t) + inp := env.mustCreateInput(common.MapStr{ + "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, + "syslog_identifiers": testCase.identifiers, + }) + + ctx, cancelInput := context.WithCancel(context.Background()) + env.startInput(ctx, inp) + defer cancelInput() + + env.waitUntilEventCount(len(testCase.expectedMessages)) + + for idx, event := range env.pipeline.clients[0].GetEvents() { + if got, expected := event.Fields["message"], testCase.expectedMessages[idx]; got != expected { + t.Fatalf("expecting event message %q, got %q", expected, got) + } + } + }) + } +} + +func TestInputUnits(t *testing.T) { + tests := map[string]struct { + units []string + kernel bool + expectedMessages []string + }{ + "one unit": { + units: []string{"session-1.scope"}, + kernel: true, + expectedMessages: []string{ + "pam_unix(sudo:session): session closed for user root", + }, + }, + "one unit with kernel": { + units: []string{"session-1.scope"}, + expectedMessages: []string{ + "pam_unix(sudo:session): session closed for user root", + }, + }, + "two units, all messages": { + units: []string{"session-1.scope", "user@1000.service"}, + expectedMessages: []string{ + "pam_unix(sudo:session): session closed for user root", + "Started Outputs some log lines.", + "1st line", + "2nd line", + "3rd line", + "4th line", + "5th line", + "6th line", + }, + }, + } + + for name, testCase := range tests { + t.Run(name, func(t *testing.T) { + env := newInputTestingEnvironment(t) + inp := env.mustCreateInput(common.MapStr{ + "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, + "units": testCase.units, + "kernel": testCase.kernel, + }) + + ctx, cancelInput := context.WithCancel(context.Background()) + env.startInput(ctx, inp) + defer cancelInput() + + env.waitUntilEventCount(len(testCase.expectedMessages)) + + for idx, event := range env.pipeline.clients[0].GetEvents() { + if got, expected := event.Fields["message"], testCase.expectedMessages[idx]; got != expected { + t.Fatalf("expecting event message %q, got %q", expected, got) + } + } + }) + } +} + +func TestInputIncludeMatches(t *testing.T) { + tests := map[string]struct { + includeMatches map[string]interface{} + expectedMessages []string + }{ + "single match condition": { + includeMatches: map[string]interface{}{ + "match": []string{ + "syslog.facility=3", + }, + }, + expectedMessages: []string{ + "Started Outputs some log lines.", + "1st line", + "2nd line", + "3rd line", + "4th line", + "5th line", + "6th line", + }, + }, + "multiple match condition": { + includeMatches: map[string]interface{}{ + "match": []string{ + "journald.process.name=systemd", + "syslog.facility=3", + }, + }, + expectedMessages: []string{ + "Started Outputs some log lines.", + }, + }, + "and condition": { + includeMatches: map[string]interface{}{ + "and": []map[string]interface{}{ + map[string]interface{}{ + "match": []string{ + "syslog.facility=3", + "message=6th line", + }, + }, + }, + }, + expectedMessages: []string{ + "6th line", + }, + }, + "or condition": { + includeMatches: map[string]interface{}{ + "or": []map[string]interface{}{ + map[string]interface{}{ + "match": []string{ + "message=5th line", + "message=6th line", + }, + }, + }, + }, + expectedMessages: []string{ + "5th line", + "6th line", + }, + }, + } + + for name, testCase := range tests { + t.Run(name, func(t *testing.T) { + env := newInputTestingEnvironment(t) + inp := env.mustCreateInput(common.MapStr{ + "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, + "include_matches": testCase.includeMatches, + }) + + ctx, cancelInput := context.WithCancel(context.Background()) + env.startInput(ctx, inp) + defer cancelInput() + + env.waitUntilEventCount(len(testCase.expectedMessages)) + + for idx, event := range env.pipeline.clients[0].GetEvents() { + if got, expected := event.Fields["message"], testCase.expectedMessages[idx]; got != expected { + t.Fatalf("expecting event message %q, got %q", expected, got) + } + } + }) + } + +} diff --git a/filebeat/input/journald/input_parsers_test.go b/filebeat/input/journald/input_parsers_test.go index 6aadb031cd2c..3c6d1ad5780e 100644 --- a/filebeat/input/journald/input_parsers_test.go +++ b/filebeat/input/journald/input_parsers_test.go @@ -36,8 +36,8 @@ func TestInputParsers(t *testing.T) { env := newInputTestingEnvironment(t) inp := env.mustCreateInput(common.MapStr{ - "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, - "include_matches": []string{"_SYSTEMD_USER_UNIT=log-service.service"}, + "paths": []string{path.Join("testdata", "input-multiline-parser.journal")}, + "include_matches.match": []string{"_SYSTEMD_USER_UNIT=log-service.service"}, "parsers": []common.MapStr{ { "multiline": common.MapStr{ diff --git a/filebeat/input/journald/pkg/journalfield/default.go b/filebeat/input/journald/pkg/journalfield/default.go index 7573eb4156df..a72df0ce5c0b 100644 --- a/filebeat/input/journald/pkg/journalfield/default.go +++ b/filebeat/input/journald/pkg/journalfield/default.go @@ -46,6 +46,7 @@ var journaldEventFields = FieldConversion{ "_UDEV_DEVLINK": text("journald.kernel.device_symlinks"), "_UDEV_DEVNODE": text("journald.kernel.device_node_path"), "_UDEV_SYSNAME": text("journald.kernel.device_name"), + "UNIT": text("journald.unit"), sdjournal.SD_JOURNAL_FIELD_AUDIT_LOGINUID: integer("journald.audit.login_uid"), sdjournal.SD_JOURNAL_FIELD_AUDIT_SESSION: text("journald.audit.session"), sdjournal.SD_JOURNAL_FIELD_BOOT_ID: text("journald.host.boot_id"), @@ -60,6 +61,7 @@ var journaldEventFields = FieldConversion{ sdjournal.SD_JOURNAL_FIELD_HOSTNAME: text("host.hostname"), sdjournal.SD_JOURNAL_FIELD_MACHINE_ID: text("host.id"), sdjournal.SD_JOURNAL_FIELD_MESSAGE: text("message"), + sdjournal.SD_JOURNAL_FIELD_MESSAGE_ID: text("message_id"), sdjournal.SD_JOURNAL_FIELD_PID: integer("journald.pid"), sdjournal.SD_JOURNAL_FIELD_PRIORITY: integer("syslog.priority", "log.syslog.priority"), sdjournal.SD_JOURNAL_FIELD_SYSLOG_FACILITY: integer("syslog.facility", "log.syslog.facility.code"), diff --git a/filebeat/input/journald/pkg/journalfield/matcher.go b/filebeat/input/journald/pkg/journalfield/matcher.go index 0227b2aae832..49d4e98fe1a7 100644 --- a/filebeat/input/journald/pkg/journalfield/matcher.go +++ b/filebeat/input/journald/pkg/journalfield/matcher.go @@ -36,12 +36,26 @@ type MatcherBuilder struct { Conversions map[string]Conversion } +// IncludeMatches stores the advanced matching configuratio +// provided by the user. +type IncludeMatches struct { + Matches []Matcher `config:"match"` + AND []IncludeMatches `config:"and"` + OR []IncludeMatches `config:"or"` +} + type journal interface { AddMatch(string) error AddDisjunction() error + AddConjunction() error } -var defaultBuilder = MatcherBuilder{Conversions: journaldEventFields} +var ( + defaultBuilder = MatcherBuilder{Conversions: journaldEventFields} + coreDumpMsgID = MustBuildMatcher("message_id=fc2e22bc6ee647b6b90729ab34a250b1") // matcher for messages from coredumps + journaldUID = MustBuildMatcher("journald.uid=0") // matcher for messages from root (UID 0) + journaldPID = MustBuildMatcher("journald.pid=1") // matcher for messages from init process (PID 1) +) // Build creates a new Matcher using the configured conversion table. // If no table has been configured the internal default table will be used. @@ -73,6 +87,14 @@ func BuildMatcher(in string) (Matcher, error) { return defaultBuilder.Build(in) } +func MustBuildMatcher(in string) Matcher { + m, err := BuildMatcher(in) + if err != nil { + panic(err) + } + return m +} + // IsValid returns true if the matcher was initialized correctly. func (m Matcher) IsValid() bool { return m.str != "" } @@ -118,3 +140,125 @@ func ApplyMatchersOr(j journal, matchers []Matcher) error { return nil } + +// ApplyUnitMatchers adds unit based filtering to the journal reader. +// Filtering is similar to what systemd does here: +// https://github.com/systemd/systemd/blob/641e2124de6047e6010cd2925ea22fba29b25309/src/shared/logs-show.c#L1409-L1455 +func ApplyUnitMatchers(j journal, units []string) error { + for _, unit := range units { + systemdUnit, err := BuildMatcher("systemd.unit=" + unit) + if err != nil { + return fmt.Errorf("failed to build matcher for _SYSTEMD_UNIT: %+w", err) + } + coredumpUnit, err := BuildMatcher("journald.coredump.unit=" + unit) + if err != nil { + return fmt.Errorf("failed to build matcher for COREDUMP_UNIT: %+w", err) + } + journaldUnit, err := BuildMatcher("journald.unit=" + unit) + if err != nil { + return fmt.Errorf("failed to build matcher for UNIT: %+w", err) + } + journaldObjectUnit, err := BuildMatcher("journald.object.systemd.unit=" + unit) + if err != nil { + return fmt.Errorf("failed to build matcher for OBJECT_SYSTEMD_UNIT: %+w", err) + } + + matchers := [][]Matcher{ + // match for the messages of the service + []Matcher{ + systemdUnit, + }, + // match for the coredumps of the service + []Matcher{ + coreDumpMsgID, + journaldUID, + coredumpUnit, + }, + // match for messages about the service with PID value of 1 + []Matcher{ + journaldPID, + journaldUnit, + }, + // match for messages about the service from authorized daemons + []Matcher{ + journaldUID, + journaldObjectUnit, + }, + } + if strings.HasSuffix(unit, ".slice") { + if sliceMatcher, err := BuildMatcher("systemd.slice=" + unit); err != nil { + matchers = append(matchers, []Matcher{sliceMatcher}) + } + } + + for _, m := range matchers { + if err := ApplyMatchersOr(j, m); err != nil { + return fmt.Errorf("error while setting up unit matcher for %s: %+v", unit, err) + } + } + + } + + return nil + +} + +// ApplyTransportMatcher adds matchers for the configured transports. +func ApplyTransportMatcher(j journal, transports []string) error { + if len(transports) == 0 { + return nil + } + + transportMatchers := make([]Matcher, len(transports)) + for i, transport := range transports { + transportMatcher, err := BuildMatcher("_TRANSPORT=" + transport) + if err != nil { + return err + } + transportMatchers[i] = transportMatcher + } + if err := ApplyMatchersOr(j, transportMatchers); err != nil { + return fmt.Errorf("error while adding %+v transport to matchers: %+v", transports, err) + } + return nil + +} + +// ApplySyslogIdentifierMatcher adds syslog identifier filtering to the journal reader. +func ApplySyslogIdentifierMatcher(j journal, identifiers []string) error { + identifierMatchers := make([]Matcher, len(identifiers)) + for i, identifier := range identifiers { + identifierMatchers[i] = MustBuildMatcher("syslog.identifier=" + identifier) + } + + return ApplyMatchersOr(j, identifierMatchers) +} + +// ApplyIncludeMatches adds advanced filtering to journals. +func ApplyIncludeMatches(j journal, m IncludeMatches) error { + for _, or := range m.OR { + if err := ApplyIncludeMatches(j, or); err != nil { + return err + } + if err := j.AddDisjunction(); err != nil { + return fmt.Errorf("error adding disjunction to journal: %v", err) + } + } + + for _, and := range m.AND { + if err := ApplyIncludeMatches(j, and); err != nil { + return err + } + if err := j.AddConjunction(); err != nil { + return fmt.Errorf("error adding conjunction to journal: %v", err) + } + } + + for _, match := range m.Matches { + if err := match.Apply(j); err != nil { + return fmt.Errorf("failed to apply %s expression: %+v", match.str, err) + } + } + + return nil +} diff --git a/filebeat/input/journald/pkg/journalfield/matcher_test.go b/filebeat/input/journald/pkg/journalfield/matcher_test.go index 82832f3297a7..e1e896a7bf01 100644 --- a/filebeat/input/journald/pkg/journalfield/matcher_test.go +++ b/filebeat/input/journald/pkg/journalfield/matcher_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/coreos/go-systemd/v22/sdjournal" + "github.com/stretchr/testify/require" ) func TestApplyMatchersOr(t *testing.T) { @@ -79,3 +80,25 @@ func TestApplyMatchersOr(t *testing.T) { }) } } + +func TestApplySyslogIdentifier(t *testing.T) { + journal, err := sdjournal.NewJournal() + if err != nil { + t.Fatalf("error while creating test journal: %v", err) + } + defer journal.Close() + + err = ApplySyslogIdentifierMatcher(journal, []string{"audit"}) + require.NoError(t, err) +} + +func TestApplyUnit(t *testing.T) { + journal, err := sdjournal.NewJournal() + if err != nil { + t.Fatalf("error while creating test journal: %v", err) + } + defer journal.Close() + + err = ApplyUnitMatchers(journal, []string{"docker.service"}) + require.NoError(t, err) +} diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index e65e6990c620..cabffe369c94 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -3038,10 +3038,21 @@ filebeat.inputs: #id: service-foo # You may wish to have separate inputs for each service. You can use - # include_matches to specify a list of filter expressions that are + # include_matches.or to specify a list of filter expressions that are # applied as a logical OR. You may specify filter - #include_matches: - #- _SYSTEMD_UNIT=foo.service + #include_matches.or: + #- equals: + #- _SYSTEMD_UNIT=foo.service + + # List of syslog identifiers + #syslog_identifiers: ["audit"] + + # Collect events from the service and messages about the service, + # including coredumps. + #units: ["docker.service"] + + # The list of transports (_TRANSPORT field of journald entries) + #transports: ["audit"] # Parsers are also supported, here is an example of the multiline # parser. From 2b8d076628f8cc11beb7401a071f0437def38d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 4 Jan 2022 17:54:52 +0100 Subject: [PATCH 140/172] Add warning about removing Functionbeat (#29295) --- x-pack/functionbeat/function/beater/functionbeat.go | 3 +++ x-pack/functionbeat/manager/beater/functionbeat.go | 2 ++ x-pack/functionbeat/manager/cmd/root.go | 3 +++ 3 files changed, 8 insertions(+) diff --git a/x-pack/functionbeat/function/beater/functionbeat.go b/x-pack/functionbeat/function/beater/functionbeat.go index 9118fe771653..0906a1433e3c 100644 --- a/x-pack/functionbeat/function/beater/functionbeat.go +++ b/x-pack/functionbeat/function/beater/functionbeat.go @@ -56,6 +56,7 @@ type Functionbeat struct { // New creates an instance of functionbeat. func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { + c := &config.DefaultConfig if err := cfg.Unpack(c); err != nil { return nil, fmt.Errorf("error reading config file: %+v", err) @@ -84,6 +85,8 @@ func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { func (bt *Functionbeat) Run(b *beat.Beat) error { defer bt.cancel() + bt.log.Warn("Functionbeat is going to be removed in 8.1") + outputName := b.Config.Output.Name() if !isOutputSupported(outputName) { return fmt.Errorf("unsupported output type: %s; supported ones: %+v", outputName, supportedOutputs) diff --git a/x-pack/functionbeat/manager/beater/functionbeat.go b/x-pack/functionbeat/manager/beater/functionbeat.go index 855cf16c02a9..2178228c5770 100644 --- a/x-pack/functionbeat/manager/beater/functionbeat.go +++ b/x-pack/functionbeat/manager/beater/functionbeat.go @@ -51,6 +51,8 @@ func (bt *Functionbeat) Run(b *beat.Beat) error { bt.log.Info("Functionbeat is running") defer bt.log.Info("Functionbeat stopped running") + bt.log.Warn("Functionbeat is going to be removed in 8.1") + return nil } diff --git a/x-pack/functionbeat/manager/cmd/root.go b/x-pack/functionbeat/manager/cmd/root.go index ca9e8bda81aa..0d63eb391a0b 100644 --- a/x-pack/functionbeat/manager/cmd/root.go +++ b/x-pack/functionbeat/manager/cmd/root.go @@ -5,6 +5,7 @@ package cmd import ( + "fmt" "os" "github.com/spf13/cobra" @@ -31,6 +32,8 @@ func init() { RootCmd.RemoveCommand(RootCmd.RunCmd) RootCmd.Run = func(_ *cobra.Command, _ []string) { + fmt.Println("Functionbeat is going to be removed in 8.1") + RootCmd.Usage() os.Exit(1) } From d37cdbdcddf3154b96702caaaaba11e8610461e5 Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Tue, 4 Jan 2022 18:12:00 +0100 Subject: [PATCH 141/172] Update Beats docs to include ES CA fingerprint (#29632) Update Beats ES connection documentation to include ES CA fingerprint information. --- .../docs/tab-widgets/set-connection.asciidoc | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/libbeat/docs/tab-widgets/set-connection.asciidoc b/libbeat/docs/tab-widgets/set-connection.asciidoc index 571e9cec5702..3d8c90147326 100644 --- a/libbeat/docs/tab-widgets/set-connection.asciidoc +++ b/libbeat/docs/tab-widgets/set-connection.asciidoc @@ -29,11 +29,22 @@ set the username and password of a user who is authorized to set up ["source","yaml",subs="attributes"] ---- output.elasticsearch: - hosts: ["myEShost:9200"] + hosts: ["https://myEShost:9200"] username: "{beatname_lc}_internal" password: "{pwd}" <1> + ssl: + enabled: true + ca_trusted_fingerprint: "b9a10bbe64ee9826abeda6546fc988c8bf798b41957c33d05db736716513dc9c" <2> ---- -<1> This examples shows a hard-coded password, but you should store sensitive +<1> This example shows a hard-coded password, but you should store sensitive +values +ifndef::serverless[] +in the {beatname_url}/keystore.html[secrets keystore]. +endif::[] +ifdef::serverless[] +in environment variables. +endif::[] +<2> This example shows a hard-coded fingerprint, but you should store sensitive values ifndef::serverless[] in the {beatname_url}/keystore.html[secrets keystore]. @@ -41,6 +52,16 @@ endif::[] ifdef::serverless[] in environment variables. endif::[] +The fingerprint is a HEX encoded SHA-256 of a CA certificate, +when you start {es} for the first time, security features such as +network encryption (TLS) for {es} are enabled by default. If you are +using the self-signed certificate generated by {es} when it is started +for the first time, you will need to add its fingerprint here. The +fingerprint is printed on {es} start up logs, or you can refer to {ref-80}/configuring-stack-security.html#_connect_clients_to_elasticsearch_5[connect clients to {es} +documentation] for other options on retrieving it. If you are +providing your own SSL certificate to {es} refer to +{beatname_url}/configuration-ssl.html#ssl-client-config[{beatname_uc} +documentation on how to setup SSL]. . If you plan to use our pre-built {kib} dashboards, configure the {kib} endpoint. Skip this step if {kib} is running on the same host as {es}. From a3c22086c5a493e8a5208805837b17a471d4f0ec Mon Sep 17 00:00:00 2001 From: Lee E Hinman <57081003+leehinman@users.noreply.github.com> Date: Tue, 4 Jan 2022 09:18:54 -0800 Subject: [PATCH 142/172] [Winlogbeat] Switch to ingest node processing (#29435) What does this PR do? Switches to ingest node processing instead of local javascript processing for modules. Why is it important? For Agent we are using ingest node processing. This keeps the Winlogbeat and Agent processing in sync and allows bug fixes to be shared between them. Changes - remove JS processing - remove testing of JS processing - add ingest node pipelines from agent - use routing pipeline to direct to correct module pipeline - embed pipelines in winlogbeat executable - add `export pipeline` command - add loading of pipelines to setup command - add loading of pipelines to every ES connection if the pipelines don't exist - exports several functions from filebeat/fileset to avoid code duplication - update docs - update default config - update reference config Closes #29184 --- CHANGELOG.next.asciidoc | 1 + filebeat/fileset/compatibility.go | 2 +- filebeat/fileset/compatibility_test.go | 18 +- filebeat/fileset/fileset.go | 41 +- filebeat/fileset/modules_integration_test.go | 6 +- filebeat/fileset/pipelines.go | 10 +- libbeat/docs/command-reference.asciidoc | 23 + winlogbeat/_meta/config/header.yml.tmpl | 5 + winlogbeat/beater/winlogbeat.go | 28 +- winlogbeat/config/config.go | 9 +- winlogbeat/docs/index.asciidoc | 1 + winlogbeat/docs/winlogbeat-options.asciidoc | 9 + winlogbeat/module/pipeline.go | 212 ++ winlogbeat/winlogbeat.reference.yml | 5 + .../config/output-elasticsearch.yml.tmpl | 15 + .../config/winlogbeat.event_logs.yml.tmpl | 41 - x-pack/winlogbeat/cmd/export.go | 60 + x-pack/winlogbeat/cmd/root.go | 3 + x-pack/winlogbeat/module/pipeline.go | 19 + .../config/winlogbeat-powershell.js | 690 ---- .../module/powershell/ingest/powershell.yml | 433 +++ .../ingest/powershell_operational.yml | 492 +++ .../test/powershell_windows_test.go | 26 - .../module/routing/ingest/routing.yml | 20 + .../security/config/winlogbeat-security.js | 2828 -------------- .../module/security/ingest/security.yml | 3364 +++++++++++++++++ .../security/test/security_windows_test.go | 26 - .../module/sysmon/config/winlogbeat-sysmon.js | 1802 --------- .../module/sysmon/ingest/sysmon.yml | 1253 ++++++ .../module/sysmon/test/sysmon_windows_test.go | 34 - x-pack/winlogbeat/winlogbeat.reference.yml | 46 +- x-pack/winlogbeat/winlogbeat.yml | 44 +- 32 files changed, 5995 insertions(+), 5571 deletions(-) create mode 100644 winlogbeat/module/pipeline.go create mode 100644 x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl create mode 100644 x-pack/winlogbeat/cmd/export.go create mode 100644 x-pack/winlogbeat/module/pipeline.go delete mode 100644 x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js create mode 100644 x-pack/winlogbeat/module/powershell/ingest/powershell.yml create mode 100644 x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml delete mode 100644 x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go create mode 100644 x-pack/winlogbeat/module/routing/ingest/routing.yml delete mode 100644 x-pack/winlogbeat/module/security/config/winlogbeat-security.js create mode 100644 x-pack/winlogbeat/module/security/ingest/security.yml delete mode 100644 x-pack/winlogbeat/module/security/test/security_windows_test.go delete mode 100644 x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js create mode 100644 x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml delete mode 100644 x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1c73e56a5ecf..439d12787327 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -73,6 +73,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Improve ECS field mappings in Sysmon module. `file.name`, `file.directory`, and `file.extension` are now populated. {issue}18364[18364] - Improve ECS field mappings in Sysmon module. `rule.name` is populated for all events when present. {issue}18364[18364] - Remove top level `hash` property from sysmon events {pull}20653[20653] +- Move module processing from local Javascript processor to ingest node {issue}29184[29184] {pull}29435[29435] *Functionbeat* diff --git a/filebeat/fileset/compatibility.go b/filebeat/fileset/compatibility.go index 8a38e6158ccc..63631e86b88b 100644 --- a/filebeat/fileset/compatibility.go +++ b/filebeat/fileset/compatibility.go @@ -211,7 +211,7 @@ func (p *Processor) String() string { // adaptPipelineForCompatibility iterates over all processors in the pipeline // and adapts them for version of Elasticsearch used. Adapt can mean modifying // processor options or removing the processor. -func adaptPipelineForCompatibility(esVersion common.Version, pipelineID string, content map[string]interface{}, log *logp.Logger) (err error) { +func AdaptPipelineForCompatibility(esVersion common.Version, pipelineID string, content map[string]interface{}, log *logp.Logger) (err error) { log = log.With("pipeline_id", pipelineID) // Adapt the main processors in the pipeline. if err = adaptProcessorsForCompatibility(esVersion, content, "processors", false, log); err != nil { diff --git a/filebeat/fileset/compatibility_test.go b/filebeat/fileset/compatibility_test.go index 82e584b046fe..79b10eb263df 100644 --- a/filebeat/fileset/compatibility_test.go +++ b/filebeat/fileset/compatibility_test.go @@ -128,7 +128,7 @@ func TestAdaptPipelineForCompatibility(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -305,7 +305,7 @@ func TestReplaceSetIgnoreEmptyValue(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -507,7 +507,7 @@ func TestReplaceAppendAllowDuplicates(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -632,7 +632,7 @@ func TestRemoveURIPartsProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -767,7 +767,7 @@ func TestRemoveNetworkDirectionProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -950,7 +950,7 @@ func TestReplaceConvertIPWithGrok(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1070,7 +1070,7 @@ func TestRemoveRegisteredDomainProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1331,7 +1331,7 @@ func TestReplaceAlternativeFlowProcessors(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1446,7 +1446,7 @@ func TestRemoveDescription(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { diff --git a/filebeat/fileset/fileset.go b/filebeat/fileset/fileset.go index 09a2738bb172..dae801738f90 100644 --- a/filebeat/fileset/fileset.go +++ b/filebeat/fileset/fileset.go @@ -237,13 +237,13 @@ func (fs *Fileset) turnOffElasticsearchVars(vars map[string]interface{}, esVersi func resolveVariable(vars map[string]interface{}, value interface{}) (interface{}, error) { switch v := value.(type) { case string: - return applyTemplate(vars, v, false) + return ApplyTemplate(vars, v, false) case []interface{}: transformed := []interface{}{} for _, val := range v { s, ok := val.(string) if ok { - transf, err := applyTemplate(vars, s, false) + transf, err := ApplyTemplate(vars, s, false) if err != nil { return nil, fmt.Errorf("array: %v", err) } @@ -257,10 +257,10 @@ func resolveVariable(vars map[string]interface{}, value interface{}) (interface{ return value, nil } -// applyTemplate applies a Golang text/template. If specialDelims is set to true, +// ApplyTemplate applies a Golang text/template. If specialDelims is set to true, // the delimiters are set to `{<` and `>}` instead of `{{` and `}}`. These are easier to use // in pipeline definitions. -func applyTemplate(vars map[string]interface{}, templateString string, specialDelims bool) (string, error) { +func ApplyTemplate(vars map[string]interface{}, templateString string, specialDelims bool) (string, error) { tpl := template.New("text").Option("missingkey=error") if specialDelims { tpl = tpl.Delims("{<", ">}") @@ -307,7 +307,7 @@ func getTemplateFunctions(vars map[string]interface{}) (template.FuncMap, error) return buf.String(), err }, "IngestPipeline": func(shortID string) string { - return formatPipelineID( + return FormatPipelineID( builtinVars["prefix"].(string), builtinVars["module"].(string), builtinVars["fileset"].(string), @@ -343,7 +343,7 @@ func (fs *Fileset) getBuiltinVars(info beat.Info) (map[string]interface{}, error } func (fs *Fileset) getInputConfig() (*common.Config, error) { - path, err := applyTemplate(fs.vars, fs.manifest.Input, false) + path, err := ApplyTemplate(fs.vars, fs.manifest.Input, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the input path: %v", err) } @@ -352,7 +352,7 @@ func (fs *Fileset) getInputConfig() (*common.Config, error) { return nil, fmt.Errorf("Error reading input file %s: %v", path, err) } - yaml, err := applyTemplate(fs.vars, string(contents), false) + yaml, err := ApplyTemplate(fs.vars, string(contents), false) if err != nil { return nil, fmt.Errorf("Error interpreting the template of the input: %v", err) } @@ -409,12 +409,12 @@ func (fs *Fileset) getInputConfig() (*common.Config, error) { func (fs *Fileset) getPipelineIDs(info beat.Info) ([]string, error) { var pipelineIDs []string for _, ingestPipeline := range fs.manifest.IngestPipeline { - path, err := applyTemplate(fs.vars, ingestPipeline, false) + path, err := ApplyTemplate(fs.vars, ingestPipeline, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the ingest pipeline path: %v", err) } - pipelineIDs = append(pipelineIDs, formatPipelineID(info.IndexPrefix, fs.mcfg.Module, fs.name, path, info.Version)) + pipelineIDs = append(pipelineIDs, FormatPipelineID(info.IndexPrefix, fs.mcfg.Module, fs.name, path, info.Version)) } return pipelineIDs, nil @@ -428,7 +428,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, } for idx, ingestPipeline := range fs.manifest.IngestPipeline { - path, err := applyTemplate(fs.vars, ingestPipeline, false) + path, err := ApplyTemplate(fs.vars, ingestPipeline, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the ingest pipeline path: %v", err) } @@ -438,7 +438,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, return nil, fmt.Errorf("Error reading pipeline file %s: %v", path, err) } - encodedString, err := applyTemplate(vars, string(strContents), true) + encodedString, err := ApplyTemplate(vars, string(strContents), true) if err != nil { return nil, fmt.Errorf("Error interpreting the template of the ingest pipeline: %v", err) } @@ -453,7 +453,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, if err = yaml.Unmarshal([]byte(encodedString), &content); err != nil { return nil, fmt.Errorf("Error YAML decoding the pipeline file: %s: %v", path, err) } - newContent, err := fixYAMLMaps(content) + newContent, err := FixYAMLMaps(content) if err != nil { return nil, fmt.Errorf("Failed to sanitize the YAML pipeline file: %s: %v", path, err) } @@ -474,11 +474,11 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, return pipelines, nil } -// This function recursively converts maps with interface{} keys, as returned by +// FixYAMLMaps recursively converts maps with interface{} keys, as returned by // yaml.Unmarshal, to maps of string keys, as expected by the json encoder // that will be used when delivering the pipeline to Elasticsearch. // Will return an error when something other than a string is used as a key. -func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { +func FixYAMLMaps(elem interface{}) (_ interface{}, err error) { switch v := elem.(type) { case map[interface{}]interface{}: result := make(map[string]interface{}, len(v)) @@ -487,20 +487,20 @@ func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { if !ok { return nil, fmt.Errorf("key '%v' is not string but %T", key, key) } - if result[keyS], err = fixYAMLMaps(value); err != nil { + if result[keyS], err = FixYAMLMaps(value); err != nil { return nil, err } } return result, nil case map[string]interface{}: for key, value := range v { - if v[key], err = fixYAMLMaps(value); err != nil { + if v[key], err = FixYAMLMaps(value); err != nil { return nil, err } } case []interface{}: for idx, value := range v { - if v[idx], err = fixYAMLMaps(value); err != nil { + if v[idx], err = FixYAMLMaps(value); err != nil { return nil, err } } @@ -508,8 +508,11 @@ func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { return elem, nil } -// formatPipelineID generates the ID to be used for the pipeline ID in Elasticsearch -func formatPipelineID(prefix, module, fileset, path, version string) string { +// FormatPipelineID generates the ID to be used for the pipeline ID in Elasticsearch +func FormatPipelineID(prefix, module, fileset, path, version string) string { + if module == "" && fileset == "" { + return fmt.Sprintf("%s-%s-%s", prefix, version, removeExt(filepath.Base(path))) + } return fmt.Sprintf("%s-%s-%s-%s-%s", prefix, version, module, fileset, removeExt(filepath.Base(path))) } diff --git a/filebeat/fileset/modules_integration_test.go b/filebeat/fileset/modules_integration_test.go index 6b9e86cac84b..f17be7c8d73f 100644 --- a/filebeat/fileset/modules_integration_test.go +++ b/filebeat/fileset/modules_integration_test.go @@ -62,7 +62,7 @@ func TestLoadPipeline(t *testing.T) { } log := logp.NewLogger(logName) - err := loadPipeline(client, "my-pipeline-id", content, false, log) + err := LoadPipeline(client, "my-pipeline-id", content, false, log) require.NoError(t, err) status, _, err := client.Request("GET", "/_ingest/pipeline/my-pipeline-id", "", nil, nil) @@ -71,12 +71,12 @@ func TestLoadPipeline(t *testing.T) { // loading again shouldn't actually update the pipeline content["description"] = "describe pipeline 2" - err = loadPipeline(client, "my-pipeline-id", content, false, log) + err = LoadPipeline(client, "my-pipeline-id", content, false, log) require.NoError(t, err) checkUploadedPipeline(t, client, "describe pipeline") // loading again updates the pipeline - err = loadPipeline(client, "my-pipeline-id", content, true, log) + err = LoadPipeline(client, "my-pipeline-id", content, true, log) require.NoError(t, err) checkUploadedPipeline(t, client, "describe pipeline 2") } diff --git a/filebeat/fileset/pipelines.go b/filebeat/fileset/pipelines.go index a3ce0b3de423..c93825ad09e4 100644 --- a/filebeat/fileset/pipelines.go +++ b/filebeat/fileset/pipelines.go @@ -86,7 +86,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool var pipelineIDsLoaded []string for _, pipeline := range pipelines { - err = loadPipeline(esClient, pipeline.id, pipeline.contents, overwrite, reg.log.With("pipeline", pipeline.id)) + err = LoadPipeline(esClient, pipeline.id, pipeline.contents, overwrite, reg.log.With("pipeline", pipeline.id)) if err != nil { err = fmt.Errorf("error loading pipeline for fileset %s/%s: %v", module, name, err) break @@ -100,7 +100,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool // error, validate all pipelines before loading any of them. This requires https://github.com/elastic/elasticsearch/issues/35495. errs := multierror.Errors{err} for _, pipelineID := range pipelineIDsLoaded { - err = deletePipeline(esClient, pipelineID) + err = DeletePipeline(esClient, pipelineID) if err != nil { errs = append(errs, err) } @@ -112,7 +112,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool return nil } -func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string]interface{}, overwrite bool, log *logp.Logger) error { +func LoadPipeline(esClient PipelineLoader, pipelineID string, content map[string]interface{}, overwrite bool, log *logp.Logger) error { path := makeIngestPipelinePath(pipelineID) if !overwrite { status, _, _ := esClient.Request("GET", path, "", nil, nil) @@ -122,7 +122,7 @@ func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string } } - if err := adaptPipelineForCompatibility(esClient.GetVersion(), pipelineID, content, log); err != nil { + if err := AdaptPipelineForCompatibility(esClient.GetVersion(), pipelineID, content, log); err != nil { return fmt.Errorf("failed to adapt pipeline with backwards compatibility changes: %w", err) } @@ -134,7 +134,7 @@ func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string return nil } -func deletePipeline(esClient PipelineLoader, pipelineID string) error { +func DeletePipeline(esClient PipelineLoader, pipelineID string) error { path := makeIngestPipelinePath(pipelineID) _, _, err := esClient.Request("DELETE", path, "", nil, nil) return err diff --git a/libbeat/docs/command-reference.asciidoc b/libbeat/docs/command-reference.asciidoc index d761c7f4b169..eddee911d7fa 100644 --- a/libbeat/docs/command-reference.asciidoc +++ b/libbeat/docs/command-reference.asciidoc @@ -19,6 +19,7 @@ :apikey-command-short-desc: Manage API Keys for communication between APM agents and server. +ifndef::export_pipeline[] ifndef::serverless[] ifndef::no_dashboards[] :export-command-short-desc: Exports the configuration, index template, ILM policy, or a dashboard to stdout @@ -32,6 +33,11 @@ endif::serverless[] ifdef::serverless[] :export-command-short-desc: Exports the configuration, index template, or {cloudformation-ref} template to stdout endif::serverless[] +endif::export_pipeline[] + +ifdef::export_pipeline[] +:export-command-short-desc: Exports the configuration, index template, pipeline, or ILM policy to stdout +endif::export_pipeline[] :help-command-short-desc: Shows help for any command :keystore-command-short-desc: Manages the <> @@ -262,6 +268,7 @@ endif::[] [[export-command]] ==== `export` command +ifndef::export_pipeline[] ifndef::serverless[] ifndef::no_dashboards[] {export-command-short-desc}. You can use this @@ -281,6 +288,14 @@ ifdef::serverless[] command to quickly view your configuration, see the contents of the index template and the ILM policy, or export an CloudFormation template. endif::serverless[] +endif::export_pipeline[] + +ifdef::export_pipeline[] +{export-command-short-desc}. You can use this +command to quickly view your configuration, see the contents of the index +template and the ILM policy, export a dashboard from {kib}, or export ingest +pipelines. +endif::export_pipeline[] *SYNOPSIS* @@ -336,6 +351,14 @@ ifdef::serverless[] Exports an {cloudformation-ref} template to stdout. endif::serverless[] +ifdef::export_pipeline[] +[[pipeline-subcommand]] +*`pipeline`*:: +Exports the ingest piplines. You must specify the `--es.version` to which +the pipelines should be exported. You can optionally specify `--dir` to control +where the pipelines are written. +endif::export_pipeline[] + *FLAGS* *`--es.version VERSION`*:: diff --git a/winlogbeat/_meta/config/header.yml.tmpl b/winlogbeat/_meta/config/header.yml.tmpl index 7d966b365242..b12d31c47d93 100644 --- a/winlogbeat/_meta/config/header.yml.tmpl +++ b/winlogbeat/_meta/config/header.yml.tmpl @@ -21,6 +21,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + {{end -}} # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of diff --git a/winlogbeat/beater/winlogbeat.go b/winlogbeat/beater/winlogbeat.go index 568bb911539d..ec7ebf90ef6f 100644 --- a/winlogbeat/beater/winlogbeat.go +++ b/winlogbeat/beater/winlogbeat.go @@ -29,14 +29,21 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/outputs/elasticsearch" "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/winlogbeat/module" "github.com/elastic/beats/v7/winlogbeat/checkpoint" "github.com/elastic/beats/v7/winlogbeat/config" "github.com/elastic/beats/v7/winlogbeat/eventlog" ) +const pipelinesWarning = "Winlogbeat is unable to load the ingest pipelines" + + " because the Elasticsearch output is not configured/enabled. If you have" + + " already loaded the ingest pipelines, you can ignore this warning." + // Time the application was started. var startTime = time.Now().UTC() @@ -100,7 +107,14 @@ func (eb *Winlogbeat) init(b *beat.Beat) error { eb.eventLogs = append(eb.eventLogs, logger) } - + b.OverwritePipelinesCallback = func(esConfig *common.Config) error { + overwritePipelines := config.OverwritePipelines + esClient, err := eslegclient.NewConnectedClient(esConfig, "Winlogbeat") + if err != nil { + return err + } + return module.UploadPipelines(b.Info, esClient, overwritePipelines) + } return nil } @@ -125,6 +139,18 @@ func (eb *Winlogbeat) Run(b *beat.Beat) error { return err } + if b.Config.Output.Name() == "elasticsearch" { + callback := func(esClient *eslegclient.Connection) error { + return module.UploadPipelines(b.Info, esClient, eb.config.OverwritePipelines) + } + _, err := elasticsearch.RegisterConnectCallback(callback) + if err != nil { + return err + } + } else { + eb.log.Warn(pipelinesWarning) + } + acker := newEventACKer(eb.checkpoint) persistedState := eb.checkpoint.States() diff --git a/winlogbeat/config/config.go b/winlogbeat/config/config.go index 1b8eab40c0a1..ed8f2195d026 100644 --- a/winlogbeat/config/config.go +++ b/winlogbeat/config/config.go @@ -41,10 +41,11 @@ var ( // WinlogbeatConfig contains all of Winlogbeat configuration data. type WinlogbeatConfig struct { - EventLogs []*common.Config `config:"event_logs"` - RegistryFile string `config:"registry_file"` - RegistryFlush time.Duration `config:"registry_flush"` - ShutdownTimeout time.Duration `config:"shutdown_timeout"` + EventLogs []*common.Config `config:"event_logs"` + RegistryFile string `config:"registry_file"` + RegistryFlush time.Duration `config:"registry_flush"` + ShutdownTimeout time.Duration `config:"shutdown_timeout"` + OverwritePipelines bool `config:"overwrite_pipelines"` } // Validate validates the WinlogbeatConfig data and returns an error describing diff --git a/winlogbeat/docs/index.asciidoc b/winlogbeat/docs/index.asciidoc index d953f0d641c2..97c1023d4c26 100644 --- a/winlogbeat/docs/index.asciidoc +++ b/winlogbeat/docs/index.asciidoc @@ -21,6 +21,7 @@ include::{asciidoc-dir}/../../shared/attributes.asciidoc[] :no_decode_cef_processor: :no_decode_csv_fields_processor: :include_translate_sid_processor: +:export_pipeline: include::{libbeat-dir}/shared-beats-attributes.asciidoc[] diff --git a/winlogbeat/docs/winlogbeat-options.asciidoc b/winlogbeat/docs/winlogbeat-options.asciidoc index 23e63803089b..e703406061da 100644 --- a/winlogbeat/docs/winlogbeat-options.asciidoc +++ b/winlogbeat/docs/winlogbeat-options.asciidoc @@ -514,3 +514,12 @@ There are a few notable differences in the events: `winlog.event_data`. * Setting `include_xml: true` has no effect. + +[float] +==== `overwrite_pipelines` + +By default Ingest pipelines are not updated if a pipeline with the same ID +already exists. If this option is enabled Winlogbeat overwrites pipelines +every time a new Elasticsearch connection is established. + +The default value is `false`. diff --git a/winlogbeat/module/pipeline.go b/winlogbeat/module/pipeline.go new file mode 100644 index 000000000000..c134bd9068b4 --- /dev/null +++ b/winlogbeat/module/pipeline.go @@ -0,0 +1,212 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package module + +import ( + "embed" + "encoding/json" + "errors" + "fmt" + "os" + "path" + "path/filepath" + "strings" + + "github.com/joeshaw/multierror" + "gopkg.in/yaml.v2" + + "github.com/elastic/beats/v7/filebeat/fileset" + "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" + "github.com/elastic/beats/v7/libbeat/logp" +) + +// PipelinesFS is used from the x-pack/winlogbeat code to inject modules. The +// OSS version does not have modules. +var PipelinesFS *embed.FS + +var errNoFS = errors.New("no embedded file system") + +const logName = "pipeline" + +type pipeline struct { + id string + contents map[string]interface{} +} + +// UploadPipelines reads all pipelines embedded in the Winlogbeat executable +// and adapts the pipeline for a given ES version, converts to JSON if +// necessary and creates or updates ingest pipeline in ES. +func UploadPipelines(info beat.Info, esClient *eslegclient.Connection, overwritePipelines bool) error { + pipelines, err := readAll(info) + if err != nil { + return err + } + return load(esClient, pipelines, overwritePipelines) +} + +// ExportPipelines reads all pipelines embedded in the Winlogbeat executable +// and adapts the pipelines for a given ES version and writes the +// converted pipelines to the given directory in JSON format. +func ExportPipelines(info beat.Info, version common.Version, directory string) error { + log := logp.NewLogger(logName) + pipelines, err := readAll(info) + if err != nil { + return err + } + + for _, pipeline := range pipelines { + if err := fileset.AdaptPipelineForCompatibility(version, pipeline.id, pipeline.contents, log); err != nil { + return fmt.Errorf("failed to adapt pipeline with backwards compatibility changes for version %s: %w", version.String(), err) + } + f, err := os.Create(filepath.Join(directory, pipeline.id+".json")) + if err != nil { + return fmt.Errorf("unable to create file to export pipeline to: %w", err) + } + enc := json.NewEncoder(f) + enc.SetEscapeHTML(false) + err = enc.Encode(pipeline.contents) + if err != nil { + return fmt.Errorf("unable to JSON encode pipeline %s: %w", f.Name(), err) + } + } + return nil +} + +// readAll reads pipelines from the the embedded filesystem and +// returns a slice of pipelines suitable for sending to Elasticsearch +// with load. +func readAll(info beat.Info) (pipelines []pipeline, err error) { + p, err := readDir(".", info) + if err == errNoFS { + return nil, nil + } + return p, err +} + +func readDir(dir string, info beat.Info) (pipelines []pipeline, err error) { + if PipelinesFS == nil { + return nil, errNoFS + } + dirEntries, err := PipelinesFS.ReadDir(dir) + if err != nil { + return nil, err + } + for _, de := range dirEntries { + if de.IsDir() { + subPipelines, err := readDir(path.Join(dir, de.Name()), info) + if err != nil { + return nil, err + } + pipelines = append(pipelines, subPipelines...) + continue + } + p, err := readFile(path.Join(dir, de.Name()), info) + if err == errNoFS { + continue + } + if err != nil { + return nil, err + } + pipelines = append(pipelines, p) + } + return pipelines, nil +} + +func readFile(filename string, info beat.Info) (p pipeline, err error) { + if PipelinesFS == nil { + return pipeline{}, errNoFS + } + contents, err := PipelinesFS.ReadFile(filename) + if err != nil { + return pipeline{}, err + } + updatedContent, err := applyTemplates(info.IndexPrefix, info.Version, filename, contents) + if err != nil { + return pipeline{}, err + } + p = pipeline{ + id: fileset.FormatPipelineID(info.IndexPrefix, "", "", filename, info.Version), + contents: updatedContent, + } + return p, nil +} + +// load uses esClient to load pipelines to Elasticsearch cluster. +// Will only overwrite existing pipelines if overwritePipelines is +// true. An error in loading one of the pipelines will cause the +// successfully loaded ones to be deleted. +func load(esClient *eslegclient.Connection, pipelines []pipeline, overwritePipelines bool) (err error) { + var pipelineIDsLoaded []string + log := logp.NewLogger(logName) + + for _, pipeline := range pipelines { + err = fileset.LoadPipeline(esClient, pipeline.id, pipeline.contents, overwritePipelines, log) + if err != nil { + err = fmt.Errorf("error loading pipeline %s: %w", pipeline.id, err) + break + } + pipelineIDsLoaded = append(pipelineIDsLoaded, pipeline.id) + } + + if err != nil { + errs := multierror.Errors{err} + for _, pipelineID := range pipelineIDsLoaded { + err = fileset.DeletePipeline(esClient, pipelineID) + if err != nil { + errs = append(errs, err) + } + } + return errs.Err() + } + return nil +} + +func applyTemplates(prefix string, version string, filename string, original []byte) (converted map[string]interface{}, err error) { + vars := map[string]interface{}{ + "builtin": map[string]interface{}{ + "prefix": prefix, + "module": "", + "fileset": "", + "beatVersion": version, + }, + } + + encodedString, err := fileset.ApplyTemplate(vars, string(original), true) + + var content map[string]interface{} + switch extension := strings.ToLower(filepath.Ext(filename)); extension { + case ".json": + if err = json.Unmarshal([]byte(encodedString), &content); err != nil { + return nil, fmt.Errorf("error JSON decoding the pipeline file: %s: %w", filename, err) + } + case ".yaml", ".yml": + if err = yaml.Unmarshal([]byte(encodedString), &content); err != nil { + return nil, fmt.Errorf("error YAML decoding the pipeline file: %s: %w", filename, err) + } + newContent, err := fileset.FixYAMLMaps(content) + if err != nil { + return nil, fmt.Errorf("failed to sanitize the YAML pipeline file: %s: %w", filename, err) + } + content = newContent.(map[string]interface{}) + default: + return nil, fmt.Errorf("unsupported extension '%s' for pipeline file: %s", extension, filename) + } + return content, nil +} diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 51ca51897f8f..17f40c8a5f97 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -20,6 +20,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. diff --git a/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl b/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl new file mode 100644 index 000000000000..ed83c8f61039 --- /dev/null +++ b/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl @@ -0,0 +1,15 @@ +{{subheader "Elasticsearch Output"}} +output.elasticsearch: + # Array of hosts to connect to. + hosts: ["localhost:9200"] + + # Protocol - either `http` (default) or `https`. + #protocol: "https" + + # Authentication credentials - either API key or username/password. + #api_key: "id:api_key" + #username: "elastic" + #password: "changeme" + + # Pipeline to route events to security, sysmon, or powershell pipelines. + pipeline: "winlogbeat-%{[agent.version]}-routing" diff --git a/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl b/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl index bf3d2423a788..5ee2b373dffe 100644 --- a/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl +++ b/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl @@ -5,55 +5,14 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js diff --git a/x-pack/winlogbeat/cmd/export.go b/x-pack/winlogbeat/cmd/export.go new file mode 100644 index 000000000000..ce6ecc5f9bf1 --- /dev/null +++ b/x-pack/winlogbeat/cmd/export.go @@ -0,0 +1,60 @@ +// 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 cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "github.com/elastic/beats/v7/libbeat/cmd/instance" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/winlogbeat/module" +) + +// GenTemplateConfigCmd is the command used to export the elasticsearch template. +func GenExportPipelineCmd(settings instance.Settings) *cobra.Command { + genExportPipelineCmd := &cobra.Command{ + Use: "pipelines", + Short: "Export pipelines", + Run: func(cmd *cobra.Command, args []string) { + version, _ := cmd.Flags().GetString("es.version") + dir, _ := cmd.Flags().GetString("dir") + + if version == "" { + fatalf("--es.version is required") + } + + ver, err := common.NewVersion(version) + if err != nil { + fatalf("Unable to parse ES version from %s: %+v", version, err) + } + + b, err := instance.NewInitializedBeat(settings) + if err != nil { + fatalf("Failed to initialize 'pipeline' command: %+v", err) + } + + err = module.ExportPipelines(b.Info, *ver, dir) + if err != nil { + fatalf("Failed to export pipelines: %+v", err) + } + + fmt.Fprintf(os.Stdout, "Exported pipelines") + }, + } + + genExportPipelineCmd.Flags().String("es.version", settings.Version, "Elasticsearch version (required)") + genExportPipelineCmd.Flags().String("dir", "", "Specify directory for exporting pipelines. Default is current directory.") + + return genExportPipelineCmd +} + +func fatalf(msg string, vs ...interface{}) { + fmt.Fprintf(os.Stderr, msg, vs...) + fmt.Fprintln(os.Stderr) + os.Exit(1) +} diff --git a/x-pack/winlogbeat/cmd/root.go b/x-pack/winlogbeat/cmd/root.go index ae56c4de83fe..9ac4f71a8910 100644 --- a/x-pack/winlogbeat/cmd/root.go +++ b/x-pack/winlogbeat/cmd/root.go @@ -7,6 +7,7 @@ package cmd import ( "github.com/elastic/beats/v7/libbeat/cmd" winlogbeatCmd "github.com/elastic/beats/v7/winlogbeat/cmd" + "github.com/elastic/beats/v7/x-pack/winlogbeat/module" // Register fields. _ "github.com/elastic/beats/v7/x-pack/libbeat/include" @@ -23,4 +24,6 @@ func init() { settings := winlogbeatCmd.WinlogbeatSettings() settings.ElasticLicensed = true RootCmd = winlogbeatCmd.Initialize(settings) + RootCmd.ExportCmd.AddCommand(GenExportPipelineCmd(settings)) + module.Init() } diff --git a/x-pack/winlogbeat/module/pipeline.go b/x-pack/winlogbeat/module/pipeline.go new file mode 100644 index 000000000000..baa335e4b2a1 --- /dev/null +++ b/x-pack/winlogbeat/module/pipeline.go @@ -0,0 +1,19 @@ +// 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 module + +import ( + "embed" + + "github.com/elastic/beats/v7/winlogbeat/module" +) + +// pipelineFS holds the yml representation of the ingest node pipelines +//go:embed */ingest/*.yml +var pipelinesFS embed.FS + +func Init() { + module.PipelinesFS = &pipelinesFS +} diff --git a/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js b/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js deleted file mode 100644 index 698b12711bf2..000000000000 --- a/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js +++ /dev/null @@ -1,690 +0,0 @@ -// 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. - -var powershell = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - - var normalizeCommonFieldNames = new processor.Convert({ - fields: [ - { - from: "winlog.event_data.Engine Version", - to: "winlog.event_data.EngineVersion", - }, - { - from: "winlog.event_data.Pipeline ID", - to: "winlog.event_data.PipelineId", - }, - { - from: "winlog.event_data.Runspace ID", - to: "winlog.event_data.RunspaceId", - }, - { - from: "winlog.event_data.Host Version", - to: "winlog.event_data.HostVersion", - }, - { - from: "winlog.event_data.Script Name", - to: "winlog.event_data.ScriptName", - }, - { - from: "winlog.event_data.Path", - to: "winlog.event_data.ScriptName", - }, - { - from: "winlog.event_data.Command Path", - to: "winlog.event_data.CommandPath", - }, - { - from: "winlog.event_data.Command Name", - to: "winlog.event_data.CommandName", - }, - { - from: "winlog.event_data.Command Type", - to: "winlog.event_data.CommandType", - }, - { - from: "winlog.event_data.User", - to: "winlog.event_data.UserId", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - - // Builds a dissect tokenizer. - // - // - chunks: number of chunks dissect needs to look for. - // - delimiter: indicates what is the delimiter between chunks, - // in addition to `\n` which is already expected. - // - sep: separator between key value pairs. - // - // example: - // For a string like "Foo=Bar\n\tBar=Baz", chunks: 2, delimiter: '\t', sep: '=' - var buildNewlineSpacedTokenizer = function (chunks, delimiter, sep) { - var tokenizer = ""; - for (var i = 0; i < chunks; i++) { - if (i !== 0) { - tokenizer += "\n%{}"; - } - tokenizer += delimiter+"%{*p"+i+"}"+sep+"%{&p"+i+"}"; - } - return tokenizer; - }; - - var dissectField = function (fromField, targetPrefix, chunks, delimiter, sep) { - return new processor.Dissect({ - field: fromField, - target_prefix: targetPrefix, - tokenizer: buildNewlineSpacedTokenizer(chunks, delimiter, sep), - fail_on_error: false, - }); - }; - - // countChunksDelimitedBy will return the number of chunks contained in a field - // that are delimited by the given delimiter. - var countChunksDelimitedBy = function(evt, fromField, delimiter) { - var str = evt.Get(fromField); - if (!str) { - return 0; - } - return str.split(delimiter).length-1; - }; - - var dissect4xxAnd600 = function (evt) { - var delimiter = "\t"; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.param3", delimiter); - - dissectField("winlog.event_data.param3", "winlog.event_data", chunks, delimiter, "=").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.param1"); - evt.Delete("winlog.event_data.param2"); - evt.Delete("winlog.event_data.param3"); - }; - - var dissect800Detail = function (evt) { - var delimiter = "\t"; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.param2", delimiter); - - dissectField("winlog.event_data.param2", "winlog.event_data", chunks, "\t", "=").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.param1"); - evt.Delete("winlog.event_data.param2"); - }; - - var dissect4103 = function (evt) { - var delimiter = " "; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.ContextInfo", delimiter); - - dissectField("winlog.event_data.ContextInfo", "winlog.event_data", chunks, delimiter, " = ").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.ContextInfo"); - evt.Delete("winlog.event_data.Severity"); - }; - - var addEngineVersion = function (evt) { - var version = evt.Get("winlog.event_data.EngineVersion"); - evt.Delete("winlog.event_data.EngineVersion"); - if (!version) { - return; - } - - evt.Put("powershell.engine.version", version); - }; - - var addPipelineID = function (evt) { - var id = evt.Get("winlog.event_data.PipelineId"); - evt.Delete("winlog.event_data.PipelineId"); - if (!id) { - return; - } - - evt.Put("powershell.pipeline_id", id); - }; - - var addRunspaceID = function (evt) { - var id = evt.Get("winlog.event_data.RunspaceId"); - evt.Delete("winlog.event_data.RunspaceId"); - if (!id) { - return; - } - - evt.Put("powershell.runspace_id", id); - }; - - var addScriptBlockID = function (evt) { - var id = evt.Get("winlog.event_data.ScriptBlockId"); - evt.Delete("winlog.event_data.ScriptBlockId"); - if (!id) { - return; - } - - evt.Put("powershell.file.script_block_id", id); - }; - - var addScriptBlockText = function (evt) { - var text = evt.Get("winlog.event_data.ScriptBlockText"); - evt.Delete("winlog.event_data.ScriptBlockText"); - if (!text) { - return; - } - - evt.Put("powershell.file.script_block_text", text); - }; - - var splitCommandLine = function (evt, source, target) { - var commandLine = evt.Get(source); - if (!commandLine) { - return; - } - evt.Put(target, windows.splitCommandLine(commandLine)); - }; - - var addProcessArgs = function (evt) { - splitCommandLine(evt, "process.command_line", "process.args"); - var args = evt.Get("process.args"); - if (args && args.length > 0) { - evt.Put("process.args_count", args.length); - } - }; - - var addExecutableVersion = function (evt) { - var version = evt.Get("winlog.event_data.HostVersion"); - evt.Delete("winlog.event_data.HostVersion"); - if (!version) { - return; - } - - evt.Put("powershell.process.executable_version", version); - }; - - var addFileInfo = function (evt) { - var scriptName = evt.Get("winlog.event_data.ScriptName"); - evt.Delete("winlog.event_data.ScriptName"); - if (!scriptName) { - return; - } - - evt.Put("file.path", scriptName); - evt.Put("file.name", path.basename(scriptName)); - evt.Put("file.directory", path.dirname(scriptName)); - - // path returns extensions with a preceding ., e.g.: .tmp, .png - // according to ecs the expected format is without it, so we need to remove it. - var ext = path.extname(scriptName); - if (!ext) { - return; - } - - if (ext.charAt(0) === ".") { - ext = ext.substr(1); - } - evt.Put("file.extension", ext); - }; - - var addCommandValue = function (evt) { - var value = evt.Get("winlog.event_data.CommandLine") - evt.Delete("winlog.event_data.CommandLine"); - if (!value) { - return; - } - - evt.Put("powershell.command.value", value.trim()); - }; - - var addCommandPath = function (evt) { - var commandPath = evt.Get("winlog.event_data.CommandPath"); - evt.Delete("winlog.event_data.CommandPath"); - if (!commandPath) { - return; - } - - evt.Put("powershell.command.path", commandPath); - }; - - var addCommandName = function (evt) { - var commandName = evt.Get("winlog.event_data.CommandName"); - evt.Delete("winlog.event_data.CommandName"); - if (!commandName) { - return; - } - - evt.Put("powershell.command.name", commandName); - }; - - var addCommandType = function (evt) { - var commandType = evt.Get("winlog.event_data.CommandType"); - evt.Delete("winlog.event_data.CommandType"); - if (!commandType) { - return; - } - - evt.Put("powershell.command.type", commandType); - }; - - var detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; - var parameterBindingRegex = /^.*name\=(.+);\s*value\=(.+)$/ - - // Parses a command invocation detail raw line, and converts it to an object, based on its type. - // - // - for unexpectedly formatted ones: {value: "the raw line as it is"} - // - for all: - // * related_command: describes to what command it is related to - // * value: the value for that detail line - // * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError - // - additionally, ParameterBinding adds a `name` field with the parameter name being bound. - var parseRawDetail = function (raw) { - var matches = detailRegex.exec(raw); - if (!matches || matches.length !== 4) { - return {value: raw}; - } - - if (matches[1] !== "ParameterBinding") { - return {type: matches[1], related_command: matches[2], value: matches[3]}; - } - - var nameValMatches = parameterBindingRegex.exec(matches[3]); - if (!nameValMatches || nameValMatches.length !== 3) { - return {value: matches[3]}; - } - - return { - type: matches[1], - related_command: matches[2], - name: nameValMatches[1], - value: nameValMatches[2], - }; - }; - - var addCommandInvocationDetails = function (evt, from) { - var rawDetails = evt.Get(from); - if (!rawDetails) { - return; - } - - var details = []; - rawDetails.split("\n").forEach(function (raw) { - details.push(parseRawDetail(raw)); - }); - - if (details.length === 0) { - return; - } - - evt.Delete(from); - evt.Put("powershell.command.invocation_details", details); - }; - - var addCommandInvocationDetailsForEvent800 = function (evt) { - addCommandInvocationDetails(evt, "winlog.event_data.param3"); - }; - - var addCommandInvocationDetailsForEvent4103 = function (evt) { - addCommandInvocationDetails(evt, "winlog.event_data.Payload"); - }; - - var addUser = function (evt) { - var userParts = evt.Get("winlog.event_data.UserId").split("\\"); - evt.Delete("winlog.event_data.UserId"); - if (userParts.length === 2) { - evt.Put("user.domain", userParts[0]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - } - }; - - var addConnectedUser = function (evt) { - var userParts = evt.Get("winlog.event_data.Connected User").split("\\"); - evt.Delete("winlog.event_data.Connected User"); - if (userParts.length === 2) { - evt.Put("powershell.connected_user.domain", userParts[0]); - if (evt.Get("user.domain")) { - evt.Put("destination.user.domain", evt.Get("user.domain")); - } - evt.Put("source.user.domain", userParts[0]); - evt.Put("user.domain", userParts[0]); - - evt.Put("powershell.connected_user.name", userParts[1]); - if (evt.Get("user.name")) { - evt.Put("destination.user.name", evt.Get("user.name")); - } - evt.Put("source.user.name", userParts[1]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - } - }; - - var removeEmptyEventData = function (evt) { - var eventData = evt.Get("winlog.event_data"); - if (eventData && Object.keys(eventData).length === 0) { - evt.Delete("winlog.event_data"); - } - }; - - var event4xxAnd600Common = new processor.Chain() - .Add(dissect4xxAnd600) - .Convert({ - fields: [ - { - from: "winlog.event_data.SequenceNumber", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.NewEngineState", - to: "powershell.engine.new_state", - }, - { - from: "winlog.event_data.PreviousEngineState", - to: "powershell.engine.previous_state", - }, - { - from: "winlog.event_data.NewProviderState", - to: "powershell.provider.new_state", - }, - { - from: "winlog.event_data.ProviderName", - to: "powershell.provider.name", - }, - { - from: "winlog.event_data.HostId", - to: "process.entity_id", - }, - { - from: "winlog.event_data.HostApplication", - to: "process.command_line", - }, - { - from: "winlog.event_data.HostName", - to: "process.title", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(removeEmptyEventData) - .Build(); - - var event400 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["start"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event403 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["end"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event600 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event800 = new processor.Chain() - .Add(dissect800Detail) - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.SequenceNumber", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.HostId", - to: "process.entity_id", - }, - { - from: "winlog.event_data.HostApplication", - to: "process.command_line", - }, - { - from: "winlog.event_data.HostName", - to: "process.title", - }, - { - from: "winlog.event_data.DetailTotal", - to: "powershell.total", - type: "long", - }, - { - from: "winlog.event_data.DetailSequence", - to: "powershell.sequence", - type: "long", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(addUser) - .Add(addCommandInvocationDetailsForEvent800) - .Add(removeEmptyEventData) - .Build(); - - var event4103 = new processor.Chain() - .Add(dissect4103) - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.Sequence Number", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.Host ID", - to: "process.entity_id", - }, - { - from: "winlog.event_data.Host Application", - to: "process.command_line", - }, - { - from: "winlog.event_data.Host Name", - to: "process.title", - }, - { - from: "winlog.event_data.Shell ID", - to: "powershell.id", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(normalizeCommonFieldNames) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(addUser) - .Add(addConnectedUser) - .Add(addCommandInvocationDetailsForEvent4103) - .Add(removeEmptyEventData) - .Build(); - - var event4104 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.MessageNumber", - to: "powershell.sequence", - type: "long", - }, - { - from: "winlog.event_data.MessageTotal", - to: "powershell.total", - type: "long", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(normalizeCommonFieldNames) - .Add(addFileInfo) - .Add(addScriptBlockID) - .Add(addScriptBlockText) - .Add(removeEmptyEventData) - .Build(); - - var event4105And4106Common = new processor.Chain() - .Add(addRunspaceID) - .Add(addScriptBlockID) - .Add(removeEmptyEventData) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Build(); - - var event4105 = new processor.Chain() - .Add(event4105And4106Common) - .AddFields({ - fields: { - category: ["process"], - type: ["start"], - }, - target: "event", - }) - .Build(); - - var event4106 = new processor.Chain() - .Add(event4105And4106Common) - .AddFields({ - fields: { - category: ["process"], - type: ["end"], - }, - target: "event", - }) - .Build(); - - return { - 400: event400.Run, - 403: event403.Run, - 600: event600.Run, - 800: event800.Run, - 4103: event4103.Run, - 4104: event4104.Run, - 4105: event4105.Run, - 4106: event4106.Run, - - process: function(evt) { - var eventId = evt.Get("winlog.event_id"); - var processor = this[eventId]; - if (processor === undefined) { - return; - } - evt.Put("event.module", "powershell"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return powershell.process(evt); -} diff --git a/x-pack/winlogbeat/module/powershell/ingest/powershell.yml b/x-pack/winlogbeat/module/powershell/ingest/powershell.yml new file mode 100644 index 000000000000..117f7288a94e --- /dev/null +++ b/x-pack/winlogbeat/module/powershell/ingest/powershell.yml @@ -0,0 +1,433 @@ +--- +description: Pipeline for Windows Powershell events +processors: + - kv: + description: Split Event 800 event data fields. + field: winlog.event_data.param2 + target_field: winlog.event_data + field_split: "\n\t" + trim_key: "\n\t" + trim_value: "\n\t" + value_split: "=" + if: ctx?.winlog?.event_id == "800" + - kv: + description: Split Events 4xx and 600 event data fields. + field: winlog.event_data.param3 + target_field: winlog.event_data + field_split: "\n\t" + trim_key: "\n\t" + trim_value: "\n\t" + value_split: "=" + if: ctx?.winlog?.event_id != "800" + + ## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + - set: + field: event.category + value: process + - set: + field: event.type + value: start + if: ctx?.event.code == "400" + - set: + field: event.type + value: end + if: ctx?.event.code == "403" + - set: + field: event.type + value: info + if: ctx?.event?.type == null + - convert: + field: winlog.event_data.SequenceNumber + target_field: event.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + ## Process fields. + + - rename: + field: winlog.event_data.HostId + target_field: process.entity_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostId != "" + - rename: + field: winlog.event_data.HostApplication + target_field: process.command_line + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostApplication != "" + - rename: + field: winlog.event_data.HostName + target_field: process.title + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostName != "" + + ## User fields. + + - split: + field: winlog.event_data.UserId + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.UserId != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null + + ## PowerShell fields. + + - rename: + field: winlog.event_data.NewEngineState + target_field: powershell.engine.new_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.NewEngineState != "" + - rename: + field: winlog.event_data.PreviousEngineState + target_field: powershell.engine.previous_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.PreviousEngineState != "" + - rename: + field: winlog.event_data.NewProviderState + target_field: powershell.provider.new_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.NewProviderState != "" + - rename: + field: winlog.event_data.ProviderName + target_field: powershell.provider.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ProviderName != "" + - convert: + field: winlog.event_data.DetailTotal + target_field: powershell.total + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DetailTotal != "" + - convert: + field: winlog.event_data.DetailSequence + target_field: powershell.sequence + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DetailSequence != "" + - rename: + field: winlog.event_data.EngineVersion + target_field: powershell.engine.version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.EngineVersion != "" + - rename: + field: winlog.event_data.PipelineId + target_field: powershell.pipeline_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipelineId != "" + - rename: + field: winlog.event_data.RunspaceId + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceId != "" + - rename: + field: winlog.event_data.HostVersion + target_field: powershell.process.executable_version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.HostVersion != "" + - rename: + field: winlog.event_data.CommandLine + target_field: powershell.command.value + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CommandPath + target_field: powershell.command.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandPath != "" + - rename: + field: winlog.event_data.CommandName + target_field: powershell.command.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandName != "" + - rename: + field: winlog.event_data.CommandType + target_field: powershell.command.type + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandType != "" + + - split: + description: Split Event 800 command invocation details. + field: winlog.event_data.param3 + separator: "\n" + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "800" + - script: + description: |- + Parses all command invocation detail raw lines, and converts them to an object, based on their type. + - for unexpectedly formatted ones: {value: "the raw line as it is"} + - for all: + * related_command: describes to what command it is related to + * value: the value for that detail line + * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError + - additionally, ParameterBinding adds a `name` field with the parameter name being bound. + lang: painless + if: ctx.event.code == "800" + params: + field: param3 + source: |- + def parseRawDetail(String raw) { + Pattern detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; + Pattern parameterBindingRegex = /name\=(.+);\s*value\=(.+)$/; + + def matcher = detailRegex.matcher(raw); + if (!matcher.matches()) { + return ["value": raw]; + } + def matches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + matches.add(matcher.group(i)); + } + + if (matches.length != 4) { + return ["value": raw]; + } + + if (matches[1] != "ParameterBinding") { + return [ + "type": matches[1], + "related_command": matches[2], + "value": matches[3] + ]; + } + + matcher = parameterBindingRegex.matcher(matches[3]); + if (!matcher.matches()) { + return ["value": matches[4]]; + } + def nameValMatches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + nameValMatches.add(matcher.group(i)); + } + if (nameValMatches.length !== 3) { + return ["value": matches[3]]; + } + + return [ + "type": matches[1], + "related_command": matches[2], + "name": nameValMatches[1], + "value": nameValMatches[2] + ]; + } + + if (ctx?._temp == null) { + ctx._temp = new HashMap(); + } + + if (ctx._temp.details == null) { + ctx._temp.details = new ArrayList(); + } + + def values = ctx?.winlog?.event_data[params["field"]]; + if (values != null && values.length > 0) { + for (v in values) { + ctx._temp.details.add(parseRawDetail(v)); + } + } + - rename: + field: _temp.details + target_field: powershell.command.invocation_details + if: ctx?._temp?.details != null && ctx?._temp?.details.length > 0 + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: ctx?.process?.command_line != null && ctx.process.command_line != "" + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + ctx.process.args = commandLineToArgv(ctx.process.command_line); + ctx.process.args_count = ctx.process.args.length; + + - script: + description: Adds file information. + lang: painless + if: ctx?.winlog?.event_data?.ScriptName != null && ctx.winlog.event_data.ScriptName.length() > 1 + source: |- + def path = ctx.winlog.event_data.ScriptName; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + - rename: + field: winlog.event_data.ScriptName + target_field: file.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptName != "" + + ## Cleanup. + + - remove: + field: + - _temp + - winlog.event_data.param1 + - winlog.event_data.param2 + - winlog.event_data.param3 + - winlog.event_data.SequenceNumber + - winlog.event_data.DetailTotal + - winlog.event_data.DetailSequence + - winlog.event_data.UserId + - winlog.time_created + - winlog.level + ignore_missing: true + ignore_failure: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml b/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml new file mode 100644 index 000000000000..d508f0d73413 --- /dev/null +++ b/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml @@ -0,0 +1,492 @@ +--- +description: Pipeline for Windows Powershell/Operational events +processors: + - kv: + description: Split Event 4103 event data fields. + field: winlog.event_data.ContextInfo + target_field: winlog.event_data + field_split: "\n" + trim_key: " \n\t" + trim_value: " \n\t" + value_split: "=" + if: ctx?.winlog?.event_id == "4103" + - script: + description: Remove spaces from all event_data keys. + lang: painless + if: ctx?.winlog?.event_data != null + source: |- + def newEventData = new HashMap(); + for (entry in ctx.winlog.event_data.entrySet()) { + def newKey = /\s/.matcher(entry.getKey().toString()).replaceAll(""); + newEventData.put(newKey, entry.getValue()); + } + ctx.winlog.event_data = newEventData; + + ## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + - set: + field: event.category + value: process + - set: + field: event.type + value: start + if: ctx?.event.code == "4105" + - set: + field: event.type + value: end + if: ctx?.event.code == "4106" + - set: + field: event.type + value: info + if: ctx?.event?.type == null + - convert: + field: winlog.event_data.SequenceNumber + target_field: event.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + ## Process fields. + + - rename: + field: winlog.event_data.HostID + target_field: process.entity_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostID != "" + - rename: + field: winlog.event_data.HostApplication + target_field: process.command_line + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostApplication != "" + - rename: + field: winlog.event_data.HostName + target_field: process.title + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostName != "" + + ## User fields. + + - set: + field: user.id + copy_from: winlog.user.identifier + ignore_failure: true + ignore_empty_value: true + - split: + field: winlog.event_data.User + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.User != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null + - split: + field: winlog.event_data.ConnectedUser + target_field: "_temp.connected_user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.ConnectedUser != null + - set: + field: source.user.domain + value: "{{_temp.connected_user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.connected_user_parts != null && ctx._temp.connected_user_parts.size() == 2 + - set: + field: source.user.name + value: "{{_temp.connected_user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.connected_user_parts != null && ctx._temp.connected_user_parts.size() == 2 + - append: + field: related.user + value: "{{source.user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.source?.user?.name != null + - rename: + field: user.domain + target_field: destination.user.domain + ignore_failure: true + ignore_missing: true + if: ctx?.source?.user != null + - rename: + field: user.name + target_field: destination.user.name + ignore_failure: true + ignore_missing: true + if: ctx?.source?.user != null + - set: + field: user.domain + copy_from: source.user.domain + ignore_failure: true + ignore_empty_value: true + if: ctx?.source?.user != null + - set: + field: user.name + copy_from: source.user.name + ignore_failure: true + ignore_empty_value: true + if: ctx?.source?.user != null + + ## PowerShell fields. + + - convert: + field: winlog.event_data.MessageNumber + target_field: powershell.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.event_data.MessageTotal + target_field: powershell.total + type: long + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.ShellID + target_field: powershell.id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ShellID != "" + - rename: + field: winlog.event_data.EngineVersion + target_field: powershell.engine.version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.EngineVersion != "" + - rename: + field: winlog.event_data.PipelineID + target_field: powershell.pipeline_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipelineID != "" + - rename: + field: winlog.event_data.RunspaceID + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceID != "" + - rename: + field: winlog.event_data.RunspaceId + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceId != "" + - rename: + field: winlog.event_data.HostVersion + target_field: powershell.process.executable_version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.HostVersion != "" + - rename: + field: winlog.event_data.CommandLine + target_field: powershell.command.value + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CommandPath + target_field: powershell.command.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandPath != "" + - rename: + field: winlog.event_data.CommandName + target_field: powershell.command.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandName != "" + - rename: + field: winlog.event_data.CommandType + target_field: powershell.command.type + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandType != "" + - rename: + field: winlog.event_data.ScriptBlockId + target_field: powershell.file.script_block_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptBlockId != "" + - rename: + field: winlog.event_data.ScriptBlockText + target_field: powershell.file.script_block_text + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptBlockText != "" + + - split: + description: Split Event 800 command invocation details. + field: winlog.event_data.Payload + separator: "\n" + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "4103" + - script: + description: |- + Parses all command invocation detail raw lines, and converts them to an object, based on their type. + - for unexpectedly formatted ones: {value: "the raw line as it is"} + - for all: + * related_command: describes to what command it is related to + * value: the value for that detail line + * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError + - additionally, ParameterBinding adds a `name` field with the parameter name being bound. + lang: painless + if: ctx.event.code == "4103" + params: + field: Payload + source: |- + def parseRawDetail(String raw) { + Pattern detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; + Pattern parameterBindingRegex = /name\=(.+);\s*value\=(.+)$/; + + def matcher = detailRegex.matcher(raw); + if (!matcher.matches()) { + return ["value": raw]; + } + def matches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + matches.add(matcher.group(i)); + } + + if (matches.length != 4) { + return ["value": raw]; + } + + if (matches[1] != "ParameterBinding") { + return [ + "type": matches[1], + "related_command": matches[2], + "value": matches[3] + ]; + } + + matcher = parameterBindingRegex.matcher(matches[3]); + if (!matcher.matches()) { + return ["value": matches[4]]; + } + def nameValMatches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + nameValMatches.add(matcher.group(i)); + } + if (nameValMatches.length !== 3) { + return ["value": matches[3]]; + } + + return [ + "type": matches[1], + "related_command": matches[2], + "name": nameValMatches[1], + "value": nameValMatches[2] + ]; + } + + if (ctx?._temp == null) { + ctx._temp = new HashMap(); + } + + if (ctx._temp.details == null) { + ctx._temp.details = new ArrayList(); + } + + def values = ctx?.winlog?.event_data[params["field"]]; + if (values != null && values.length > 0) { + for (v in values) { + ctx._temp.details.add(parseRawDetail(v)); + } + } + - rename: + field: _temp.details + target_field: powershell.command.invocation_details + if: ctx?._temp?.details != null && ctx?._temp?.details.length > 0 + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: ctx?.process?.command_line != null && ctx.process.command_line != "" + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + ctx.process.args = commandLineToArgv(ctx.process.command_line); + ctx.process.args_count = ctx.process.args.length; + + - rename: + field: winlog.event_data.Path + target_field: winlog.event_data.ScriptName + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.Path != "" + - script: + description: Adds file information. + lang: painless + if: ctx?.winlog?.event_data?.ScriptName != null && ctx.winlog.event_data.ScriptName.length() > 1 + source: |- + def path = ctx.winlog.event_data.ScriptName; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + - rename: + field: winlog.event_data.ScriptName + target_field: file.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptName != "" + + ## Cleanup. + + - remove: + field: + - _temp + - winlog.event_data.SequenceNumber + - winlog.event_data.User + - winlog.event_data.ConnectedUser + - winlog.event_data.ContextInfo + - winlog.event_data.Severity + - winlog.event_data.MessageTotal + - winlog.event_data.MessageNumber + - winlog.event_data.Payload + - winlog.time_created + - winlog.level + ignore_missing: true + ignore_failure: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go b/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go deleted file mode 100644 index 46c4f463f404..000000000000 --- a/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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 test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields because they can be different on different versions -// of windows. -var ignoreFields = []string{ - "message", -} - -func TestPowerShell(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-powershell.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/module/routing/ingest/routing.yml b/x-pack/winlogbeat/module/routing/ingest/routing.yml new file mode 100644 index 000000000000..7566be699437 --- /dev/null +++ b/x-pack/winlogbeat/module/routing/ingest/routing.yml @@ -0,0 +1,20 @@ +--- +description: Winlogbeat Routing Pipeline +processors: + - pipeline: + name: '{< IngestPipeline "security" >}' + if: ctx?.winlog?.channel == 'Security' + - pipeline: + name: '{< IngestPipeline "sysmon" >}' + if: ctx?.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational' + - pipeline: + name: '{< IngestPipeline "powershell" >}' + if: ctx?.winlog?.channel == 'Windows Powershell' + - pipeline: + name: '{< IngestPipeline "powershell_operational" >}' + if: ctx?.winlog?.channel == 'Microsoft-Windows-PowerShell/Operational' +on_failure: + - set: + field: error.message + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js b/x-pack/winlogbeat/module/security/config/winlogbeat-security.js deleted file mode 100644 index 39739db14796..000000000000 --- a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js +++ /dev/null @@ -1,2828 +0,0 @@ -// 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. - -var security = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - - // Logon Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events - var logonTypes = { - "2": "Interactive", - "3": "Network", - "4": "Batch", - "5": "Service", - "7": "Unlock", - "8": "NetworkCleartext", - "9": "NewCredentials", - "10": "RemoteInteractive", - "11": "CachedInteractive", - }; - - // User Account Control Attributes Table - // https://support.microsoft.com/es-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties - var uacFlags = [ - [0x0001, 'SCRIPT'], - [0x0002, 'ACCOUNTDISABLE'], - [0x0008, 'HOMEDIR_REQUIRED'], - [0x0010, 'LOCKOUT'], - [0x0020, 'PASSWD_NOTREQD'], - [0x0040, 'PASSWD_CANT_CHANGE'], - [0x0080, 'ENCRYPTED_TEXT_PWD_ALLOWED'], - [0x0100, 'TEMP_DUPLICATE_ACCOUNT'], - [0x0200, 'NORMAL_ACCOUNT'], - [0x0800, 'INTERDOMAIN_TRUST_ACCOUNT'], - [0x1000, 'WORKSTATION_TRUST_ACCOUNT'], - [0x2000, 'SERVER_TRUST_ACCOUNT'], - [0x10000, 'DONT_EXPIRE_PASSWORD'], - [0x20000, 'MNS_LOGON_ACCOUNT'], - [0x40000, 'SMARTCARD_REQUIRED'], - [0x80000, 'TRUSTED_FOR_DELEGATION'], - [0x100000, 'NOT_DELEGATED'], - [0x200000, 'USE_DES_KEY_ONLY'], - [0x400000, 'DONT_REQ_PREAUTH'], - [0x800000, 'PASSWORD_EXPIRED'], - [0x1000000, 'TRUSTED_TO_AUTH_FOR_DELEGATION'], - [0x04000000, 'PARTIAL_SECRETS_ACCOUNT'], - ]; - - // Kerberos TGT and TGS Ticket Options - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4769 - var ticketOptions = [ - "Reserved", - "Forwardable", - "Forwarded", - "Proxiable", - "Proxy", - "Allow-postdate", - "Postdated", - "Invalid", - "Renewable", - "Initial", - "Pre-authent", - "Opt-hardware-auth", - "Transited-policy-checked", - "Ok-as-delegate", - "Request-anonymous", - "Name-canonicalize", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Disable-transited-check", - "Renewable-ok", - "Enc-tkt-in-skey", - "Unused", - "Renew", - "Validate"]; - - // Kerberos Encryption Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - var ticketEncryptionTypes = { - "0x1": "DES-CBC-CRC", - "0x3": "DES-CBC-MD5", - "0x11": "AES128-CTS-HMAC-SHA1-96", - "0x12": "AES256-CTS-HMAC-SHA1-96", - "0x17": "RC4-HMAC", - "0x18": "RC4-HMAC-EXP", - "0xffffffff": "FAIL", - }; - - // Kerberos Result Status Codes - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - var kerberosTktStatusCodes = { - "0x0": "KDC_ERR_NONE", - "0x1": "KDC_ERR_NAME_EXP", - "0x2": "KDC_ERR_SERVICE_EXP", - "0x3": "KDC_ERR_BAD_PVNO", - "0x4": "KDC_ERR_C_OLD_MAST_KVNO", - "0x5": "KDC_ERR_S_OLD_MAST_KVNO", - "0x6": "KDC_ERR_C_PRINCIPAL_UNKNOWN", - "0x7": "KDC_ERR_S_PRINCIPAL_UNKNOWN", - "0x8": "KDC_ERR_PRINCIPAL_NOT_UNIQUE", - "0x9": "KDC_ERR_NULL_KEY", - "0xA": "KDC_ERR_CANNOT_POSTDATE", - "0xB": "KDC_ERR_NEVER_VALID", - "0xC": "KDC_ERR_POLICY", - "0xD": "KDC_ERR_BADOPTION", - "0xE": "KDC_ERR_ETYPE_NOTSUPP", - "0xF": "KDC_ERR_SUMTYPE_NOSUPP", - "0x10": "KDC_ERR_PADATA_TYPE_NOSUPP", - "0x11": "KDC_ERR_TRTYPE_NO_SUPP", - "0x12": "KDC_ERR_CLIENT_REVOKED", - "0x13": "KDC_ERR_SERVICE_REVOKED", - "0x14": "KDC_ERR_TGT_REVOKED", - "0x15": "KDC_ERR_CLIENT_NOTYET", - "0x16": "KDC_ERR_SERVICE_NOTYET", - "0x17": "KDC_ERR_KEY_EXPIRED", - "0x18": "KDC_ERR_PREAUTH_FAILED", - "0x19": "KDC_ERR_PREAUTH_REQUIRED", - "0x1A": "KDC_ERR_SERVER_NOMATCH", - "0x1B": "KDC_ERR_MUST_USE_USER2USER", - "0x1F": "KRB_AP_ERR_BAD_INTEGRITY", - "0x20": "KRB_AP_ERR_TKT_EXPIRED", - "0x21": "KRB_AP_ERR_TKT_NYV", - "0x22": "KRB_AP_ERR_REPEAT", - "0x23": "KRB_AP_ERR_NOT_US", - "0x24": "KRB_AP_ERR_BADMATCH", - "0x25": "KRB_AP_ERR_SKEW", - "0x26": "KRB_AP_ERR_BADADDR", - "0x27": "KRB_AP_ERR_BADVERSION", - "0x28": "KRB_AP_ERR_MSG_TYPE", - "0x29": "KRB_AP_ERR_MODIFIED", - "0x2A": "KRB_AP_ERR_BADORDER", - "0x2C": "KRB_AP_ERR_BADKEYVER", - "0x2D": "KRB_AP_ERR_NOKEY", - "0x2E": "KRB_AP_ERR_MUT_FAIL", - "0x2F": "KRB_AP_ERR_BADDIRECTION", - "0x30": "KRB_AP_ERR_METHOD", - "0x31": "KRB_AP_ERR_BADSEQ", - "0x32": "KRB_AP_ERR_INAPP_CKSUM", - "0x33": "KRB_AP_PATH_NOT_ACCEPTED", - "0x34": "KRB_ERR_RESPONSE_TOO_BIG", - "0x3C": "KRB_ERR_GENERIC", - "0x3D": "KRB_ERR_FIELD_TOOLONG", - "0x3E": "KDC_ERR_CLIENT_NOT_TRUSTED", - "0x3F": "KDC_ERR_KDC_NOT_TRUSTED", - "0x40": "KDC_ERR_INVALID_SIG", - "0x41": "KDC_ERR_KEY_TOO_WEAK", - "0x42": "KRB_AP_ERR_USER_TO_USER_REQUIRED", - "0x43": "KRB_AP_ERR_NO_TGT", - "0x44": "KDC_ERR_WRONG_REALM", - }; - - // event.category, event.type, event.action - var eventActionTypes = { - "1100": [["process"], ["end"], "logging-service-shutdown"], - "1102": [["iam"], ["admin", "change"], "audit-log-cleared"], // need to recategorize - "1104": [["iam"], ["admin"],"logging-full"], - "1105": [["iam"], ["admin"],"auditlog-archieved"], - "1108": [["iam"], ["admin"],"logging-processing-error"], - "4610": [["configuration"], ["access"], "authentication-package-loaded"], - "4611": [["configuration"], ["change"], "trusted-logon-process-registered"], - "4614": [["configuration"], ["access"], "notification-package-loaded"], - "4616": [["configuration"], ["change"], "system-time-changed"], - "4622": [["configuration"], ["access"], "security-package-loaded"], - "4624": [["authentication"], ["start"], "logged-in"], - "4625": [["authentication"], ["start"], "logon-failed"], - "4634": [["authentication"], ["end"], "logged-out"], - "4647": [["authentication"], ["end"], "logged-out"], - "4648": [["authentication"], ["start"], "logged-in-explicit"], - "4657": [["registry", "configuration"], ["change"], "registry-value-modified"], - "4670": [["iam", "configuration"],["admin", "change"],"permissions-changed"], - "4672": [["iam"], ["admin"], "logged-in-special"], - "4673": [["iam"], ["admin"], "privileged-service-called"], - "4674": [["iam"], ["admin"], "privileged-operation"], - "4688": [["process"], ["start"], "created-process"], - "4689": [["process"], ["end"], "exited-process"], - "4697": [["iam", "configuration"], ["admin", "change"],"service-installed"], // remove iam and admin - "4698": [["iam", "configuration"], ["creation", "admin"], "scheduled-task-created"], // remove iam and admin - "4699": [["iam", "configuration"], ["deletion", "admin"], "scheduled-task-deleted"], // remove iam and admin - "4700": [["iam", "configuration"], ["change", "admin"], "scheduled-task-enabled"], // remove iam and admin - "4701": [["iam", "configuration"], ["change", "admin"], "scheduled-task-disabled"], // remove iam and admin - "4702": [["iam", "configuration"], ["change", "admin"], "scheduled-task-updated"], // remove iam and admin - "4706": [["configuration"], ["creation"], "domain-trust-added"], - "4707": [["configuration"], ["deletion"], "domain-trust-removed"], - "4713": [["configuration"], ["change"], "kerberos-policy-changed"], - "4714": [["configuration"], ["change"], "encrypted-data-recovery-policy-changed"], - "4715": [["configuration"], ["change"], "object-audit-policy-changed"], - "4716": [["configuration"], ["change"], "trusted-domain-information-changed"], - "4717": [["iam", "configuration"],["admin", "change"],"system-security-access-granted"], - "4718": [["iam", "configuration"],["admin", "deletion"],"system-security-access-removed"], - "4719": [["iam", "configuration"], ["admin", "change"], "changed-audit-config"], // remove iam and admin - "4720": [["iam"], ["user", "creation"], "added-user-account"], - "4722": [["iam"], ["user", "change"], "enabled-user-account"], - "4723": [["iam"], ["user", "change"], "changed-password"], - "4724": [["iam"], ["user", "change"], "reset-password"], - "4725": [["iam"], ["user", "deletion"], "disabled-user-account"], - "4726": [["iam"], ["user", "deletion"], "deleted-user-account"], - "4727": [["iam"], ["group", "creation"], "added-group-account"], - "4728": [["iam"], ["group", "change"], "added-member-to-group"], - "4729": [["iam"], ["group", "change"], "removed-member-from-group"], - "4730": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4731": [["iam"], ["group", "creation"], "added-group-account"], - "4732": [["iam"], ["group", "change"], "added-member-to-group"], - "4733": [["iam"], ["group", "change"], "removed-member-from-group"], - "4734": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4735": [["iam"], ["group", "change"], "modified-group-account"], - "4737": [["iam"], ["group", "change"], "modified-group-account"], - "4738": [["iam"], ["user", "change"], "modified-user-account"], - "4739": [["configuration"], ["change"], "domain-policy-changed"], - "4740": [["iam"], ["user", "change"], "locked-out-user-account"], - "4741": [["iam"], ["creation", "admin"], "added-computer-account"], // remove admin - "4742": [["iam"], ["change", "admin"], "changed-computer-account"], // remove admin - "4743": [["iam"], ["deletion", "admin"], "deleted-computer-account"], // remove admin - "4744": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4745": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4746": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4747": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4748": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4749": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4750": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4751": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4752": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4753": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4754": [["iam"], ["group", "creation"], "added-group-account"], - "4755": [["iam"], ["group", "change"], "modified-group-account"], - "4756": [["iam"], ["group", "change"], "added-member-to-group"], - "4757": [["iam"], ["group", "change"], "removed-member-from-group"], - "4758": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4759": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4760": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4761": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4762": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4763": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4764": [["iam"], ["group", "change"], "type-changed-group-account"], - "4767": [["iam"], ["user", "change"], "unlocked-user-account"], - "4768": [["authentication"], ["start"], "kerberos-authentication-ticket-requested"], - "4769": [["authentication"], ["start"], "kerberos-service-ticket-requested"], - "4770": [["authentication"], ["start"], "kerberos-service-ticket-renewed"], - "4771": [["authentication"], ["start"], "kerberos-preauth-failed"], - "4776": [["authentication"], ["start"], "credential-validated"], - "4778": [["authentication", "session"], ["start"], "session-reconnected"], - "4779": [["authentication", "session"], ["end"], "session-disconnected"], - "4781": [["iam"], ["user", "change"], "renamed-user-account"], - "4798": [["iam"], ["user", "info"], "group-membership-enumerated"], // process enumerates the local groups to which the specified user belongs - "4799": [["iam"], ["group", "info"], "user-member-enumerated"], // a process enumerates the members of the specified local group - "4817": [["iam", "configuration"], ["admin", "change"],"object-audit-changed"], - "4902": [["iam", "configuration"], ["admin", "creation"],"user-audit-policy-created"], - "4904": [["iam", "configuration"], ["admin", "change"],"security-event-source-added"], - "4905": [["iam", "configuration"], ["admin", "deletion"], "security-event-source-removed"], - "4906": [["iam", "configuration"], ["admin", "change"], "crash-on-audit-changed"], - "4907": [["iam", "configuration"], ["admin", "change"], "audit-setting-changed"], - "4908": [["iam", "configuration"], ["admin", "change"], "special-group-table-changed"], - "4912": [["iam", "configuration"], ["admin", "change"], "per-user-audit-policy-changed"], - "4950": [["configuration"], ["change"], "windows-firewall-setting-changed"], - "4954": [["configuration"], ["change"], "windows-firewall-group-policy-changed"], - "4964": [["iam"], ["admin", "group"], "logged-in-special"], - "5024": [["process"], ["start"], "windows-firewall-service-started"], - "5025": [["process"], ["end"], "windows-firewall-service-stopped"], - "5033": [["driver"], ["start"], "windows-firewall-driver-started"], - "5034": [["driver"], ["end"], "windows-firewall-driver-stopped"], - "5037": [["driver"], ["end"], "windows-firewall-driver-error"], - }; - - // Services Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4697 - var serviceTypes = { - "0x1": "Kernel Driver", - "0x2": "File System Driver", - "0x8": "Recognizer Driver", - "0x10": "Win32 Own Process", - "0x20": "Win32 Share Process", - "0x110": "Interactive Own Process", - "0x120": "Interactive Share Process", - }; - - - // Audit Categories Description - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpac/77878370-0712-47cd-997d-b07053429f6d - var auditDescription = { - "0CCE9210-69AE-11D9-BED3-505054503030":["Security State Change", "System"], - "0CCE9211-69AE-11D9-BED3-505054503030":["Security System Extension", "System"], - "0CCE9212-69AE-11D9-BED3-505054503030":["System Integrity", "System"], - "0CCE9213-69AE-11D9-BED3-505054503030":["IPsec Driver", "System"], - "0CCE9214-69AE-11D9-BED3-505054503030":["Other System Events", "System"], - "0CCE9215-69AE-11D9-BED3-505054503030":["Logon", "Logon/Logoff"], - "0CCE9216-69AE-11D9-BED3-505054503030":["Logoff","Logon/Logoff"], - "0CCE9217-69AE-11D9-BED3-505054503030":["Account Lockout","Logon/Logoff"], - "0CCE9218-69AE-11D9-BED3-505054503030":["IPsec Main Mode","Logon/Logoff"], - "0CCE9219-69AE-11D9-BED3-505054503030":["IPsec Quick Mode","Logon/Logoff"], - "0CCE921A-69AE-11D9-BED3-505054503030":["IPsec Extended Mode","Logon/Logoff"], - "0CCE921B-69AE-11D9-BED3-505054503030":["Special Logon","Logon/Logoff"], - "0CCE921C-69AE-11D9-BED3-505054503030":["Other Logon/Logoff Events","Logon/Logoff"], - "0CCE9243-69AE-11D9-BED3-505054503030":["Network Policy Server","Logon/Logoff"], - "0CCE9247-69AE-11D9-BED3-505054503030":["User / Device Claims","Logon/Logoff"], - "0CCE921D-69AE-11D9-BED3-505054503030":["File System","Object Access"], - "0CCE921E-69AE-11D9-BED3-505054503030":["Registry","Object Access"], - "0CCE921F-69AE-11D9-BED3-505054503030":["Kernel Object","Object Access"], - "0CCE9220-69AE-11D9-BED3-505054503030":["SAM","Object Access"], - "0CCE9221-69AE-11D9-BED3-505054503030":["Certification Services","Object Access"], - "0CCE9222-69AE-11D9-BED3-505054503030":["Application Generated","Object Access"], - "0CCE9223-69AE-11D9-BED3-505054503030":["Handle Manipulation","Object Access"], - "0CCE9224-69AE-11D9-BED3-505054503030":["File Share","Object Access"], - "0CCE9225-69AE-11D9-BED3-505054503030":["Filtering Platform Packet Drop","Object Access"], - "0CCE9226-69AE-11D9-BED3-505054503030":["Filtering Platform Connection ","Object Access"], - "0CCE9227-69AE-11D9-BED3-505054503030":["Other Object Access Events","Object Access"], - "0CCE9244-69AE-11D9-BED3-505054503030":["Detailed File Share","Object Access"], - "0CCE9245-69AE-11D9-BED3-505054503030":["Removable Storage","Object Access"], - "0CCE9246-69AE-11D9-BED3-505054503030":["Central Policy Staging","Object Access"], - "0CCE9228-69AE-11D9-BED3-505054503030":["Sensitive Privilege Use","Privilege Use"], - "0CCE9229-69AE-11D9-BED3-505054503030":["Non Sensitive Privilege Use","Privilege Use"], - "0CCE922A-69AE-11D9-BED3-505054503030":["Other Privilege Use Events","Privilege Use"], - "0CCE922B-69AE-11D9-BED3-505054503030":["Process Creation","Detailed Tracking"], - "0CCE922C-69AE-11D9-BED3-505054503030":["Process Termination","Detailed Tracking"], - "0CCE922D-69AE-11D9-BED3-505054503030":["DPAPI Activity","Detailed Tracking"], - "0CCE922E-69AE-11D9-BED3-505054503030":["RPC Events","Detailed Tracking"], - "0CCE9248-69AE-11D9-BED3-505054503030":["Plug and Play Events","Detailed Tracking"], - "0CCE922F-69AE-11D9-BED3-505054503030":["Audit Policy Change","Policy Change"], - "0CCE9230-69AE-11D9-BED3-505054503030":["Authentication Policy Change","Policy Change"], - "0CCE9231-69AE-11D9-BED3-505054503030":["Authorization Policy Change","Policy Change"], - "0CCE9232-69AE-11D9-BED3-505054503030":["MPSSVC Rule-Level Policy Change","Policy Change"], - "0CCE9233-69AE-11D9-BED3-505054503030":["Filtering Platform Policy Change","Policy Change"], - "0CCE9234-69AE-11D9-BED3-505054503030":["Other Policy Change Events","Policy Change"], - "0CCE9235-69AE-11D9-BED3-505054503030":["User Account Management","Account Management"], - "0CCE9236-69AE-11D9-BED3-505054503030":["Computer Account Management","Account Management"], - "0CCE9237-69AE-11D9-BED3-505054503030":["Security Group Management","Account Management"], - "0CCE9238-69AE-11D9-BED3-505054503030":["Distribution Group Management","Account Management"], - "0CCE9239-69AE-11D9-BED3-505054503030":["Application Group Management","Account Management"], - "0CCE923A-69AE-11D9-BED3-505054503030":["Other Account Management Events","Account Management"], - "0CCE923B-69AE-11D9-BED3-505054503030":["Directory Service Access","Account Management"], - "0CCE923C-69AE-11D9-BED3-505054503030":["Directory Service Changes","Account Management"], - "0CCE923D-69AE-11D9-BED3-505054503030":["Directory Service Replication","Account Management"], - "0CCE923E-69AE-11D9-BED3-505054503030":["Detailed Directory Service Replication","Account Management"], - "0CCE923F-69AE-11D9-BED3-505054503030":["Credential Validation","Account Logon"], - "0CCE9240-69AE-11D9-BED3-505054503030":["Kerberos Service Ticket Operations","Account Logon"], - "0CCE9241-69AE-11D9-BED3-505054503030":["Other Account Logon Events","Account Logon"], - "0CCE9242-69AE-11D9-BED3-505054503030":["Kerberos Authentication Service","Account Logon"], - }; - - - // Descriptions of failure status codes. - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4776 - var logonFailureStatus = { - "0xc000005e": "There are currently no logon servers available to service the logon request.", - "0xc0000064": "User logon with misspelled or bad user account", - "0xc000006a": "User logon with misspelled or bad password", - "0xc000006d": "This is either due to a bad username or authentication information", - "0xc000006e": "Unknown user name or bad password.", - "0xc000006f": "User logon outside authorized hours", - "0xc0000070": "User logon from unauthorized workstation", - "0xc0000071": "User logon with expired password", - "0xc0000072": "User logon to account disabled by administrator", - "0xc00000dc": "Indicates the Sam Server was in the wrong state to perform the desired operation.", - "0xc0000133": "Clocks between DC and other computer too far out of sync", - "0xc000015b": "The user has not been granted the requested logon type (aka logon right) at this machine", - "0xc000018c": "The logon request failed because the trust relationship between the primary domain and the trusted domain failed.", - "0xc0000192": "An attempt was made to logon, but the Netlogon service was not started.", - "0xc0000193": "User logon with expired account", - "0xc0000224": "User is required to change password at next logon", - "0xc0000225": "Evidently a bug in Windows and not a risk", - "0xc0000234": "User logon with account locked", - "0xc00002ee": "Failure Reason: An Error occurred during Logon", - "0xc0000413": "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine.", - "0xc0000371": "The local account store does not contain secret material for the specified account", - "0x0": "Status OK.", - }; - - // Message table extracted from msobjs.dll on Windows 2019. - // https://gist.github.com/andrewkroh/665dca0682bd0e4daf194ab291694012 - var msobjsMessageTable = { - "279": "Undefined Access (no effect) Bit 7", - "1536": "Unused message ID", - "1537": "DELETE", - "1538": "READ_CONTROL", - "1539": "WRITE_DAC", - "1540": "WRITE_OWNER", - "1541": "SYNCHRONIZE", - "1542": "ACCESS_SYS_SEC", - "1543": "MAX_ALLOWED", - "1552": "Unknown specific access (bit 0)", - "1553": "Unknown specific access (bit 1)", - "1554": "Unknown specific access (bit 2)", - "1555": "Unknown specific access (bit 3)", - "1556": "Unknown specific access (bit 4)", - "1557": "Unknown specific access (bit 5)", - "1558": "Unknown specific access (bit 6)", - "1559": "Unknown specific access (bit 7)", - "1560": "Unknown specific access (bit 8)", - "1561": "Unknown specific access (bit 9)", - "1562": "Unknown specific access (bit 10)", - "1563": "Unknown specific access (bit 11)", - "1564": "Unknown specific access (bit 12)", - "1565": "Unknown specific access (bit 13)", - "1566": "Unknown specific access (bit 14)", - "1567": "Unknown specific access (bit 15)", - "1601": "Not used", - "1603": "Assign Primary Token Privilege", - "1604": "Lock Memory Privilege", - "1605": "Increase Memory Quota Privilege", - "1606": "Unsolicited Input Privilege", - "1607": "Trusted Computer Base Privilege", - "1608": "Security Privilege", - "1609": "Take Ownership Privilege", - "1610": "Load/Unload Driver Privilege", - "1611": "Profile System Privilege", - "1612": "Set System Time Privilege", - "1613": "Profile Single Process Privilege", - "1614": "Increment Base Priority Privilege", - "1615": "Create Pagefile Privilege", - "1616": "Create Permanent Object Privilege", - "1617": "Backup Privilege", - "1618": "Restore From Backup Privilege", - "1619": "Shutdown System Privilege", - "1620": "Debug Privilege", - "1621": "View or Change Audit Log Privilege", - "1622": "Change Hardware Environment Privilege", - "1623": "Change Notify (and Traverse) Privilege", - "1624": "Remotely Shut System Down Privilege", - "1792": "", - "1794": "", - "1795": "Enabled", - "1796": "Disabled", - "1797": "All", - "1798": "None", - "1799": "Audit Policy query/set API Operation", - "1800": "", - "1801": "Granted by", - "1802": "Denied by", - "1803": "Denied by Integrity Policy check", - "1804": "Granted by Ownership", - "1805": "Not granted", - "1806": "Granted by NULL DACL", - "1807": "Denied by Empty DACL", - "1808": "Granted by NULL Security Descriptor", - "1809": "Unknown or unchecked", - "1810": "Not granted due to missing", - "1811": "Granted by ACE on parent folder", - "1812": "Denied by ACE on parent folder", - "1813": "Granted by Central Access Rule", - "1814": "NOT Granted by Central Access Rule", - "1815": "Granted by parent folder's Central Access Rule", - "1816": "NOT Granted by parent folder's Central Access Rule", - "1817": "Unknown Type", - "1818": "String", - "1819": "Unsigned 64-bit Integer", - "1820": "64-bit Integer", - "1821": "FQBN", - "1822": "Blob", - "1823": "Sid", - "1824": "Boolean", - "1825": "TRUE", - "1826": "FALSE", - "1827": "Invalid", - "1828": "an ACE too long to display", - "1829": "a Security Descriptor too long to display", - "1830": "Not granted to AppContainers", - "1831": "...", - "1832": "Identification", - "1833": "Impersonation", - "1840": "Delegation", - "1841": "Denied by Process Trust Label ACE", - "1842": "Yes", - "1843": "No", - "1844": "System", - "1845": "Not Available", - "1846": "Default", - "1847": "DisallowMmConfig", - "1848": "Off", - "1849": "Auto", - "1872": "REG_NONE", - "1873": "REG_SZ", - "1874": "REG_EXPAND_SZ", - "1875": "REG_BINARY", - "1876": "REG_DWORD", - "1877": "REG_DWORD_BIG_ENDIAN", - "1878": "REG_LINK", - "1879": "REG_MULTI_SZ (New lines are replaced with *. A * is replaced with **)", - "1880": "REG_RESOURCE_LIST", - "1881": "REG_FULL_RESOURCE_DESCRIPTOR", - "1882": "REG_RESOURCE_REQUIREMENTS_LIST", - "1883": "REG_QWORD", - "1904": "New registry value created", - "1905": "Existing registry value modified", - "1906": "Registry value deleted", - "1920": "Sunday", - "1921": "Monday", - "1922": "Tuesday", - "1923": "Wednesday", - "1924": "Thursday", - "1925": "Friday", - "1926": "Saturday", - "1936": "TokenElevationTypeDefault (1)", - "1937": "TokenElevationTypeFull (2)", - "1938": "TokenElevationTypeLimited (3)", - "2048": "Account Enabled", - "2049": "Home Directory Required' - Disabled", - "2050": "Password Not Required' - Disabled", - "2051": "Temp Duplicate Account' - Disabled", - "2052": "Normal Account' - Disabled", - "2053": "MNS Logon Account' - Disabled", - "2054": "Interdomain Trust Account' - Disabled", - "2055": "Workstation Trust Account' - Disabled", - "2056": "Server Trust Account' - Disabled", - "2057": "Don't Expire Password' - Disabled", - "2058": "Account Unlocked", - "2059": "Encrypted Text Password Allowed' - Disabled", - "2060": "Smartcard Required' - Disabled", - "2061": "Trusted For Delegation' - Disabled", - "2062": "Not Delegated' - Disabled", - "2063": "Use DES Key Only' - Disabled", - "2064": "Don't Require Preauth' - Disabled", - "2065": "Password Expired' - Disabled", - "2066": "Trusted To Authenticate For Delegation' - Disabled", - "2067": "Exclude Authorization Information' - Disabled", - "2068": "Undefined UserAccountControl Bit 20' - Disabled", - "2069": "Protect Kerberos Service Tickets with AES Keys' - Disabled", - "2070": "Undefined UserAccountControl Bit 22' - Disabled", - "2071": "Undefined UserAccountControl Bit 23' - Disabled", - "2072": "Undefined UserAccountControl Bit 24' - Disabled", - "2073": "Undefined UserAccountControl Bit 25' - Disabled", - "2074": "Undefined UserAccountControl Bit 26' - Disabled", - "2075": "Undefined UserAccountControl Bit 27' - Disabled", - "2076": "Undefined UserAccountControl Bit 28' - Disabled", - "2077": "Undefined UserAccountControl Bit 29' - Disabled", - "2078": "Undefined UserAccountControl Bit 30' - Disabled", - "2079": "Undefined UserAccountControl Bit 31' - Disabled", - "2080": "Account Disabled", - "2081": "Home Directory Required' - Enabled", - "2082": "Password Not Required' - Enabled", - "2083": "Temp Duplicate Account' - Enabled", - "2084": "Normal Account' - Enabled", - "2085": "MNS Logon Account' - Enabled", - "2086": "Interdomain Trust Account' - Enabled", - "2087": "Workstation Trust Account' - Enabled", - "2088": "Server Trust Account' - Enabled", - "2089": "Don't Expire Password' - Enabled", - "2090": "Account Locked", - "2091": "Encrypted Text Password Allowed' - Enabled", - "2092": "Smartcard Required' - Enabled", - "2093": "Trusted For Delegation' - Enabled", - "2094": "Not Delegated' - Enabled", - "2095": "Use DES Key Only' - Enabled", - "2096": "Don't Require Preauth' - Enabled", - "2097": "Password Expired' - Enabled", - "2098": "Trusted To Authenticate For Delegation' - Enabled", - "2099": "Exclude Authorization Information' - Enabled", - "2100": "Undefined UserAccountControl Bit 20' - Enabled", - "2101": "Protect Kerberos Service Tickets with AES Keys' - Enabled", - "2102": "Undefined UserAccountControl Bit 22' - Enabled", - "2103": "Undefined UserAccountControl Bit 23' - Enabled", - "2104": "Undefined UserAccountControl Bit 24' - Enabled", - "2105": "Undefined UserAccountControl Bit 25' - Enabled", - "2106": "Undefined UserAccountControl Bit 26' - Enabled", - "2107": "Undefined UserAccountControl Bit 27' - Enabled", - "2108": "Undefined UserAccountControl Bit 28' - Enabled", - "2109": "Undefined UserAccountControl Bit 29' - Enabled", - "2110": "Undefined UserAccountControl Bit 30' - Enabled", - "2111": "Undefined UserAccountControl Bit 31' - Enabled", - "2304": "An Error occured during Logon.", - "2305": "The specified user account has expired.", - "2306": "The NetLogon component is not active.", - "2307": "Account locked out.", - "2308": "The user has not been granted the requested logon type at this machine.", - "2309": "The specified account's password has expired.", - "2310": "Account currently disabled.", - "2311": "Account logon time restriction violation.", - "2312": "User not allowed to logon at this computer.", - "2313": "Unknown user name or bad password.", - "2314": "Domain sid inconsistent.", - "2315": "Smartcard logon is required and was not used.", - "2432": "Not Available.", - "2436": "Random number generator failure.", - "2437": "Random number generation failed FIPS-140 pre-hash check.", - "2438": "Failed to zero secret data.", - "2439": "Key failed pair wise consistency check.", - "2448": "Failed to unprotect persistent cryptographic key.", - "2449": "Key export checks failed.", - "2450": "Validation of public key failed.", - "2451": "Signature verification failed.", - "2456": "Open key file.", - "2457": "Delete key file.", - "2458": "Read persisted key from file.", - "2459": "Write persisted key to file.", - "2464": "Export of persistent cryptographic key.", - "2465": "Import of persistent cryptographic key.", - "2480": "Open Key.", - "2481": "Create Key.", - "2482": "Delete Key.", - "2483": "Encrypt.", - "2484": "Decrypt.", - "2485": "Sign hash.", - "2486": "Secret agreement.", - "2487": "Domain settings", - "2488": "Local settings", - "2489": "Add provider.", - "2490": "Remove provider.", - "2491": "Add context.", - "2492": "Remove context.", - "2493": "Add function.", - "2494": "Remove function.", - "2495": "Add function provider.", - "2496": "Remove function provider.", - "2497": "Add function property.", - "2498": "Remove function property.", - "2499": "Machine key.", - "2500": "User key.", - "2501": "Key Derivation.", - "4352": "Device Access Bit 0", - "4353": "Device Access Bit 1", - "4354": "Device Access Bit 2", - "4355": "Device Access Bit 3", - "4356": "Device Access Bit 4", - "4357": "Device Access Bit 5", - "4358": "Device Access Bit 6", - "4359": "Device Access Bit 7", - "4360": "Device Access Bit 8", - "4361": "Undefined Access (no effect) Bit 9", - "4362": "Undefined Access (no effect) Bit 10", - "4363": "Undefined Access (no effect) Bit 11", - "4364": "Undefined Access (no effect) Bit 12", - "4365": "Undefined Access (no effect) Bit 13", - "4366": "Undefined Access (no effect) Bit 14", - "4367": "Undefined Access (no effect) Bit 15", - "4368": "Query directory", - "4369": "Traverse", - "4370": "Create object in directory", - "4371": "Create sub-directory", - "4372": "Undefined Access (no effect) Bit 4", - "4373": "Undefined Access (no effect) Bit 5", - "4374": "Undefined Access (no effect) Bit 6", - "4375": "Undefined Access (no effect) Bit 7", - "4376": "Undefined Access (no effect) Bit 8", - "4377": "Undefined Access (no effect) Bit 9", - "4378": "Undefined Access (no effect) Bit 10", - "4379": "Undefined Access (no effect) Bit 11", - "4380": "Undefined Access (no effect) Bit 12", - "4381": "Undefined Access (no effect) Bit 13", - "4382": "Undefined Access (no effect) Bit 14", - "4383": "Undefined Access (no effect) Bit 15", - "4384": "Query event state", - "4385": "Modify event state", - "4386": "Undefined Access (no effect) Bit 2", - "4387": "Undefined Access (no effect) Bit 3", - "4388": "Undefined Access (no effect) Bit 4", - "4389": "Undefined Access (no effect) Bit 5", - "4390": "Undefined Access (no effect) Bit 6", - "4391": "Undefined Access (no effect) Bit 7", - "4392": "Undefined Access (no effect) Bit 8", - "4393": "Undefined Access (no effect) Bit 9", - "4394": "Undefined Access (no effect) Bit 10", - "4395": "Undefined Access (no effect) Bit 11", - "4396": "Undefined Access (no effect) Bit 12", - "4397": "Undefined Access (no effect) Bit 13", - "4398": "Undefined Access (no effect) Bit 14", - "4399": "Undefined Access (no effect) Bit 15", - "4416": "ReadData (or ListDirectory)", - "4417": "WriteData (or AddFile)", - "4418": "AppendData (or AddSubdirectory or CreatePipeInstance)", - "4419": "ReadEA", - "4420": "WriteEA", - "4421": "Execute/Traverse", - "4422": "DeleteChild", - "4423": "ReadAttributes", - "4424": "WriteAttributes", - "4425": "Undefined Access (no effect) Bit 9", - "4426": "Undefined Access (no effect) Bit 10", - "4427": "Undefined Access (no effect) Bit 11", - "4428": "Undefined Access (no effect) Bit 12", - "4429": "Undefined Access (no effect) Bit 13", - "4430": "Undefined Access (no effect) Bit 14", - "4431": "Undefined Access (no effect) Bit 15", - "4432": "Query key value", - "4433": "Set key value", - "4434": "Create sub-key", - "4435": "Enumerate sub-keys", - "4436": "Notify about changes to keys", - "4437": "Create Link", - "4438": "Undefined Access (no effect) Bit 6", - "4439": "Undefined Access (no effect) Bit 7", - "4440": "Enable 64(or 32) bit application to open 64 bit key", - "4441": "Enable 64(or 32) bit application to open 32 bit key", - "4442": "Undefined Access (no effect) Bit 10", - "4443": "Undefined Access (no effect) Bit 11", - "4444": "Undefined Access (no effect) Bit 12", - "4445": "Undefined Access (no effect) Bit 13", - "4446": "Undefined Access (no effect) Bit 14", - "4447": "Undefined Access (no effect) Bit 15", - "4448": "Query mutant state", - "4449": "Undefined Access (no effect) Bit 1", - "4450": "Undefined Access (no effect) Bit 2", - "4451": "Undefined Access (no effect) Bit 3", - "4452": "Undefined Access (no effect) Bit 4", - "4453": "Undefined Access (no effect) Bit 5", - "4454": "Undefined Access (no effect) Bit 6", - "4455": "Undefined Access (no effect) Bit 7", - "4456": "Undefined Access (no effect) Bit 8", - "4457": "Undefined Access (no effect) Bit 9", - "4458": "Undefined Access (no effect) Bit 10", - "4459": "Undefined Access (no effect) Bit 11", - "4460": "Undefined Access (no effect) Bit 12", - "4461": "Undefined Access (no effect) Bit 13", - "4462": "Undefined Access (no effect) Bit 14", - "4463": "Undefined Access (no effect) Bit 15", - "4464": "Communicate using port", - "4465": "Undefined Access (no effect) Bit 1", - "4466": "Undefined Access (no effect) Bit 2", - "4467": "Undefined Access (no effect) Bit 3", - "4468": "Undefined Access (no effect) Bit 4", - "4469": "Undefined Access (no effect) Bit 5", - "4470": "Undefined Access (no effect) Bit 6", - "4471": "Undefined Access (no effect) Bit 7", - "4472": "Undefined Access (no effect) Bit 8", - "4473": "Undefined Access (no effect) Bit 9", - "4474": "Undefined Access (no effect) Bit 10", - "4475": "Undefined Access (no effect) Bit 11", - "4476": "Undefined Access (no effect) Bit 12", - "4477": "Undefined Access (no effect) Bit 13", - "4478": "Undefined Access (no effect) Bit 14", - "4479": "Undefined Access (no effect) Bit 15", - "4480": "Force process termination", - "4481": "Create new thread in process", - "4482": "Set process session ID", - "4483": "Perform virtual memory operation", - "4484": "Read from process memory", - "4485": "Write to process memory", - "4486": "Duplicate handle into or out of process", - "4487": "Create a subprocess of process", - "4488": "Set process quotas", - "4489": "Set process information", - "4490": "Query process information", - "4491": "Set process termination port", - "4492": "Undefined Access (no effect) Bit 12", - "4493": "Undefined Access (no effect) Bit 13", - "4494": "Undefined Access (no effect) Bit 14", - "4495": "Undefined Access (no effect) Bit 15", - "4496": "Control profile", - "4497": "Undefined Access (no effect) Bit 1", - "4498": "Undefined Access (no effect) Bit 2", - "4499": "Undefined Access (no effect) Bit 3", - "4500": "Undefined Access (no effect) Bit 4", - "4501": "Undefined Access (no effect) Bit 5", - "4502": "Undefined Access (no effect) Bit 6", - "4503": "Undefined Access (no effect) Bit 7", - "4504": "Undefined Access (no effect) Bit 8", - "4505": "Undefined Access (no effect) Bit 9", - "4506": "Undefined Access (no effect) Bit 10", - "4507": "Undefined Access (no effect) Bit 11", - "4508": "Undefined Access (no effect) Bit 12", - "4509": "Undefined Access (no effect) Bit 13", - "4510": "Undefined Access (no effect) Bit 14", - "4511": "Undefined Access (no effect) Bit 15", - "4512": "Query section state", - "4513": "Map section for write", - "4514": "Map section for read", - "4515": "Map section for execute", - "4516": "Extend size", - "4517": "Undefined Access (no effect) Bit 5", - "4518": "Undefined Access (no effect) Bit 6", - "4519": "Undefined Access (no effect) Bit 7", - "4520": "Undefined Access (no effect) Bit 8", - "4521": "Undefined Access (no effect) Bit 9", - "4522": "Undefined Access (no effect) Bit 10", - "4523": "Undefined Access (no effect) Bit 11", - "4524": "Undefined Access (no effect) Bit 12", - "4525": "Undefined Access (no effect) Bit 13", - "4526": "Undefined Access (no effect) Bit 14", - "4527": "Undefined Access (no effect) Bit 15", - "4528": "Query semaphore state", - "4529": "Modify semaphore state", - "4530": "Undefined Access (no effect) Bit 2", - "4531": "Undefined Access (no effect) Bit 3", - "4532": "Undefined Access (no effect) Bit 4", - "4533": "Undefined Access (no effect) Bit 5", - "4534": "Undefined Access (no effect) Bit 6", - "4535": "Undefined Access (no effect) Bit 7", - "4536": "Undefined Access (no effect) Bit 8", - "4537": "Undefined Access (no effect) Bit 9", - "4538": "Undefined Access (no effect) Bit 10", - "4539": "Undefined Access (no effect) Bit 11", - "4540": "Undefined Access (no effect) Bit 12", - "4541": "Undefined Access (no effect) Bit 13", - "4542": "Undefined Access (no effect) Bit 14", - "4543": "Undefined Access (no effect) Bit 15", - "4544": "Use symbolic link", - "4545": "Undefined Access (no effect) Bit 1", - "4546": "Undefined Access (no effect) Bit 2", - "4547": "Undefined Access (no effect) Bit 3", - "4548": "Undefined Access (no effect) Bit 4", - "4549": "Undefined Access (no effect) Bit 5", - "4550": "Undefined Access (no effect) Bit 6", - "4551": "Undefined Access (no effect) Bit 7", - "4552": "Undefined Access (no effect) Bit 8", - "4553": "Undefined Access (no effect) Bit 9", - "4554": "Undefined Access (no effect) Bit 10", - "4555": "Undefined Access (no effect) Bit 11", - "4556": "Undefined Access (no effect) Bit 12", - "4557": "Undefined Access (no effect) Bit 13", - "4558": "Undefined Access (no effect) Bit 14", - "4559": "Undefined Access (no effect) Bit 15", - "4560": "Force thread termination", - "4561": "Suspend or resume thread", - "4562": "Send an alert to thread", - "4563": "Get thread context", - "4564": "Set thread context", - "4565": "Set thread information", - "4566": "Query thread information", - "4567": "Assign a token to the thread", - "4568": "Cause thread to directly impersonate another thread", - "4569": "Directly impersonate this thread", - "4570": "Undefined Access (no effect) Bit 10", - "4571": "Undefined Access (no effect) Bit 11", - "4572": "Undefined Access (no effect) Bit 12", - "4573": "Undefined Access (no effect) Bit 13", - "4574": "Undefined Access (no effect) Bit 14", - "4575": "Undefined Access (no effect) Bit 15", - "4576": "Query timer state", - "4577": "Modify timer state", - "4578": "Undefined Access (no effect) Bit 2", - "4579": "Undefined Access (no effect) Bit 3", - "4580": "Undefined Access (no effect) Bit 4", - "4581": "Undefined Access (no effect) Bit 5", - "4582": "Undefined Access (no effect) Bit 6", - "4584": "Undefined Access (no effect) Bit 8", - "4585": "Undefined Access (no effect) Bit 9", - "4586": "Undefined Access (no effect) Bit 10", - "4587": "Undefined Access (no effect) Bit 11", - "4588": "Undefined Access (no effect) Bit 12", - "4589": "Undefined Access (no effect) Bit 13", - "4590": "Undefined Access (no effect) Bit 14", - "4591": "Undefined Access (no effect) Bit 15", - "4592": "AssignAsPrimary", - "4593": "Duplicate", - "4594": "Impersonate", - "4595": "Query", - "4596": "QuerySource", - "4597": "AdjustPrivileges", - "4598": "AdjustGroups", - "4599": "AdjustDefaultDacl", - "4600": "AdjustSessionID", - "4601": "Undefined Access (no effect) Bit 9", - "4602": "Undefined Access (no effect) Bit 10", - "4603": "Undefined Access (no effect) Bit 11", - "4604": "Undefined Access (no effect) Bit 12", - "4605": "Undefined Access (no effect) Bit 13", - "4606": "Undefined Access (no effect) Bit 14", - "4607": "Undefined Access (no effect) Bit 15", - "4608": "Create instance of object type", - "4609": "Undefined Access (no effect) Bit 1", - "4610": "Undefined Access (no effect) Bit 2", - "4611": "Undefined Access (no effect) Bit 3", - "4612": "Undefined Access (no effect) Bit 4", - "4613": "Undefined Access (no effect) Bit 5", - "4614": "Undefined Access (no effect) Bit 6", - "4615": "Undefined Access (no effect) Bit 7", - "4616": "Undefined Access (no effect) Bit 8", - "4617": "Undefined Access (no effect) Bit 9", - "4618": "Undefined Access (no effect) Bit 10", - "4619": "Undefined Access (no effect) Bit 11", - "4620": "Undefined Access (no effect) Bit 12", - "4621": "Undefined Access (no effect) Bit 13", - "4622": "Undefined Access (no effect) Bit 14", - "4623": "Undefined Access (no effect) Bit 15", - "4864": "Query State", - "4865": "Modify State", - "5120": "Channel read message", - "5121": "Channel write message", - "5122": "Channel query information", - "5123": "Channel set information", - "5124": "Undefined Access (no effect) Bit 4", - "5125": "Undefined Access (no effect) Bit 5", - "5126": "Undefined Access (no effect) Bit 6", - "5127": "Undefined Access (no effect) Bit 7", - "5128": "Undefined Access (no effect) Bit 8", - "5129": "Undefined Access (no effect) Bit 9", - "5130": "Undefined Access (no effect) Bit 10", - "5131": "Undefined Access (no effect) Bit 11", - "5132": "Undefined Access (no effect) Bit 12", - "5133": "Undefined Access (no effect) Bit 13", - "5134": "Undefined Access (no effect) Bit 14", - "5135": "Undefined Access (no effect) Bit 15", - "5136": "Assign process", - "5137": "Set Attributes", - "5138": "Query Attributes", - "5139": "Terminate Job", - "5140": "Set Security Attributes", - "5141": "Undefined Access (no effect) Bit 5", - "5142": "Undefined Access (no effect) Bit 6", - "5143": "Undefined Access (no effect) Bit 7", - "5144": "Undefined Access (no effect) Bit 8", - "5145": "Undefined Access (no effect) Bit 9", - "5146": "Undefined Access (no effect) Bit 10", - "5147": "Undefined Access (no effect) Bit 11", - "5148": "Undefined Access (no effect) Bit 12", - "5149": "Undefined Access (no effect) Bit 13", - "5150": "Undefined Access (no effect) Bit 14", - "5151": "Undefined Access (no effect) Bit 15", - "5376": "ConnectToServer", - "5377": "ShutdownServer", - "5378": "InitializeServer", - "5379": "CreateDomain", - "5380": "EnumerateDomains", - "5381": "LookupDomain", - "5382": "Undefined Access (no effect) Bit 6", - "5383": "Undefined Access (no effect) Bit 7", - "5384": "Undefined Access (no effect) Bit 8", - "5385": "Undefined Access (no effect) Bit 9", - "5386": "Undefined Access (no effect) Bit 10", - "5387": "Undefined Access (no effect) Bit 11", - "5388": "Undefined Access (no effect) Bit 12", - "5389": "Undefined Access (no effect) Bit 13", - "5390": "Undefined Access (no effect) Bit 14", - "5391": "Undefined Access (no effect) Bit 15", - "5392": "ReadPasswordParameters", - "5393": "WritePasswordParameters", - "5394": "ReadOtherParameters", - "5395": "WriteOtherParameters", - "5396": "CreateUser", - "5397": "CreateGlobalGroup", - "5398": "CreateLocalGroup", - "5399": "GetLocalGroupMembership", - "5400": "ListAccounts", - "5401": "LookupIDs", - "5402": "AdministerServer", - "5403": "Undefined Access (no effect) Bit 11", - "5404": "Undefined Access (no effect) Bit 12", - "5405": "Undefined Access (no effect) Bit 13", - "5406": "Undefined Access (no effect) Bit 14", - "5407": "Undefined Access (no effect) Bit 15", - "5408": "ReadInformation", - "5409": "WriteAccount", - "5410": "AddMember", - "5411": "RemoveMember", - "5412": "ListMembers", - "5413": "Undefined Access (no effect) Bit 5", - "5414": "Undefined Access (no effect) Bit 6", - "5415": "Undefined Access (no effect) Bit 7", - "5416": "Undefined Access (no effect) Bit 8", - "5417": "Undefined Access (no effect) Bit 9", - "5418": "Undefined Access (no effect) Bit 10", - "5419": "Undefined Access (no effect) Bit 11", - "5420": "Undefined Access (no effect) Bit 12", - "5421": "Undefined Access (no effect) Bit 13", - "5422": "Undefined Access (no effect) Bit 14", - "5423": "Undefined Access (no effect) Bit 15", - "5424": "AddMember", - "5425": "RemoveMember", - "5426": "ListMembers", - "5427": "ReadInformation", - "5428": "WriteAccount", - "5429": "Undefined Access (no effect) Bit 5", - "5430": "Undefined Access (no effect) Bit 6", - "5431": "Undefined Access (no effect) Bit 7", - "5432": "Undefined Access (no effect) Bit 8", - "5433": "Undefined Access (no effect) Bit 9", - "5434": "Undefined Access (no effect) Bit 10", - "5435": "Undefined Access (no effect) Bit 11", - "5436": "Undefined Access (no effect) Bit 12", - "5437": "Undefined Access (no effect) Bit 13", - "5438": "Undefined Access (no effect) Bit 14", - "5439": "Undefined Access (no effect) Bit 15", - "5440": "ReadGeneralInformation", - "5441": "ReadPreferences", - "5442": "WritePreferences", - "5443": "ReadLogon", - "5444": "ReadAccount", - "5445": "WriteAccount", - "5446": "ChangePassword (with knowledge of old password)", - "5447": "SetPassword (without knowledge of old password)", - "5448": "ListGroups", - "5449": "ReadGroupMembership", - "5450": "ChangeGroupMembership", - "5451": "Undefined Access (no effect) Bit 11", - "5452": "Undefined Access (no effect) Bit 12", - "5453": "Undefined Access (no effect) Bit 13", - "5454": "Undefined Access (no effect) Bit 14", - "5455": "Undefined Access (no effect) Bit 15", - "5632": "View non-sensitive policy information", - "5633": "View system audit requirements", - "5634": "Get sensitive policy information", - "5635": "Modify domain trust relationships", - "5636": "Create special accounts (for assignment of user rights)", - "5637": "Create a secret object", - "5638": "Create a privilege", - "5639": "Set default quota limits", - "5640": "Change system audit requirements", - "5641": "Administer audit log attributes", - "5642": "Enable/Disable LSA", - "5643": "Lookup Names/SIDs", - "5648": "Change secret value", - "5649": "Query secret value", - "5650": "Undefined Access (no effect) Bit 2", - "5651": "Undefined Access (no effect) Bit 3", - "5652": "Undefined Access (no effect) Bit 4", - "5653": "Undefined Access (no effect) Bit 5", - "5654": "Undefined Access (no effect) Bit 6", - "5655": "Undefined Access (no effect) Bit 7", - "5656": "Undefined Access (no effect) Bit 8", - "5657": "Undefined Access (no effect) Bit 9", - "5658": "Undefined Access (no effect) Bit 10", - "5659": "Undefined Access (no effect) Bit 11", - "5660": "Undefined Access (no effect) Bit 12", - "5661": "Undefined Access (no effect) Bit 13", - "5662": "Undefined Access (no effect) Bit 14", - "5663": "Undefined Access (no effect) Bit 15", - "5664": "Query trusted domain name/SID", - "5665": "Retrieve the controllers in the trusted domain", - "5666": "Change the controllers in the trusted domain", - "5667": "Query the Posix ID offset assigned to the trusted domain", - "5668": "Change the Posix ID offset assigned to the trusted domain", - "5669": "Undefined Access (no effect) Bit 5", - "5670": "Undefined Access (no effect) Bit 6", - "5671": "Undefined Access (no effect) Bit 7", - "5672": "Undefined Access (no effect) Bit 8", - "5673": "Undefined Access (no effect) Bit 9", - "5674": "Undefined Access (no effect) Bit 10", - "5675": "Undefined Access (no effect) Bit 11", - "5676": "Undefined Access (no effect) Bit 12", - "5677": "Undefined Access (no effect) Bit 13", - "5678": "Undefined Access (no effect) Bit 14", - "5679": "Undefined Access (no effect) Bit 15", - "5680": "Query account information", - "5681": "Change privileges assigned to account", - "5682": "Change quotas assigned to account", - "5683": "Change logon capabilities assigned to account", - "5684": "Change the Posix ID offset assigned to the accounted domain", - "5685": "Undefined Access (no effect) Bit 5", - "5686": "Undefined Access (no effect) Bit 6", - "5687": "Undefined Access (no effect) Bit 7", - "5688": "Undefined Access (no effect) Bit 8", - "5689": "Undefined Access (no effect) Bit 9", - "5690": "Undefined Access (no effect) Bit 10", - "5691": "Undefined Access (no effect) Bit 11", - "5692": "Undefined Access (no effect) Bit 12", - "5693": "Undefined Access (no effect) Bit 13", - "5694": "Undefined Access (no effect) Bit 14", - "5695": "Undefined Access (no effect) Bit 15", - "5696": "KeyedEvent Wait", - "5697": "KeyedEvent Wake", - "5698": "Undefined Access (no effect) Bit 2", - "5699": "Undefined Access (no effect) Bit 3", - "5700": "Undefined Access (no effect) Bit 4", - "5701": "Undefined Access (no effect) Bit 5", - "5702": "Undefined Access (no effect) Bit 6", - "5703": "Undefined Access (no effect) Bit 7", - "5704": "Undefined Access (no effect) Bit 8", - "5705": "Undefined Access (no effect) Bit 9", - "5706": "Undefined Access (no effect) Bit 10", - "5707": "Undefined Access (no effect) Bit 11", - "5708": "Undefined Access (no effect) Bit 12", - "5709": "Undefined Access (no effect) Bit 13", - "5710": "Undefined Access (no effect) Bit 14", - "5711": "Undefined Access (no effect) Bit 15", - "6656": "Enumerate desktops", - "6657": "Read attributes", - "6658": "Access Clipboard", - "6659": "Create desktop", - "6660": "Write attributes", - "6661": "Access global atoms", - "6662": "Exit windows", - "6663": "Unused Access Flag", - "6664": "Include this windowstation in enumerations", - "6665": "Read screen", - "6672": "Read Objects", - "6673": "Create window", - "6674": "Create menu", - "6675": "Hook control", - "6676": "Journal (record)", - "6677": "Journal (playback)", - "6678": "Include this desktop in enumerations", - "6679": "Write objects", - "6680": "Switch to this desktop", - "6912": "Administer print server", - "6913": "Enumerate printers", - "6930": "Full Control", - "6931": "Print", - "6948": "Administer Document", - "7168": "Connect to service controller", - "7169": "Create a new service", - "7170": "Enumerate services", - "7171": "Lock service database for exclusive access", - "7172": "Query service database lock state", - "7173": "Set last-known-good state of service database", - "7184": "Query service configuration information", - "7185": "Set service configuration information", - "7186": "Query status of service", - "7187": "Enumerate dependencies of service", - "7188": "Start the service", - "7189": "Stop the service", - "7190": "Pause or continue the service", - "7191": "Query information from service", - "7192": "Issue service-specific control commands", - "7424": "DDE Share Read", - "7425": "DDE Share Write", - "7426": "DDE Share Initiate Static", - "7427": "DDE Share Initiate Link", - "7428": "DDE Share Request", - "7429": "DDE Share Advise", - "7430": "DDE Share Poke", - "7431": "DDE Share Execute", - "7432": "DDE Share Add Items", - "7433": "DDE Share List Items", - "7680": "Create Child", - "7681": "Delete Child", - "7682": "List Contents", - "7683": "Write Self", - "7684": "Read Property", - "7685": "Write Property", - "7686": "Delete Tree", - "7687": "List Object", - "7688": "Control Access", - "7689": "Undefined Access (no effect) Bit 9", - "7690": "Undefined Access (no effect) Bit 10", - "7691": "Undefined Access (no effect) Bit 11", - "7692": "Undefined Access (no effect) Bit 12", - "7693": "Undefined Access (no effect) Bit 13", - "7694": "Undefined Access (no effect) Bit 14", - "7695": "Undefined Access (no effect) Bit 15", - "7936": "Audit Set System Policy", - "7937": "Audit Query System Policy", - "7938": "Audit Set Per User Policy", - "7939": "Audit Query Per User Policy", - "7940": "Audit Enumerate Users", - "7941": "Audit Set Options", - "7942": "Audit Query Options", - "8064": "Port sharing (read)", - "8065": "Port sharing (write)", - "8096": "Default credentials", - "8097": "Credentials manager", - "8098": "Fresh credentials", - "8192": "Kerberos", - "8193": "Preshared key", - "8194": "Unknown authentication", - "8195": "DES", - "8196": "3DES", - "8197": "MD5", - "8198": "SHA1", - "8199": "Local computer", - "8200": "Remote computer", - "8201": "No state", - "8202": "Sent first (SA) payload", - "8203": "Sent second (KE) payload", - "8204": "Sent third (ID) payload", - "8205": "Initiator", - "8206": "Responder", - "8207": "No state", - "8208": "Sent first (SA) payload", - "8209": "Sent final payload", - "8210": "Complete", - "8211": "Unknown", - "8212": "Transport", - "8213": "Tunnel", - "8214": "IKE/AuthIP DoS prevention mode started", - "8215": "IKE/AuthIP DoS prevention mode stopped", - "8216": "Enabled", - "8217": "Not enabled", - "8218": "No state", - "8219": "Sent first (EM attributes) payload", - "8220": "Sent second (SSPI) payload", - "8221": "Sent third (hash) payload", - "8222": "IKEv1", - "8223": "AuthIP", - "8224": "Anonymous", - "8225": "NTLM V2", - "8226": "CGA", - "8227": "Certificate", - "8228": "SSL", - "8229": "None", - "8230": "DH group 1", - "8231": "DH group 2", - "8232": "DH group 14", - "8233": "DH group ECP 256", - "8234": "DH group ECP 384", - "8235": "AES-128", - "8236": "AES-192", - "8237": "AES-256", - "8238": "Certificate ECDSA P256", - "8239": "Certificate ECDSA P384", - "8240": "SSL ECDSA P256", - "8241": "SSL ECDSA P384", - "8242": "SHA 256", - "8243": "SHA 384", - "8244": "IKEv2", - "8245": "EAP payload sent", - "8246": "Authentication payload sent", - "8247": "EAP", - "8248": "DH group 24", - "8272": "System", - "8273": "Logon/Logoff", - "8274": "Object Access", - "8275": "Privilege Use", - "8276": "Detailed Tracking", - "8277": "Policy Change", - "8278": "Account Management", - "8279": "DS Access", - "8280": "Account Logon", - "8448": "Success removed", - "8449": "Success Added", - "8450": "Failure removed", - "8451": "Failure Added", - "8452": "Success include removed", - "8453": "Success include added", - "8454": "Success exclude removed", - "8455": "Success exclude added", - "8456": "Failure include removed", - "8457": "Failure include added", - "8458": "Failure exclude removed", - "8459": "Failure exclude added", - "12288": "Security State Change", - "12289": "Security System Extension", - "12290": "System Integrity", - "12291": "IPsec Driver", - "12292": "Other System Events", - "12544": "Logon", - "12545": "Logoff", - "12546": "Account Lockout", - "12547": "IPsec Main Mode", - "12548": "Special Logon", - "12549": "IPsec Quick Mode", - "12550": "IPsec Extended Mode", - "12551": "Other Logon/Logoff Events", - "12552": "Network Policy Server", - "12553": "User / Device Claims", - "12554": "Group Membership", - "12800": "File System", - "12801": "Registry", - "12802": "Kernel Object", - "12803": "SAM", - "12804": "Other Object Access Events", - "12805": "Certification Services", - "12806": "Application Generated", - "12807": "Handle Manipulation", - "12808": "File Share", - "12809": "Filtering Platform Packet Drop", - "12810": "Filtering Platform Connection", - "12811": "Detailed File Share", - "12812": "Removable Storage", - "12813": "Central Policy Staging", - "13056": "Sensitive Privilege Use", - "13057": "Non Sensitive Privilege Use", - "13058": "Other Privilege Use Events", - "13312": "Process Creation", - "13313": "Process Termination", - "13314": "DPAPI Activity", - "13315": "RPC Events", - "13316": "Plug and Play Events", - "13317": "Token Right Adjusted Events", - "13568": "Audit Policy Change", - "13569": "Authentication Policy Change", - "13570": "Authorization Policy Change", - "13571": "MPSSVC Rule-Level Policy Change", - "13572": "Filtering Platform Policy Change", - "13573": "Other Policy Change Events", - "13824": "User Account Management", - "13825": "Computer Account Management", - "13826": "Security Group Management", - "13827": "Distribution Group Management", - "13828": "Application Group Management", - "13829": "Other Account Management Events", - "14080": "Directory Service Access", - "14081": "Directory Service Changes", - "14082": "Directory Service Replication", - "14083": "Detailed Directory Service Replication", - "14336": "Credential Validation", - "14337": "Kerberos Service Ticket Operations", - "14338": "Other Account Logon Events", - "14339": "Kerberos Authentication Service", - "14592": "Inbound", - "14593": "Outbound", - "14594": "Forward", - "14595": "Bidirectional", - "14596": "IP Packet", - "14597": "Transport", - "14598": "Forward", - "14599": "Stream", - "14600": "Datagram Data", - "14601": "ICMP Error", - "14602": "MAC 802.3", - "14603": "MAC Native", - "14604": "vSwitch", - "14608": "Resource Assignment", - "14609": "Listen", - "14610": "Receive/Accept", - "14611": "Connect", - "14612": "Flow Established", - "14614": "Resource Release", - "14615": "Endpoint Closure", - "14616": "Connect Redirect", - "14617": "Bind Redirect", - "14624": "Stream Packet", - "14640": "ICMP Echo-Request", - "14641": "vSwitch Ingress", - "14642": "vSwitch Egress", - "14672": "", - "14673": "[NULL]", - "14674": "Value Added", - "14675": "Value Deleted", - "14676": "Active Directory Domain Services", - "14677": "Active Directory Lightweight Directory Services", - "14678": "Yes", - "14679": "No", - "14680": "Value Added With Expiration Time", - "14681": "Value Deleted With Expiration Time", - "14688": "Value Auto Deleted With Expiration Time", - "16384": "Add", - "16385": "Delete", - "16386": "Boot-time", - "16387": "Persistent", - "16388": "Not persistent", - "16389": "Block", - "16390": "Permit", - "16391": "Callout", - "16392": "MD5", - "16393": "SHA-1", - "16394": "SHA-256", - "16395": "AES-GCM 128", - "16396": "AES-GCM 192", - "16397": "AES-GCM 256", - "16398": "DES", - "16399": "3DES", - "16400": "AES-128", - "16401": "AES-192", - "16402": "AES-256", - "16403": "Transport", - "16404": "Tunnel", - "16405": "Responder", - "16406": "Initiator", - "16407": "AES-GMAC 128", - "16408": "AES-GMAC 192", - "16409": "AES-GMAC 256", - "16416": "AuthNoEncap Transport", - "16896": "Enable WMI Account", - "16897": "Execute Method", - "16898": "Full Write", - "16899": "Partial Write", - "16900": "Provider Write", - "16901": "Remote Access", - "16902": "Subscribe", - "16903": "Publish", - }; - - // Trust Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustTypes = { - "1": "TRUST_TYPE_DOWNLEVEL", - "2": "TRUST_TYPE_UPLEVEL", - "3": "TRUST_TYPE_MIT", - "4": "TRUST_TYPE_DCE" - } - - // Trust Direction - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustDirection = { - "0": "TRUST_DIRECTION_DISABLED", - "1": "TRUST_DIRECTION_INBOUND", - "2": "TRUST_DIRECTION_OUTBOUND", - "3": "TRUST_DIRECTION_BIDIRECTIONAL" - } - - // Trust Attributes - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustAttributes = { - "0": "UNDEFINED", - "1": "TRUST_ATTRIBUTE_NON_TRANSITIVE", - "2": "TRUST_ATTRIBUTE_UPLEVEL_ONLY", - "4": "TRUST_ATTRIBUTE_QUARANTINED_DOMAIN", - "8": "TRUST_ATTRIBUTE_FOREST_TRANSITIVE", - "16": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION", - "32": "TRUST_ATTRIBUTE_WITHIN_FOREST", - "64": "TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL", - "128": "TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION", - "512": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION_NO_TGT_DELEGATION", - "1024": "TRUST_ATTRIBUTE_PIM_TRUST" - } - - // SDDL Ace Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 - // https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 - var aceTypes = { - "A": "Access Allowed", - "D": "Access Denied", - "OA": "Object Access Allowed", - "OD": "Object Access Denied", - "AU": "System Audit", - "AL": "System Alarm", - "OU": "System Object Audit", - "OL": "System Object Alarm", - "ML": "System Mandatory Label", - "SP": "Central Policy ID" - } - - // SDDL Permissions - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 - var permissionDescription = { - "GA": "Generic All", - "GR": "Generic Read", - "GW": "Generic Write", - "GX": "Generic Execute", - "RC": "Read Permissions", - "SD": "Delete", - "WD": "Modify Permissions", - "WO": "Modify Owner", - "RP": "Read All Properties", - "WP": "Write All Properties", - "CC": "Create All Child Objects", - "DC": "Delete All Child Objects", - "LC": "List Contents", - "SW": "All Validated", - "LO": "List Object", - "DT": "Delete Subtree", - "CR": "All Extended Rights", - "FA": "File All Access", - "FR": "File Generic Read", - "FX": "FILE GENERIC EXECUTE", - "FW": "FILE GENERIC WRITE", - "KA": "KEY ALL ACCESS", - "KR": "KEY READ", - "KW": "KEY WRITE", - "KX": "KEY EXECUTE" - } - - // Known SIDs - // https://support.microsoft.com/en-au/help/243330/well-known-security-identifier"S-in-window"S-operating-systems - // https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings - var accountSIDDescription = { - "AO": "Account operators", - "RU": "Alias to allow previous Windows 2000", - "AN": "Anonymous logon", - "AU": "Authenticated users", - "BA": "Built-in administrators", - "BG": "Built-in guests", - "BO": "Backup operators", - "BU": "Built-in users", - "CA": "Certificate server administrators", - "CG": "Creator group", - "CO": "Creator owner", - "DA": "Domain administrators", - "DC": "Domain computers", - "DD": "Domain controllers", - "DG": "Domain guests", - "DU": "Domain users", - "EA": "Enterprise administrators", - "ED": "Enterprise domain controllers", - "WD": "Everyone", - "PA": "Group Policy administrators", - "IU": "Interactively logged-on user", - "LA": "Local administrator", - "LG": "Local guest", - "LS": "Local service account", - "SY": "Local system", - "NU": "Network logon user", - "NO": "Network configuration operators", - "NS": "Network service account", - "PO": "Printer operators", - "PS": "Personal self", - "PU": "Power users", - "RS": "RAS servers group", - "RD": "Terminal server users", - "RE": "Replicator", - "RC": "Restricted code", - "SA": "Schema administrators", - "SO": "Server operators", - "SU": "Service logon user", - "S-1-0": "Null Authority", - "S-1-0-0": "Nobody", - "S-1-1": "World Authority", - "S-1-1-0": "Everyone", - "S-1-16-0": "Untrusted Mandatory Level", - "S-1-16-12288": "High Mandatory Level", - "S-1-16-16384": "System Mandatory Level", - "S-1-16-20480": "Protected Process Mandatory Level", - "S-1-16-28672": "Secure Process Mandatory Level", - "S-1-16-4096": "Low Mandatory Level", - "S-1-16-8192": "Medium Mandatory Level", - "S-1-16-8448": "Medium Plus Mandatory Level", - "S-1-2": "Local Authority", - "S-1-2-0": "Local", - "S-1-2-1": "Console Logon", - "S-1-3": "Creator Authority", - "S-1-3-0": "Creator Owner", - "S-1-3-1": "Creator Group", - "S-1-3-2": "Creator Owner Server", - "S-1-3-3": "Creator Group Server", - "S-1-3-4": "Owner Rights", - "S-1-4": "Non-unique Authority", - "S-1-5": "NT Authority", - "S-1-5-1": "Dialup", - "S-1-5-10": "Principal Self", - "S-1-5-11": "Authenticated Users", - "S-1-5-12": "Restricted Code", - "S-1-5-13": "Terminal Server Users", - "S-1-5-14": "Remote Interactive Logon", - "S-1-5-15": "This Organization", - "S-1-5-17": "This Organization", - "S-1-5-18": "Local System", - "S-1-5-19": "NT Authority", - "S-1-5-2": "Network", - "S-1-5-20": "NT Authority", - "S-1-5-3": "Batch", - "S-1-5-32-544": "Administrators", - "S-1-5-32-545": "Users", - "S-1-5-32-546": "Guests", - "S-1-5-32-547": "Power Users", - "S-1-5-32-548": "Account Operators", - "S-1-5-32-549": "Server Operators", - "S-1-5-32-550": "Print Operators", - "S-1-5-32-551": "Backup Operators", - "S-1-5-32-552": "Replicators", - "S-1-5-32-554": "Builtin\Pre-Windows 2000 Compatible Access", - "S-1-5-32-555": "Builtin\Remote Desktop Users", - "S-1-5-32-556": "Builtin\Network Configuration Operators", - "S-1-5-32-557": "Builtin\Incoming Forest Trust Builders", - "S-1-5-32-558": "Builtin\Performance Monitor Users", - "S-1-5-32-559": "Builtin\Performance Log Users", - "S-1-5-32-560": "Builtin\Windows Authorization Access Group", - "S-1-5-32-561": "Builtin\Terminal Server License Servers", - "S-1-5-32-562": "Builtin\Distributed COM Users", - "S-1-5-32-569": "Builtin\Cryptographic Operators", - "S-1-5-32-573": "Builtin\Event Log Readers", - "S-1-5-32-574": "Builtin\Certificate Service DCOM Access", - "S-1-5-32-575": "Builtin\RDS Remote Access Servers", - "S-1-5-32-576": "Builtin\RDS Endpoint Servers", - "S-1-5-32-577": "Builtin\RDS Management Servers", - "S-1-5-32-578": "Builtin\Hyper-V Administrators", - "S-1-5-32-579": "Builtin\Access Control Assistance Operators", - "S-1-5-32-580": "Builtin\Remote Management Users", - "S-1-5-32-582": "Storage Replica Administrators", - "S-1-5-4": "Interactive", - "S-1-5-5-X-Y": "Logon Session", - "S-1-5-6": "Service", - "S-1-5-64-10": "NTLM Authentication", - "S-1-5-64-14": "SChannel Authentication", - "S-1-5-64-21": "Digest Authentication", - "S-1-5-7": "Anonymous", - "S-1-5-8": "Proxy", - "S-1-5-80": "NT Service", - "S-1-5-80-0": "All Services", - "S-1-5-83-0": "NT Virtual Machine\Virtual Machines", - "S-1-5-9": "Enterprise Domain Controllers", - "S-1-5-90-0": "Windows Manager\Windows Manager Group" - } - - // Domain-specific SIDs - // https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems - var domainSpecificSID = { - "498": "Enterprise Read-only Domain Controllers", - "500": "Administrator", - "501": "Guest", - "502": "KRBTGT", - "512": "Domain Admins", - "513": "Domain Users", - "514": "Domain Guests", - "515": "Domain Computers", - "516": "Domain Controllers", - "517": "Cert Publishers", - "518": "Schema Admins", - "519": "Enterprise Admins", - "520": "Group Policy Creator Owners", - "521": "Read-only Domain Controllers", - "522": "Cloneable Domain Controllers", - "526": "Key Admins", - "527": "Enterprise Key Admins", - "553": "RAS and IAS Servers", - "571": "Allowed RODC Password Replication Group", - "572": "Denied RODC Password Replication Group" - } - - // Object Permission Flags - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b - var permsFlags = [ - [0x80000000, 'Generic Read'], - [0x4000000, 'Generic Write'], - [0x20000000, 'Generic Execute'], - [0x10000000, 'Generic All'], - [0x02000000, 'Maximun Allowed'], - [0x01000000, 'Access System Security'], - [0x00100000, 'Syncronize'], - [0x00080000, 'Write Owner'], - [0x00040000, 'Write DACL'], - [0x00020000, 'Read Control'], - [0x00010000, 'Delete'] - ]; - - // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks - var accessMaskDescriptions = [ - [0x00000001, 'Create Child'], - [0x00000002, 'Delete Child'], - [0x00000004, 'List Contents'], - [0x00000008, 'SELF'], - [0x00000010, 'Read Property'], - [0x00000020, 'Write Property'], - [0x00000040, 'Delete Treee'], - [0x00000080, 'List Object'], - [0x00000100, 'Control Access'], - [0x00010000, 'DELETE'], - [0x00020000, 'READ_CONTROL'], - [0x00040000, 'WRITE_DAC'], - [0x00080000, 'WRITE_OWNER'], - [0x00100000, 'SYNCHRONIZE'], - [0x00F00000, 'STANDARD_RIGHTS_REQUIRED'], - [0x001F0000, 'STANDARD_RIGHTS_ALL'], - [0x0000FFFF, 'SPECIFIC_RIGHTS_ALL'], - [0x01000000, 'ADS_RIGHT_ACCESS_SYSTEM_SECURITY'], - [0x10000000, 'ADS_RIGHT_GENERIC_ALL'], - [0x20000000, 'ADS_RIGHT_GENERIC_EXECUTE'], - [0x40000000, 'ADS_RIGHT_GENERIC_WRITE'], - [0x80000000, 'ADS_RIGHT_GENERIC_READ'] - ]; - - // lookupMessageCode returns the string associated with the code. key should - // be the name of the field in evt containing the code (e.g. %%2313). - var lookupMessageCode = function (evt, key) { - var code = evt.Get(key); - if (!code) { - return; - } - code = code.replace("%%", ""); - return msobjsMessageTable[code]; - }; - - var addEventFields = function(evt){ - var code = evt.Get("event.code"); - if (!code) { - return; - } - var eventActionDescription = eventActionTypes[code][2]; - if (eventActionDescription) { - evt.Put("event.category", eventActionTypes[code][0]); - evt.Put("event.type", eventActionTypes[code][1]); - evt.Put("event.action", eventActionTypes[code][2]); - } - }; - - var addLogonType = function(evt) { - var code = evt.Get("winlog.event_data.LogonType"); - if (!code) { - return; - } - var descriptiveLogonType = logonTypes[code]; - if (descriptiveLogonType === undefined) { - return; - } - evt.Put("winlog.logon.type", descriptiveLogonType); - }; - - var addFailureCode = function(evt) { - var msg = lookupMessageCode(evt, "winlog.event_data.FailureReason"); - if (!msg) { - return; - } - evt.Put("winlog.logon.failure.reason", msg); - }; - - var addFailureStatus = function(evt) { - var code = evt.Get("winlog.event_data.Status"); - if (!code) { - return; - } - var descriptiveFailureStatus = logonFailureStatus[code]; - if (descriptiveFailureStatus === undefined) { - return; - } - evt.Put("winlog.logon.failure.status", descriptiveFailureStatus); - }; - - var addFailureSubStatus = function(evt) { - var code = evt.Get("winlog.event_data.SubStatus"); - if (!code) { - return; - } - var descriptiveFailureStatus = logonFailureStatus[code]; - if (descriptiveFailureStatus === undefined) { - return; - } - evt.Put("winlog.logon.failure.sub_status", descriptiveFailureStatus); - }; - - var addUACDescription = function(evt) { - var code = evt.Get("winlog.event_data.NewUacValue"); - if (!code) { - return; - } - var uacCode = parseInt(code); - var uacResult = []; - for (var i = 0; i < uacFlags.length; i++) { - if ((uacCode | uacFlags[i][0]) === uacCode) { - uacResult.push(uacFlags[i][1]); - } - } - if (uacResult) { - evt.Put("winlog.event_data.NewUACList", uacResult); - } - var uacList = evt.Get("winlog.event_data.UserAccountControl").replace(/\s/g, '').split("%%").filter(String); - if (!uacList) { - return; - } - evt.Put("winlog.event_data.UserAccountControl", uacList); - }; - - var addAuditInfo = function(evt) { - var subcategoryGuid = evt.Get("winlog.event_data.SubcategoryGuid").replace("{", '').replace("}", '').toUpperCase(); - if (!subcategoryGuid) { - return; - } - if (!auditDescription[subcategoryGuid]) { - return; - } - evt.Put("winlog.event_data.Category", auditDescription[subcategoryGuid][1]); - evt.Put("winlog.event_data.SubCategory", auditDescription[subcategoryGuid][0]); - var codedActions = evt.Get("winlog.event_data.AuditPolicyChanges").split(","); - var actionResults = []; - for (var j = 0; j < codedActions.length; j++) { - var actionCode = codedActions[j].replace("%%", '').replace(' ', ''); - actionResults.push(msobjsMessageTable[actionCode]); - } - evt.Put("winlog.event_data.AuditPolicyChangesDescription", actionResults); - }; - - var addTicketOptionsDescription = function(evt) { - var code = evt.Get("winlog.event_data.TicketOptions"); - if (!code) { - return; - } - var tktCode = parseInt(code, 16).toString(2); - var tktResult = []; - var tktCodeLen = tktCode.length; - for (var i = tktCodeLen; i >= 0; i--) { - if (tktCode[i] == 1) { - tktResult.push(ticketOptions[(32-tktCodeLen)+i]); - } - } - if (tktResult) { - evt.Put("winlog.event_data.TicketOptionsDescription", tktResult); - } - }; - - var addTicketEncryptionType = function(evt) { - var code = evt.Get("winlog.event_data.TicketEncryptionType"); - if (!code) { - return; - } - var encTypeCode = code.toLowerCase(); - evt.Put("winlog.event_data.TicketEncryptionTypeDescription", ticketEncryptionTypes[encTypeCode]); - }; - - var addTicketStatus = function(evt) { - var code = evt.Get("winlog.event_data.Status"); - if (!code) { - return; - } - evt.Put("winlog.event_data.StatusDescription", kerberosTktStatusCodes[code]); - }; - - var translateSID = function(sid){ - var translatedSID = accountSIDDescription[sid]; - if (translatedSID == undefined) { - if (/^S\-1\-5\-21/.test(sid)) { - var uid = sid.match(/[0-9]{1,5}$/g); - if (uid) { - translatedSID = domainSpecificSID[uid]; - } - } - } - if (translatedSID == undefined) { - translatedSID = sid; - } - return translatedSID; - } - - var translatePermissionMask = function(mask) { - if (!mask) { - return; - } - var permCode = parseInt(mask); - var permResult = []; - for (var i = 0; i < permsFlags.length; i++) { - if ((permCode | permsFlags[i][0]) === permCode) { - permResult.push(permsFlags[i][1]); - } - } - if (permResult) { - return permResult; - } else { - return mask; - } - }; - - var translateACL = function(dacl) { - var aceArray = dacl.split(";"); - var aceResult = []; - var aceType = aceArray[0]; - var acePerm = aceArray[2]; - var aceTrustedSid = aceArray[5]; - if (aceTrustedSid) { - aceResult['grantee'] = translateSID(aceTrustedSid); - } - if (aceType) { - aceResult['type'] = aceTypes[aceType]; - } - if (acePerm) { - if (/^0x/.test(acePerm)) { - var perms = translatePermissionMask(acePerm); - } - else { - var perms = [] - var permPairs = acePerm.match(/.{1,2}/g); - for ( var i = 0; i < permPairs.length; i ++) { - perms.push(permissionDescription[permPairs[i]]) - } - } - aceResult['perms'] = perms; - } - return aceResult; - }; - - var enrichSDDL = function(evt, sddl) { - var sddlStr = evt.Get(sddl); - if (!sddlStr) { - return; - } - var sdOwner = sddlStr.match(/^O\:[A-Z]{2}/g); - var sdGroup = sddlStr.match(/^G\:[A-Z]{2}/g); - var sdDacl = sddlStr.match(/(D:([A-Z]*(\(.*\))*))/g); - var sdSacl = sddlStr.match(/(S:([A-Z]*(\(.*\))*))?$/g); - if (sdOwner) { - evt.Put(sddl+"Owner", translateSID(sdOwner)); - } - if (sdGroup) { - evt.Put(sddl+"Group", translateSID(sdGroup)); - } - if (sdDacl) { - // Split each entry of the DACL - var daclList = (sdDacl[0]).match(/\([^*\)]*\)/g); - if (daclList) { - for (var i = 0; i < daclList.length; i++) { - var newDacl = translateACL(daclList[i].replace("(", '').replace(")", '')); - evt.Put(sddl+"Dacl"+i, newDacl['grantee']+" :"+newDacl['type']+" ("+newDacl['perms']+")"); - if ( newDacl['grantee'] === "Administrator" || newDacl['grantee'] === "Guest" || newDacl['grantee'] === "KRBTGT" ) { - evt.AppendTo('related.user', newDacl['grantee']); - } - } - } - } - if (sdSacl) { - // Split each entry of the SACL - var saclList = (sdSacl[0]).match(/\([^*\)]*\)/g); - if (saclList) { - for (var i = 0; i < saclList.length; i++) { - var newSacl = translateACL(saclList[i].replace("(", '').replace(")", '')); - evt.Put(sddl+"Sacl"+i, newSacl['grantee']+" :"+newSacl['type']+" ("+newSacl['perms']+")"); - if ( newSacl['grantee'] === "Administrator" || newSacl['grantee'] === "Guest" || newSacl['grantee'] === "KRBTGT" ) { - evt.AppendTo('related.user', newSacl['grantee']); - } - } - } - } - }; - - var translateAccessMask = function(mask) { - if (!mask) { - return; - } - var accessCode = parseInt(mask); - var accessResult = []; - for (var i = 0; i < accessMaskDescriptions.length; i++) { - if ((accessCode | accessMaskDescriptions[i][0]) === accessCode) { - accessResult.push(accessMaskDescriptions[i][1]); - } - } - if (accessResult) { - return accessResult; - } - }; - - var addSessionData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.AccountName", to: "user.name"}, - {from: "winlog.event_data.AccountDomain", to: "user.domain"}, - {from: "winlog.event_data.ClientAddress", to: "source.ip", type: "ip"}, - {from: "winlog.event_data.ClientName", to: "source.domain"}, - {from: "winlog.event_data.LogonID", to: "winlog.logon.id"}, - ], - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.AccountName"); - evt.AppendTo('related.user', user); - }) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - evt.Put('related.ip', ip); - } - }) - .Build(); - - var addServiceFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.ServiceName", to: "service.name"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var code = evt.Get("winlog.event_data.ServiceType"); - if (!code) { - return; - } - evt.Put("service.type", serviceTypes[code]); - }) - .Build(); - - var addTrustInformation = new processor.Chain() - .Add(function(evt) { - var code = evt.Get("winlog.event_data.TdoType"); - if (!code) { - return; - } - evt.Put("winlog.trustType", trustTypes[code]); - code = evt.Get("winlog.event_data.TdoDirection"); - if (!code) { - return; - } - evt.Put("winlog.trustDirection", trustDirection[code]); - code = evt.Get("winlog.event_data.TdoAttributes"); - if (!code) { - return; - } - evt.Put("winlog.trustAttribute", trustAttributes[code]); - - }) - .Build(); - - var copyTargetUser = function(evt) { - var targetUserId = evt.Get("winlog.event_data.TargetUserSid"); - if (!targetUserId) targetUserId = evt.Get("winlog.event_data.TargetSid"); - if (targetUserId) { - if (evt.Get("user.id")) evt.Put("user.target.id", targetUserId); - else evt.Put("user.id", targetUserId); - } - var targetUserName = evt.Get("winlog.event_data.TargetUserName"); - if (targetUserName) { - if (targetUserName.indexOf('@')>0) { - targetUserName = targetUserName.split('@')[0]; - } - - evt.AppendTo("related.user", targetUserName); - if (evt.Get("user.name")) evt.Put("user.target.name", targetUserName); - else evt.Put("user.name", targetUserName); - } - - var targetUserDomain = evt.Get("winlog.event_data.TargetDomainName"); - if (targetUserDomain) { - if (evt.Get("user.domain")) evt.Put("user.target.domain", targetUserDomain); - else evt.Put("user.domain", targetUserDomain); - } - } - - var removeIfEmptyOrHyphen = function(evt, key) { - var val = evt.Get(key); - if (!val || val === "-") { - evt.Delete(key); - return true; - } - return false; - } - - var copyTargetUserToEffective = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetUserSid", to: "user.effective.id"}, - {from: "winlog.event_data.TargetUserName", to: "user.effective.name"}, - {from: "winlog.event_data.TargetDomainName", to: "user.effective.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.TargetUserName"); - if (user) { - if (user.indexOf('@')>0) { - user = user.split('@')[0]; - evt.Put('user.effective.name', user); - } - } - }) - .Add(function(evt) { - if (!removeIfEmptyOrHyphen(evt, "user.effective.name")) { - evt.AppendTo("related.user", evt.Get("user.effective.name")); - } - removeIfEmptyOrHyphen(evt, "user.effective.domain"); - removeIfEmptyOrHyphen(evt, "user.effective.id"); - }) - .Build(); - - var copyTargetUserToTarget = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetSid", to: "user.target.id"}, - {from: "winlog.event_data.TargetUserName", to: "user.target.name"}, - {from: "winlog.event_data.TargetDomainName", to: "user.target.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.TargetUserName"); - if (user) { - if (user.indexOf('@')>0) { - user = user.split('@')[0]; - evt.Put('user.target.name', user); - } - evt.AppendTo('related.user', user); - } - }) - .Add(function(evt) { - if (!removeIfEmptyOrHyphen(evt, "user.target.name")) { - evt.AppendTo("related.user", evt.Get("user.target.name")); - } - removeIfEmptyOrHyphen(evt, "user.target.domain"); - removeIfEmptyOrHyphen(evt, "user.target.id"); - }) - .Build(); - - - var copyMemberToUser = function(evt) { - var member = evt.Get("winlog.event_data.MemberName"); - if (!member) { - return; - } - - var userName = member.split(',')[0].replace('CN=', '').replace('cn=', ''); - - evt.AppendTo("related.user", userName); - evt.Put("user.target.name", userName); - - var domainName = member.split(',')[3]; - if (domainName) { - evt.Put("user.target.domain", domainName.replace('DC=', '').replace('dc=', '')); - } - } - - var copyTargetUserToGroup = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetUserSid", to: "group.id"}, - {from: "winlog.event_data.TargetSid", to: "group.id"}, - {from: "winlog.event_data.TargetUserName", to: "group.name"}, - {from: "winlog.event_data.TargetDomainName", to: "group.domain"}, - ], - ignore_missing: true, - }).Add(function(evt) { - if (!evt.Get("user.target")) return; - evt.Put("user.target.group.id", evt.Get("group.id")); - evt.Put("user.target.group.name", evt.Get("group.name")); - evt.Put("user.target.group.domain", evt.Get("group.domain")); - }) - .Build(); - - var copyTargetUserToComputerObject = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetSid", to: "winlog.computerObject.id"}, - {from: "winlog.event_data.TargetUserName", to: "winlog.computerObject.name"}, - {from: "winlog.event_data.TargetDomainName", to: "winlog.computerObject.domain"}, - ], - ignore_missing: true, - }) - .Build(); - - var copyTargetUserLogonId = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var copySubjectUser = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.SubjectUserSid", to: "user.id"}, - {from: "winlog.event_data.SubjectUserName", to: "user.name"}, - {from: "winlog.event_data.SubjectDomainName", to: "user.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - evt.AppendTo('related.user', user); - }) - .Build(); - - var copySubjectUserFromUserData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.user_data.SubjectUserSid", to: "user.id"}, - {from: "winlog.user_data.SubjectUserName", to: "user.name"}, - {from: "winlog.user_data.SubjectDomainName", to: "user.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.user_data.SubjectUserName"); - evt.AppendTo('related.user', user); - }) - .Build(); - - var copySubjectUserLogonId = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.SubjectLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var copySubjectUserLogonIdFromUserData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.user_data.SubjectLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var renameCommonAuthFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.ProcessId", to: "process.pid", type: "long"}, - {from: "winlog.event_data.ProcessName", to: "process.executable"}, - {from: "winlog.event_data.IpAddress", to: "source.ip", type: "ip"}, - {from: "winlog.event_data.IpPort", to: "source.port", type: "long"}, - {from: "winlog.event_data.WorkstationName", to: "source.domain"}, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var name = evt.Get("process.name"); - if (name) { - return; - } - var exe = evt.Get("process.executable"); - if (!exe) { - return; - } - evt.Put("process.name", path.basename(exe)); - }) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - evt.Put('related.ip', ip); - } - }) - .Build(); - - var renameNewProcessFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.NewProcessId", to: "process.pid", type: "long"}, - {from: "winlog.event_data.NewProcessName", to: "process.executable"}, - {from: "winlog.event_data.ParentProcessName", to: "process.parent.executable"} - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var name = evt.Get("process.name"); - if (name) { - return; - } - var exe = evt.Get("process.executable"); - if (!exe) { - return; - } - evt.Put("process.name", path.basename(exe)); - }) - .Add(function(evt) { - var name = evt.Get("process.parent.name"); - if (name) { - return; - } - var exe = evt.Get("process.parent.executable"); - if (!exe) { - return; - } - evt.Put("process.parent.name", path.basename(exe)); - }) - .Add(function(evt) { - var cl = evt.Get("winlog.event_data.CommandLine"); - if (!cl) { - return; - } - evt.Put("process.args", windows.splitCommandLine(cl)); - evt.Put("process.command_line", cl); - }) - .Build(); - - // Handles 4634 and 4647. - var logoff = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addLogonType) - .Add(addEventFields) - .Build(); - - // Handles both 4624 - var logonSuccess = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addLogonType) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - if (user) { - var res = /^-$/.test(user); - if (!res) { - evt.AppendTo('related.user', user); - } - } - }) - .Build(); - - // Handles both 4648 - var event4648 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(copyTargetUserToEffective) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - if (user) { - var res = /^-$/.test(user); - if (!res) { - evt.AppendTo('related.user', user); - } - } - }) - .Build(); - - var event4625 = new processor.Chain() - .Add(copyTargetUser) - .Add(copySubjectUserLogonId) - .Add(addLogonType) - .Add(addFailureCode) - .Add(addFailureStatus) - .Add(addFailureSubStatus) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var event4672 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Add(addEventFields) - .Build(); - - var event4688 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameNewProcessFields) - .Add(copyTargetUserToEffective) - .Add(addEventFields) - .Build(); - - var event4689 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var event4697 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addServiceFields) - .Add(addEventFields) - .Build(); - - var userMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addUACDescription) - .Add(addEventFields) - .Add(copyTargetUserToTarget) - .Build(); - - var userRenamed = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Add(function(evt) { - var userNew = evt.Get("winlog.event_data.NewTargetUserName"); - evt.AppendTo('related.user', userNew); - var userOld = evt.Get("winlog.event_data.OldTargetUserName"); - evt.AppendTo('related.user', userOld); - if (userOld) { - evt.Put('user.target.name', userOld); - } - if (userNew) { - evt.Put('user.changes.name', userNew); - } - }) - .Build(); - - var groupMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(copyMemberToUser) - .Add(copyTargetUserToGroup) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var auditLogCleared = new processor.Chain() - .Add(copySubjectUserFromUserData) - .Add(copySubjectUserLogonIdFromUserData) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var auditChanged = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addAuditInfo) - .Add(addEventFields) - .Build(); - - var auditLogMgmt = new processor.Chain() - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var computerMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(copyTargetUserToComputerObject) - .Add(renameCommonAuthFields) - .Add(addUACDescription) - .Add(addEventFields) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Build(); - - var sessionEvts = new processor.Chain() - .Add(addSessionData) - .Add(addEventFields) - .Build(); - - var event4964 = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addEventFields) - .Build(); - - var kerberosTktEvts = new processor.Chain() - .Add(copyTargetUser) - .Add(renameCommonAuthFields) - .Add(addTicketOptionsDescription) - .Add(addTicketEncryptionType) - .Add(addTicketStatus) - .Add(addEventFields) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - if (/::ffff:/.test(ip)) { - evt.Put("source.ip", ip.replace("::ffff:", "")); - evt.Put("related.ip", ip.replace("::ffff:", "")); - } - } - }) - .Build(); - - var event4776 = new processor.Chain() - .Add(copyTargetUser) - .Add(addFailureStatus) - .Add(addEventFields) - .Build(); - - var scheduledTask = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Build(); - - var sensitivePrivilege = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Add(function(evt){ - var accessMask = evt.Get("winlog.event_data.AccessMask"); - if (!accessMask) { - return; - } - var accessDescriptions = translateAccessMask(accessMask); - if (!accessDescriptions) { - return; - } - if (accessDescriptions.length > 0) { - evt.Put("winlog.event_data.AccessMaskDescription", accessDescriptions); - } - }) - .Add(function(evt){ - var listNames = ["AccessList", "AccessMask"] - for (var i = 0; i < listNames.length; i++) { - var listContents = evt.Get("winlog.event_data." + listNames[i]) - if (!listContents) { - continue; - } - var listDescription = evt.Get("winlog.event_data." + listNames[i] + "Description") - if (listDescription) { - continue; - } - - var items = listContents.replace(/\s+/g, '').split("%%").filter(String); - evt.Put("winlog.event_data." + listNames[i], items) - var results = []; - for (var j = 0; j < items.length; j++) { - var description = msobjsMessageTable[items[j]]; - if (description === undefined) { - continue; - } - results.push(description); - } - evt.Put("winlog.event_data." + listNames[i] + "Description", results); - } - }) - - .Build(); - - var trustDomainMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Add(addTrustInformation) - .Build(); - - var policyChange = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Build(); - - var objectPolicyChange = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(copyTargetUserToTarget) - .Add(function(evt) { - var oldSd = evt.Get("winlog.event_data.OldSd"); - var newSd = evt.Get("winlog.event_data.NewSd"); - if (oldSd) { - enrichSDDL(evt, "winlog.event_data.OldSd"); - } - if (newSd) { - enrichSDDL(evt, "winlog.event_data.NewSd"); - } - }) - .Build(); - - var genericAuditChange = new processor.Chain() - .Add(addEventFields) - .Build(); - - var event4908 = new processor.Chain() - .Add(addEventFields) - .Add(function(evt) { - var sids = evt.Get("winlog.event_data.SidList"); - if (!sids) { - return; - } - var sidList = sids.split(/\s+/); - evt.Put("winlog.event_data.SidList", sids.split(/\s+/)); - var sidListDesc = []; - for (var i = 0; i < sidList.length; i++) { - var sidTemp = sidList[i].replace("%", "").replace("{", "").replace("}", "").replace(" ",""); - if (sidTemp) { - sidListDesc.push(translateSID(sidTemp)); - } - } - evt.Put("winlog.event_data.SidListDesc", sidListDesc); - }) - .Build(); - - var securityEventSource = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - return { - - // 1100 - The event logging service has shut down. - 1100: auditLogMgmt.Run, - - // 1102 - The audit log was cleared. - 1102: auditLogCleared.Run, - - // 1104 - The security log is now full. - 1104: auditLogMgmt.Run, - - // 1105 - Event log automatic backup. - 1105: auditLogMgmt.Run, - - // 1108 - The event logging service encountered an error while processing an incoming event published from %1 - 1108: auditLogMgmt.Run, - - // 4624 - An account was successfully logged on. - 4624: logonSuccess.Run, - - // 4625 - An account failed to log on. - 4625: event4625.Run, - - // 4634 - An account was logged off. - 4634: logoff.Run, - - // 4647 - User initiated logoff. - 4647: logoff.Run, - - // 4648 - A logon was attempted using explicit credentials. - 4648: event4648.Run, - - // 4670 - Permissions on an object were changed. - 4670: objectPolicyChange.Run, - - // 4672 - Special privileges assigned to new logon. - 4672: event4672.Run, - - // 4673 - A privileged service was called. - 4673: sensitivePrivilege.Run, - - // 4674 - An operation was attempted on a privileged object. - 4674: sensitivePrivilege.Run, - - // 4688 - A new process has been created. - 4688: event4688.Run, - - // 4689 - A process has exited. - 4689: event4689.Run, - - // 4697 - A service was installed in the system. - 4697: event4697.Run, - - // 4698 - A scheduled task was created. - 4698: scheduledTask.Run, - - // 4699 - A scheduled task was deleted. - 4699: scheduledTask.Run, - - // 4700 - A scheduled task was enabled. - 4700: scheduledTask.Run, - - // 4701 - A scheduled task was disabled. - 4701: scheduledTask.Run, - - // 4702 - A scheduled task was updated. - 4702: scheduledTask.Run, - - // 4706 - A new trust was created to a domain. - 4706: trustDomainMgmtEvts.Run, - - // 4707 - A trust to a domain was removed. - 4707: trustDomainMgmtEvts.Run, - - // 4713 - Kerberos policy was changed. - 4713: policyChange.Run, - - // 4716 - Trusted domain information was modified. - 4716: trustDomainMgmtEvts.Run, - - // 4717 - System security access was granted to an account. - 4717: policyChange.Run, - - // 4718 - System security access was removed from an account. - 4718: policyChange.Run, - - // 4719 - System audit policy was changed. - 4719: auditChanged.Run, - - // 4720 - A user account was created - 4720: userMgmtEvts.Run, - - // 4722 - A user account was enabled - 4722: userMgmtEvts.Run, - - // 4723 - An attempt was made to change an account's password - 4723: userMgmtEvts.Run, - - // 4724 - An attempt was made to reset an account's password - 4724: userMgmtEvts.Run, - - // 4725 - A user account was disabled. - 4725: userMgmtEvts.Run, - - // 4726 - An user account was deleted. - 4726: userMgmtEvts.Run, - - // 4727 - A security-enabled global group was created. - 4727: groupMgmtEvts.Run, - - // 4728 - A member was added to a security-enabled global group. - 4728: groupMgmtEvts.Run, - - // 4729 - A member was removed from a security-enabled global group. - 4729: groupMgmtEvts.Run, - - // 4730 - A security-enabled global group was deleted. - 4730: groupMgmtEvts.Run, - - // 4731 - A security-enabled local group was created. - 4731: groupMgmtEvts.Run, - - // 4732 - A member was added to a security-enabled local group. - 4732: groupMgmtEvts.Run, - - // 4733 - A member was removed from a security-enabled local group. - 4733: groupMgmtEvts.Run, - - // 4734 - A security-enabled local group was deleted. - 4734: groupMgmtEvts.Run, - - // 4735 - A security-enabled local group was changed. - 4735: groupMgmtEvts.Run, - - // 4737 - A security-enabled global group was changed. - 4737: groupMgmtEvts.Run, - - // 4739 - A security-enabled global group was changed. - 4739: policyChange.Run, - - // 4738 - An user account was changed. - 4738: userMgmtEvts.Run, - - // 4740 - An account was locked out - 4740: userMgmtEvts.Run, - - // 4741 - A computer account was created. - 4741: computerMgmtEvts.Run, - - // 4742 - A computer account was changed. - 4742: computerMgmtEvts.Run, - - // 4743 - A computer account was deleted. - 4743: computerMgmtEvts.Run, - - // 4744 - A security-disabled local group was created. - 4744: groupMgmtEvts.Run, - - // 4745 - A security-disabled local group was changed. - 4745: groupMgmtEvts.Run, - - // 4746 - A member was added to a security-disabled local group. - 4746: groupMgmtEvts.Run, - - // 4747 - A member was removed from a security-disabled local group. - 4747: groupMgmtEvts.Run, - - // 4748 - A security-disabled local group was deleted. - 4748: groupMgmtEvts.Run, - - // 4749 - A security-disabled global group was created. - 4749: groupMgmtEvts.Run, - - // 4750 - A security-disabled global group was changed. - 4750: groupMgmtEvts.Run, - - // 4751 - A member was added to a security-disabled global group. - 4751: groupMgmtEvts.Run, - - // 4752 - A member was removed from a security-disabled global group. - 4752: groupMgmtEvts.Run, - - // 4753 - A security-disabled global group was deleted. - 4753: groupMgmtEvts.Run, - - // 4754 - A security-enabled universal group was created. - 4754: groupMgmtEvts.Run, - - // 4755 - A security-enabled universal group was changed. - 4755: groupMgmtEvts.Run, - - // 4756 - A member was added to a security-enabled universal group. - 4756: groupMgmtEvts.Run, - - // 4757 - A member was removed from a security-enabled universal group. - 4757: groupMgmtEvts.Run, - - // 4758 - A security-enabled universal group was deleted. - 4758: groupMgmtEvts.Run, - - // 4759 - A security-disabled universal group was created. - 4759: groupMgmtEvts.Run, - - // 4760 - A security-disabled universal group was changed. - 4760: groupMgmtEvts.Run, - - // 4761 - A member was added to a security-disabled universal group. - 4761: groupMgmtEvts.Run, - - // 4762 - A member was removed from a security-disabled universal group. - 4762: groupMgmtEvts.Run, - - // 4763 - A security-disabled global group was deleted. - 4763: groupMgmtEvts.Run, - - // 4764 - A group\'s type was changed. - 4764: groupMgmtEvts.Run, - - // 4767 - A user account was unlocked. - 4767: userMgmtEvts.Run, - - // 4768 - A Kerberos authentication ticket TGT was requested. - 4768: kerberosTktEvts.Run, - - // 4769 - A Kerberos service ticket was requested. - 4769: kerberosTktEvts.Run, - - // 4770 - A Kerberos service ticket was renewed. - 4770: kerberosTktEvts.Run, - - // 4771 - Kerberos pre-authentication failed. - 4771: kerberosTktEvts.Run, - - // 4776 - The computer attempted to validate the credentials for an account. - 4776: event4776.Run, - - // 4778 - A session was reconnected to a Window Station. - 4778: sessionEvts.Run, - - // 4779 - A session was disconnected from a Window Station. - 4779: sessionEvts.Run, - - // 4781 - The name of an account was changed. - 4781: userRenamed.Run, - - // 4798 - A user's local group membership was enumerated. - 4798: userMgmtEvts.Run, - - // 4799 - A security-enabled local group membership was enumerated. - 4799: groupMgmtEvts.Run, - - // 4817 - Auditing settings on object were changed. - 4817: objectPolicyChange.Run, - - // 4902 - The Per-user audit policy table was created. - 4902: genericAuditChange.Run, - - // 4904 - An attempt was made to register a security event source. - 4904: securityEventSource.Run, - - // 4905 - An attempt was made to unregister a security event source. - 4905: securityEventSource.Run, - - // 4906 - The CrashOnAuditFail value has changed. - 4906: genericAuditChange.Run, - - // 4907 - Auditing settings on object were changed. - 4907: objectPolicyChange.Run, - - // 4908 - Special Groups Logon table modified. - 4908: event4908.Run, - - // 4912 - Per User Audit Policy was changed. - 4912: auditChanged.Run, - - // 4964 - Special groups have been assigned to a new logon. - 4964: event4964.Run, - - process: function(evt) { - var eventId = evt.Get("winlog.event_id"); - var processor = this[eventId]; - if (processor === undefined) { - return; - } - evt.Put("event.module", "security"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return security.process(evt); -} diff --git a/x-pack/winlogbeat/module/security/ingest/security.yml b/x-pack/winlogbeat/module/security/ingest/security.yml new file mode 100644 index 000000000000..7681693f253c --- /dev/null +++ b/x-pack/winlogbeat/module/security/ingest/security.yml @@ -0,0 +1,3364 @@ +--- +description: Pipeline for Windows Security events +processors: + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - convert: + field: event.code + type: string + ignore_missing: true + - script: + lang: painless + ignore_failure: false + tag: Set ECS categorization fields + description: Set ECS categorization fields + params: + "1100": + category: + - process + type: + - end + action: logging-service-shutdown + "1102": + category: + - iam + type: + - admin + - change + action: audit-log-cleared + "1104": + category: + - iam + type: + - admin + action: logging-full + "1105": + category: + - iam + type: + - admin + action: auditlog-archieved + "1108": + category: + - iam + type: + - admin + action: logging-processing-error + "4610": + category: + - configuration + type: + - access + action: authentication-package-loaded + "4611": + category: + - configuration + type: + - change + action: trusted-logon-process-registered + "4614": + category: + - configuration + type: + - access + action: notification-package-loaded + "4616": + category: + - configuration + type: + - change + action: system-time-changed + "4622": + category: + - configuration + type: + - access + action: security-package-loaded + "4624": + category: + - authentication + type: + - start + action: logged-in + "4625": + category: + - authentication + type: + - start + action: logon-failed + "4634": + category: + - authentication + type: + - end + action: logged-out + "4647": + category: + - authentication + type: + - end + action: logged-out + "4648": + category: + - authentication + type: + - start + action: logged-in-explicit + "4657": + category: + - registry + - configuration + type: + - change + action: registry-value-modified + "4670": + category: + - iam + - configuration + type: + - admin + - change + action: permissions-changed + "4672": + category: + - iam + type: + - admin + action: logged-in-special + "4673": + category: + - iam + type: + - admin + action: privileged-service-called + "4674": + category: + - iam + type: + - admin + action: privileged-operation + "4688": + category: + - process + type: + - start + action: created-process + "4689": + category: + - process + type: + - end + action: exited-process + "4697": + category: + - iam + - configuration + type: + - admin + - change + action: service-installed + "4698": + category: + - iam + - configuration + type: + - creation + - admin + action: scheduled-task-created + "4699": + category: + - iam + - configuration + type: + - deletion + - admin + action: scheduled-task-deleted + "4700": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-enabled + "4701": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-disabled + "4702": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-updated + "4706": + category: + - configuration + type: + - creation + action: domain-trust-added + "4707": + category: + - configuration + type: + - deletion + action: domain-trust-removed + "4713": + category: + - configuration + type: + - change + action: kerberos-policy-changed + "4714": + category: + - configuration + type: + - change + action: encrypted-data-recovery-policy-changed + "4715": + category: + - configuration + type: + - change + action: object-audit-policy-changed + "4716": + category: + - configuration + type: + - change + action: trusted-domain-information-changed + "4717": + category: + - iam + - configuration + type: + - admin + - change + action: system-security-access-granted + "4718": + category: + - iam + - configuration + type: + - admin + - deletion + action: system-security-access-removed + "4719": + category: + - iam + - configuration + type: + - admin + - change + action: changed-audit-config + "4720": + category: + - iam + type: + - user + - creation + action: added-user-account + "4722": + category: + - iam + type: + - user + - change + action: enabled-user-account + "4723": + category: + - iam + type: + - user + - change + action: changed-password + "4724": + category: + - iam + type: + - user + - change + action: reset-password + "4725": + category: + - iam + type: + - user + - deletion + action: disabled-user-account + "4726": + category: + - iam + type: + - user + - deletion + action: deleted-user-account + "4727": + category: + - iam + type: + - group + - creation + action: added-group-account + "4728": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4729": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4730": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4731": + category: + - iam + type: + - group + - creation + action: added-group-account + "4732": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4733": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4734": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4735": + category: + - iam + type: + - group + - change + action: modified-group-account + "4737": + category: + - iam + type: + - group + - change + action: modified-group-account + "4738": + category: + - iam + type: + - user + - change + action: modified-user-account + "4739": + category: + - configuration + type: + - change + action: domain-policy-changed + "4740": + category: + - iam + type: + - user + - change + action: locked-out-user-account + "4741": + category: + - iam + type: + - creation + - admin + action: added-computer-account + "4742": + category: + - iam + type: + - change + - admin + action: changed-computer-account + "4743": + category: + - iam + type: + - deletion + - admin + action: deleted-computer-account + "4744": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4745": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4746": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4747": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4748": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4749": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4750": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4751": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4752": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4753": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4754": + category: + - iam + type: + - group + - creation + action: added-group-account + "4755": + category: + - iam + type: + - group + - change + action: modified-group-account + "4756": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4757": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4758": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4759": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4760": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4761": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4762": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4763": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4764": + category: + - iam + type: + - group + - change + action: type-changed-group-account + "4767": + category: + - iam + type: + - user + - change + action: unlocked-user-account + "4768": + category: + - authentication + type: + - start + action: kerberos-authentication-ticket-requested + "4769": + category: + - authentication + type: + - start + action: kerberos-service-ticket-requested + "4770": + category: + - authentication + type: + - start + action: kerberos-service-ticket-renewed + "4771": + category: + - authentication + type: + - start + action: kerberos-preauth-failed + "4776": + category: + - authentication + type: + - start + action: credential-validated + "4778": + category: + - authentication + - session + type: + - start + action: session-reconnected + "4779": + category: + - authentication + - session + type: + - end + action: session-disconnected + "4781": + category: + - iam + type: + - user + - change + action: renamed-user-account + "4798": + category: + - iam + type: + - user + - info + action: group-membership-enumerated + "4799": + category: + - iam + type: + - group + - info + action: user-member-enumerated + "4817": + category: + - iam + - configuration + type: + - admin + - change + action: object-audit-changed + "4902": + category: + - iam + - configuration + type: + - admin + - creation + action: user-audit-policy-created + "4904": + category: + - iam + - configuration + type: + - admin + - change + action: security-event-source-added + "4905": + category: + - iam + - configuration + type: + - admin + - deletion + action: security-event-source-removed + "4906": + category: + - iam + - configuration + type: + - admin + - change + action: crash-on-audit-changed + "4907": + category: + - iam + - configuration + type: + - admin + - change + action: audit-setting-changed + "4908": + category: + - iam + - configuration + type: + - admin + - change + action: special-group-table-changed + "4912": + category: + - iam + - configuration + type: + - admin + - change + action: per-user-audit-policy-changed + "4950": + category: + - configuration + type: + - change + action: windows-firewall-setting-changed + "4954": + category: + - configuration + type: + - change + action: windows-firewall-group-policy-changed + "4964": + category: + - iam + type: + - admin + - group + action: logged-in-special + "5024": + category: + - process + type: + - start + action: windows-firewall-service-started + "5025": + category: + - process + type: + - end + action: windows-firewall-service-stopped + "5033": + category: + - driver + type: + - start + action: windows-firewall-driver-started + "5034": + category: + - driver + type: + - end + action: windows-firewall-driver-stopped + "5037": + category: + - driver + type: + - end + action: windows-firewall-driver-error + source: |- + if (ctx?.event?.code == null || params.get(ctx.event.code) == null) { + return; + } + def hm = new HashMap(params.get(ctx.event.code)); + hm.forEach((k, v) -> ctx.event[k] = v); + - script: + lang: painless + ignore_failure: false + tag: Set Logon Type + description: Set Logon Type + # Logon Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events + params: + "2": Interactive + "3": Network + "4": Batch + "5": Service + "7": Unlock + "8": NetworkCleartext + "9": NewCredentials + "10": RemoteInteractive + "11": CachedInteractive + source: |- + if (ctx?.winlog?.event_data?.LogonType == null) { + return; + } + def t = params.get(ctx.winlog.event_data.LogonType); + if (t == null) { + return; + } + if (ctx?.winlog?.logon == null ) { + Map map = new HashMap(); + ctx.winlog.put("logon", map); + } + ctx.winlog.logon.put("type", t) + - script: + lang: painless + ignore_failure: false + tag: Set User Account Control + description: Set User Account Control + # User Account Control Attributes Table + # https://support.microsoft.com/es-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties + params: + "0x00000001": SCRIPT + "0x00000002": ACCOUNTDISABLE + "0x00000008": HOMEDIR_REQUIRED + "0x00000010": LOCKOUT + "0x00000020": PASSWD_NOTREQD + "0x00000040": PASSWD_CANT_CHANGE + "0x00000080": ENCRYPTED_TEXT_PWD_ALLOWED + "0x00000100": TEMP_DUPLICATE_ACCOUNT + "0x00000200": NORMAL_ACCOUNT + "0x00000800": INTERDOMAIN_TRUST_ACCOUNT + "0x00001000": WORKSTATION_TRUST_ACCOUNT + "0x00002000": SERVER_TRUST_ACCOUNT + "0x00010000": DONT_EXPIRE_PASSWORD + "0x00020000": MNS_LOGON_ACCOUNT + "0x00040000": SMARTCARD_REQUIRED + "0x00080000": TRUSTED_FOR_DELEGATION + "0x00100000": NOT_DELEGATED + "0x00200000": USE_DES_KEY_ONLY + "0x00400000": DONT_REQ_PREAUTH + "0x00800000": PASSWORD_EXPIRED + "0x01000000": TRUSTED_TO_AUTH_FOR_DELEGATION + "0x04000000": PARTIAL_SECRETS_ACCOUNT + source: |- + if (ctx?.winlog?.event_data?.NewUacValue == null) { + return; + } + Long newUacValue = Long.decode(ctx.winlog.event_data.NewUacValue); + ArrayList uacResult = new ArrayList(); + for (entry in params.entrySet()) { + Long flag = Long.decode(entry.getKey()); + if ((newUacValue.longValue() & flag.longValue()) == flag.longValue()) { + uacResult.add(entry.getValue()); + } + } + if (uacResult.length == 0) { + return; + } + ctx.winlog.event_data.put("NewUACList", uacResult); + if (ctx?.winlog?.event_data?.UserAccountControl == null) { + return; + } + ArrayList uac_array = new ArrayList(); + for (elem in ctx.winlog.event_data.UserAccountControl.splitOnToken("%%")) { + if (elem.trim().length() > 0) { + uac_array.add(elem.trim()); + } + } + ctx.winlog.event_data.UserAccountControl = uac_array; + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Ticket Options + description: Set Kerberos Ticket Options + # Kerberos TGT and TGS Ticket Options + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4769 + params: + "0x40000000": Forwardable + "0x20000000": Forwarded + "0x10000000": Proxiable + "0x08000000": Proxy + "0x04000000": Allow-postdate + "0x02000000": Postdated + "0x01000000": Invalid + "0x00800000": Renewable + "0x00400000": Initial + "0x00200000": Pre-authent + "0x00100000": Opt-hardware-auth + "0x00080000": Transited-policy-checked + "0x00040000": Ok-as-delegate + "0x00020000": Request-anonymous + "0x00010000": Name-canonicalize + "0x00000020": Disable-transited-check + "0x00000010": Renewable-ok + "0x00000008": Enc-tkt-in-skey + "0x00000002": Renew + "0x00000001": Validate + source: |- + if (ctx?.winlog?.event_data?.TicketOptions == null) { + return; + } + Long tOpts = Long.decode(ctx.winlog.event_data.TicketOptions); + ArrayList tDescs = new ArrayList(); + for (entry in params.entrySet()) { + Long flag = Long.decode(entry.getKey()); + if ((tOpts.longValue() & flag.longValue()) == flag.longValue()) { + tDescs.add(entry.getValue()); + } + } + if (tDescs.length == 0) { + return; + } + ctx.winlog.event_data.put("TicketOptionsDescription", tDescs); + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Encryption Types + description: Set Kerberos Encryption Types + # Kerberos Encryption Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + params: + "0x1": DES-CBC-CRC + "0x3": DES-CBC-MD5 + "0x11": AES128-CTS-HMAC-SHA1-96 + "0x12": AES256-CTS-HMAC-SHA1-96 + "0x17": RC4-HMAC + "0x18": RC4-HMAC-EXP + "0xffffffff": FAIL + source: |- + if (ctx?.winlog?.event_data?.TicketEncryptionType == null) { + return; + } + ctx.winlog.event_data.put("TicketEncryptionTypeDescription", + params[ctx.winlog.event_data.TicketEncryptionType.toLowerCase()]) + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Ticket Status Codes + # Kerberos Result Status Codes + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + description: Set Kerberos Ticket Status Codes + params: + "0x0": KDC_ERR_NONE + "0x1": KDC_ERR_NAME_EXP + "0x2": KDC_ERR_SERVICE_EXP + "0x3": KDC_ERR_BAD_PVNO + "0x4": KDC_ERR_C_OLD_MAST_KVNO + "0x5": KDC_ERR_S_OLD_MAST_KVNO + "0x6": KDC_ERR_C_PRINCIPAL_UNKNOWN + "0x7": KDC_ERR_S_PRINCIPAL_UNKNOWN + "0x8": KDC_ERR_PRINCIPAL_NOT_UNIQUE + "0x9": KDC_ERR_NULL_KEY + "0xA": KDC_ERR_CANNOT_POSTDATE + "0xB": KDC_ERR_NEVER_VALID + "0xC": KDC_ERR_POLICY + "0xD": KDC_ERR_BADOPTION + "0xE": KDC_ERR_ETYPE_NOTSUPP + "0xF": KDC_ERR_SUMTYPE_NOSUPP + "0x10": KDC_ERR_PADATA_TYPE_NOSUPP + "0x11": KDC_ERR_TRTYPE_NO_SUPP + "0x12": KDC_ERR_CLIENT_REVOKED + "0x13": KDC_ERR_SERVICE_REVOKED + "0x14": KDC_ERR_TGT_REVOKED + "0x15": KDC_ERR_CLIENT_NOTYET + "0x16": KDC_ERR_SERVICE_NOTYET + "0x17": KDC_ERR_KEY_EXPIRED + "0x18": KDC_ERR_PREAUTH_FAILED + "0x19": KDC_ERR_PREAUTH_REQUIRED + "0x1A": KDC_ERR_SERVER_NOMATCH + "0x1B": KDC_ERR_MUST_USE_USER2USER + "0x1F": KRB_AP_ERR_BAD_INTEGRITY + "0x20": KRB_AP_ERR_TKT_EXPIRED + "0x21": KRB_AP_ERR_TKT_NYV + "0x22": KRB_AP_ERR_REPEAT + "0x23": KRB_AP_ERR_NOT_US + "0x24": KRB_AP_ERR_BADMATCH + "0x25": KRB_AP_ERR_SKEW + "0x26": KRB_AP_ERR_BADADDR + "0x27": KRB_AP_ERR_BADVERSION + "0x28": KRB_AP_ERR_MSG_TYPE + "0x29": KRB_AP_ERR_MODIFIED + "0x2A": KRB_AP_ERR_BADORDER + "0x2C": KRB_AP_ERR_BADKEYVER + "0x2D": KRB_AP_ERR_NOKEY + "0x2E": KRB_AP_ERR_MUT_FAIL + "0x2F": KRB_AP_ERR_BADDIRECTION + "0x30": KRB_AP_ERR_METHOD + "0x31": KRB_AP_ERR_BADSEQ + "0x32": KRB_AP_ERR_INAPP_CKSUM + "0x33": KRB_AP_PATH_NOT_ACCEPTED + "0x34": KRB_ERR_RESPONSE_TOO_BIG + "0x3C": KRB_ERR_GENERIC + "0x3D": KRB_ERR_FIELD_TOOLONG + "0x3E": KDC_ERR_CLIENT_NOT_TRUSTED + "0x3F": KDC_ERR_KDC_NOT_TRUSTED + "0x40": KDC_ERR_INVALID_SIG + "0x41": KDC_ERR_KEY_TOO_WEAK + "0x42": KRB_AP_ERR_USER_TO_USER_REQUIRED + "0x43": KRB_AP_ERR_NO_TGT + "0x44": KDC_ERR_WRONG_REALM + source: |- + if (ctx?.winlog?.event_data?.Status == null || + ctx?.event?.code == null || + !["4768", "4769", "4770", "4771"].contains(ctx.event.code)) { + return; + } + ctx.winlog.event_data.put("StatusDescription", params[ctx.winlog.event_data.Status]); + - script: + lang: painless + ignore_failure: false + tag: Set Service Type and Name + description: Set Service Type and Name + # Services Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4697 + params: + "0x1": Kernel Driver + "0x2": File System Driver + "0x8": Recognizer Driver + "0x10": Win32 Own Process + "0x20": Win32 Share Process + "0x110": Interactive Own Process + "0x120": Interactive Share Process + source: |- + if (ctx?.winlog?.event_data?.ServiceName != null) { + if (ctx?.service == null) { + HashMap hm = new HashMap(); + ctx.put("service", hm); + } + ctx.service.put("name", ctx.winlog.event_data.ServiceName); + } + if (ctx?.winlog.event_data?.ServiceType != null) { + if (ctx?.service == null) { + HashMap hm = new HashMap(); + ctx.put("service", hm); + } + ctx.service.put("type", params[ctx.winlog.event_data.ServiceType]); + } + - script: + lang: painless + ignore_failure: false + tag: Set Audit Information + description: Set Audit Information + # Audit Categories Description + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpac/77878370-0712-47cd-997d-b07053429f6d + params: + "0CCE9210-69AE-11D9-BED3-505054503030": ["Security State Change", "System"] + "0CCE9211-69AE-11D9-BED3-505054503030": ["Security System Extension", "System"] + "0CCE9212-69AE-11D9-BED3-505054503030": ["System Integrity", "System"] + "0CCE9213-69AE-11D9-BED3-505054503030": ["IPsec Driver", "System"] + "0CCE9214-69AE-11D9-BED3-505054503030": ["Other System Events", "System"] + "0CCE9215-69AE-11D9-BED3-505054503030": ["Logon", "Logon/Logoff"] + "0CCE9216-69AE-11D9-BED3-505054503030": ["Logoff", "Logon/Logoff"] + "0CCE9217-69AE-11D9-BED3-505054503030": ["Account Lockout", "Logon/Logoff"] + "0CCE9218-69AE-11D9-BED3-505054503030": ["IPsec Main Mode", "Logon/Logoff"] + "0CCE9219-69AE-11D9-BED3-505054503030": ["IPsec Quick Mode", "Logon/Logoff"] + "0CCE921A-69AE-11D9-BED3-505054503030": ["IPsec Extended Mode", "Logon/Logoff"] + "0CCE921B-69AE-11D9-BED3-505054503030": ["Special Logon", "Logon/Logoff"] + "0CCE921C-69AE-11D9-BED3-505054503030": ["Other Logon/Logoff Events", "Logon/Logoff"] + "0CCE9243-69AE-11D9-BED3-505054503030": ["Network Policy Server", "Logon/Logoff"] + "0CCE9247-69AE-11D9-BED3-505054503030": ["User / Device Claims", "Logon/Logoff"] + "0CCE921D-69AE-11D9-BED3-505054503030": ["File System", "Object Access"] + "0CCE921E-69AE-11D9-BED3-505054503030": ["Registry", "Object Access"] + "0CCE921F-69AE-11D9-BED3-505054503030": ["Kernel Object", "Object Access"] + "0CCE9220-69AE-11D9-BED3-505054503030": ["SAM", "Object Access"] + "0CCE9221-69AE-11D9-BED3-505054503030": ["Certification Services", "Object Access"] + "0CCE9222-69AE-11D9-BED3-505054503030": ["Application Generated", "Object Access"] + "0CCE9223-69AE-11D9-BED3-505054503030": ["Handle Manipulation", "Object Access"] + "0CCE9224-69AE-11D9-BED3-505054503030": ["File Share", "Object Access"] + "0CCE9225-69AE-11D9-BED3-505054503030": ["Filtering Platform Packet Drop", "Object Access"] + "0CCE9226-69AE-11D9-BED3-505054503030": ["Filtering Platform Connection ", "Object Access"] + "0CCE9227-69AE-11D9-BED3-505054503030": ["Other Object Access Events", "Object Access"] + "0CCE9244-69AE-11D9-BED3-505054503030": ["Detailed File Share", "Object Access"] + "0CCE9245-69AE-11D9-BED3-505054503030": ["Removable Storage", "Object Access"] + "0CCE9246-69AE-11D9-BED3-505054503030": ["Central Policy Staging", "Object Access"] + "0CCE9228-69AE-11D9-BED3-505054503030": ["Sensitive Privilege Use", "Privilege Use"] + "0CCE9229-69AE-11D9-BED3-505054503030": ["Non Sensitive Privilege Use", "Privilege Use"] + "0CCE922A-69AE-11D9-BED3-505054503030": ["Other Privilege Use Events", "Privilege Use"] + "0CCE922B-69AE-11D9-BED3-505054503030": ["Process Creation", "Detailed Tracking"] + "0CCE922C-69AE-11D9-BED3-505054503030": ["Process Termination", "Detailed Tracking"] + "0CCE922D-69AE-11D9-BED3-505054503030": ["DPAPI Activity", "Detailed Tracking"] + "0CCE922E-69AE-11D9-BED3-505054503030": ["RPC Events", "Detailed Tracking"] + "0CCE9248-69AE-11D9-BED3-505054503030": ["Plug and Play Events", "Detailed Tracking"] + "0CCE922F-69AE-11D9-BED3-505054503030": ["Audit Policy Change", "Policy Change"] + "0CCE9230-69AE-11D9-BED3-505054503030": ["Authentication Policy Change", "Policy Change"] + "0CCE9231-69AE-11D9-BED3-505054503030": ["Authorization Policy Change", "Policy Change"] + "0CCE9232-69AE-11D9-BED3-505054503030": ["MPSSVC Rule-Level Policy Change", "Policy Change"] + "0CCE9233-69AE-11D9-BED3-505054503030": ["Filtering Platform Policy Change", "Policy Change"] + "0CCE9234-69AE-11D9-BED3-505054503030": ["Other Policy Change Events", "Policy Change"] + "0CCE9235-69AE-11D9-BED3-505054503030": ["User Account Management", "Account Management"] + "0CCE9236-69AE-11D9-BED3-505054503030": ["Computer Account Management", "Account Management"] + "0CCE9237-69AE-11D9-BED3-505054503030": ["Security Group Management", "Account Management"] + "0CCE9238-69AE-11D9-BED3-505054503030": ["Distribution Group Management", "Account Management"] + "0CCE9239-69AE-11D9-BED3-505054503030": ["Application Group Management", "Account Management"] + "0CCE923A-69AE-11D9-BED3-505054503030": ["Other Account Management Events", "Account Management"] + "0CCE923B-69AE-11D9-BED3-505054503030": ["Directory Service Access", "Account Management"] + "0CCE923C-69AE-11D9-BED3-505054503030": ["Directory Service Changes", "Account Management"] + "0CCE923D-69AE-11D9-BED3-505054503030": ["Directory Service Replication", "Account Management"] + "0CCE923E-69AE-11D9-BED3-505054503030": ["Detailed Directory Service Replication", "Account Management"] + "0CCE923F-69AE-11D9-BED3-505054503030": ["Credential Validation", "Account Logon"] + "0CCE9240-69AE-11D9-BED3-505054503030": ["Kerberos Service Ticket Operations", "Account Logon"] + "0CCE9241-69AE-11D9-BED3-505054503030": ["Other Account Logon Events", "Account Logon"] + "0CCE9242-69AE-11D9-BED3-505054503030": ["Kerberos Authentication Service", "Account Logon"] + source: |- + if (ctx?.winlog?.event_data?.SubcategoryGuid == null) { + return; + } + def subCatGuid = ctx.winlog.event_data.SubcategoryGuid.replace("{","").replace("}","").toUpperCase(); + if (!params.containsKey(subCatGuid)) { + return; + } + ctx.winlog.event_data.put("Category", params[subCatGuid][1]); + ctx.winlog.event_data.put("SubCategory", params[subCatGuid][0]); + - script: + lang: painless + ignore_failure: false + tag: Decode message table + description: Decode message table + # Message table extracted from msobjs.dll on Windows 2019. + # https://gist.github.com/andrewkroh/665dca0682bd0e4daf194ab291694012 + # https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b + params: + descriptions: + "279": "Undefined Access (no effect) Bit 7" + "1536": "Unused message ID" + "1537": "DELETE" + "1538": "READ_CONTROL" + "1539": "WRITE_DAC" + "1540": "WRITE_OWNER" + "1541": "SYNCHRONIZE" + "1542": "ACCESS_SYS_SEC" + "1543": "MAX_ALLOWED" + "1552": "Unknown specific access (bit 0)" + "1553": "Unknown specific access (bit 1)" + "1554": "Unknown specific access (bit 2)" + "1555": "Unknown specific access (bit 3)" + "1556": "Unknown specific access (bit 4)" + "1557": "Unknown specific access (bit 5)" + "1558": "Unknown specific access (bit 6)" + "1559": "Unknown specific access (bit 7)" + "1560": "Unknown specific access (bit 8)" + "1561": "Unknown specific access (bit 9)" + "1562": "Unknown specific access (bit 10)" + "1563": "Unknown specific access (bit 11)" + "1564": "Unknown specific access (bit 12)" + "1565": "Unknown specific access (bit 13)" + "1566": "Unknown specific access (bit 14)" + "1567": "Unknown specific access (bit 15)" + "1601": "Not used" + "1603": "Assign Primary Token Privilege" + "1604": "Lock Memory Privilege" + "1605": "Increase Memory Quota Privilege" + "1606": "Unsolicited Input Privilege" + "1607": "Trusted Computer Base Privilege" + "1608": "Security Privilege" + "1609": "Take Ownership Privilege" + "1610": "Load/Unload Driver Privilege" + "1611": "Profile System Privilege" + "1612": "Set System Time Privilege" + "1613": "Profile Single Process Privilege" + "1614": "Increment Base Priority Privilege" + "1615": "Create Pagefile Privilege" + "1616": "Create Permanent Object Privilege" + "1617": "Backup Privilege" + "1618": "Restore From Backup Privilege" + "1619": "Shutdown System Privilege" + "1620": "Debug Privilege" + "1621": "View or Change Audit Log Privilege" + "1622": "Change Hardware Environment Privilege" + "1623": "Change Notify (and Traverse) Privilege" + "1624": "Remotely Shut System Down Privilege" + "1792": "" + "1794": "" + "1795": "Enabled" + "1796": "Disabled" + "1797": "All" + "1798": "None" + "1799": "Audit Policy query/set API Operation" + "1800": "" + "1801": "Granted by" + "1802": "Denied by" + "1803": "Denied by Integrity Policy check" + "1804": "Granted by Ownership" + "1805": "Not granted" + "1806": "Granted by NULL DACL" + "1807": "Denied by Empty DACL" + "1808": "Granted by NULL Security Descriptor" + "1809": "Unknown or unchecked" + "1810": "Not granted due to missing" + "1811": "Granted by ACE on parent folder" + "1812": "Denied by ACE on parent folder" + "1813": "Granted by Central Access Rule" + "1814": "NOT Granted by Central Access Rule" + "1815": "Granted by parent folder's Central Access Rule" + "1816": "NOT Granted by parent folder's Central Access Rule" + "1817": "Unknown Type" + "1818": "String" + "1819": "Unsigned 64-bit Integer" + "1820": "64-bit Integer" + "1821": "FQBN" + "1822": "Blob" + "1823": "Sid" + "1824": "Boolean" + "1825": "TRUE" + "1826": "FALSE" + "1827": "Invalid" + "1828": "an ACE too long to display" + "1829": "a Security Descriptor too long to display" + "1830": "Not granted to AppContainers" + "1831": "..." + "1832": "Identification" + "1833": "Impersonation" + "1840": "Delegation" + "1841": "Denied by Process Trust Label ACE" + "1842": "Yes" + "1843": "No" + "1844": "System" + "1845": "Not Available" + "1846": "Default" + "1847": "DisallowMmConfig" + "1848": "Off" + "1849": "Auto" + "1872": "REG_NONE" + "1873": "REG_SZ" + "1874": "REG_EXPAND_SZ" + "1875": "REG_BINARY" + "1876": "REG_DWORD" + "1877": "REG_DWORD_BIG_ENDIAN" + "1878": "REG_LINK" + "1879": "REG_MULTI_SZ (New lines are replaced with *. A * is replaced with **)" + "1880": "REG_RESOURCE_LIST" + "1881": "REG_FULL_RESOURCE_DESCRIPTOR" + "1882": "REG_RESOURCE_REQUIREMENTS_LIST" + "1883": "REG_QWORD" + "1904": "New registry value created" + "1905": "Existing registry value modified" + "1906": "Registry value deleted" + "1920": "Sunday" + "1921": "Monday" + "1922": "Tuesday" + "1923": "Wednesday" + "1924": "Thursday" + "1925": "Friday" + "1926": "Saturday" + "1936": "TokenElevationTypeDefault (1)" + "1937": "TokenElevationTypeFull (2)" + "1938": "TokenElevationTypeLimited (3)" + "2048": "Account Enabled" + "2049": "Home Directory Required' - Disabled" + "2050": "Password Not Required' - Disabled" + "2051": "Temp Duplicate Account' - Disabled" + "2052": "Normal Account' - Disabled" + "2053": "MNS Logon Account' - Disabled" + "2054": "Interdomain Trust Account' - Disabled" + "2055": "Workstation Trust Account' - Disabled" + "2056": "Server Trust Account' - Disabled" + "2057": "Don't Expire Password' - Disabled" + "2058": "Account Unlocked" + "2059": "Encrypted Text Password Allowed' - Disabled" + "2060": "Smartcard Required' - Disabled" + "2061": "Trusted For Delegation' - Disabled" + "2062": "Not Delegated' - Disabled" + "2063": "Use DES Key Only' - Disabled" + "2064": "Don't Require Preauth' - Disabled" + "2065": "Password Expired' - Disabled" + "2066": "Trusted To Authenticate For Delegation' - Disabled" + "2067": "Exclude Authorization Information' - Disabled" + "2068": "Undefined UserAccountControl Bit 20' - Disabled" + "2069": "Protect Kerberos Service Tickets with AES Keys' - Disabled" + "2070": "Undefined UserAccountControl Bit 22' - Disabled" + "2071": "Undefined UserAccountControl Bit 23' - Disabled" + "2072": "Undefined UserAccountControl Bit 24' - Disabled" + "2073": "Undefined UserAccountControl Bit 25' - Disabled" + "2074": "Undefined UserAccountControl Bit 26' - Disabled" + "2075": "Undefined UserAccountControl Bit 27' - Disabled" + "2076": "Undefined UserAccountControl Bit 28' - Disabled" + "2077": "Undefined UserAccountControl Bit 29' - Disabled" + "2078": "Undefined UserAccountControl Bit 30' - Disabled" + "2079": "Undefined UserAccountControl Bit 31' - Disabled" + "2080": "Account Disabled" + "2081": "Home Directory Required' - Enabled" + "2082": "Password Not Required' - Enabled" + "2083": "Temp Duplicate Account' - Enabled" + "2084": "Normal Account' - Enabled" + "2085": "MNS Logon Account' - Enabled" + "2086": "Interdomain Trust Account' - Enabled" + "2087": "Workstation Trust Account' - Enabled" + "2088": "Server Trust Account' - Enabled" + "2089": "Don't Expire Password' - Enabled" + "2090": "Account Locked" + "2091": "Encrypted Text Password Allowed' - Enabled" + "2092": "Smartcard Required' - Enabled" + "2093": "Trusted For Delegation' - Enabled" + "2094": "Not Delegated' - Enabled" + "2095": "Use DES Key Only' - Enabled" + "2096": "Don't Require Preauth' - Enabled" + "2097": "Password Expired' - Enabled" + "2098": "Trusted To Authenticate For Delegation' - Enabled" + "2099": "Exclude Authorization Information' - Enabled" + "2100": "Undefined UserAccountControl Bit 20' - Enabled" + "2101": "Protect Kerberos Service Tickets with AES Keys' - Enabled" + "2102": "Undefined UserAccountControl Bit 22' - Enabled" + "2103": "Undefined UserAccountControl Bit 23' - Enabled" + "2104": "Undefined UserAccountControl Bit 24' - Enabled" + "2105": "Undefined UserAccountControl Bit 25' - Enabled" + "2106": "Undefined UserAccountControl Bit 26' - Enabled" + "2107": "Undefined UserAccountControl Bit 27' - Enabled" + "2108": "Undefined UserAccountControl Bit 28' - Enabled" + "2109": "Undefined UserAccountControl Bit 29' - Enabled" + "2110": "Undefined UserAccountControl Bit 30' - Enabled" + "2111": "Undefined UserAccountControl Bit 31' - Enabled" + "2304": "An Error occured during Logon." + "2305": "The specified user account has expired." + "2306": "The NetLogon component is not active." + "2307": "Account locked out." + "2308": "The user has not been granted the requested logon type at this machine." + "2309": "The specified account's password has expired." + "2310": "Account currently disabled." + "2311": "Account logon time restriction violation." + "2312": "User not allowed to logon at this computer." + "2313": "Unknown user name or bad password." + "2314": "Domain sid inconsistent." + "2315": "Smartcard logon is required and was not used." + "2432": "Not Available." + "2436": "Random number generator failure." + "2437": "Random number generation failed FIPS-140 pre-hash check." + "2438": "Failed to zero secret data." + "2439": "Key failed pair wise consistency check." + "2448": "Failed to unprotect persistent cryptographic key." + "2449": "Key export checks failed." + "2450": "Validation of public key failed." + "2451": "Signature verification failed." + "2456": "Open key file." + "2457": "Delete key file." + "2458": "Read persisted key from file." + "2459": "Write persisted key to file." + "2464": "Export of persistent cryptographic key." + "2465": "Import of persistent cryptographic key." + "2480": "Open Key." + "2481": "Create Key." + "2482": "Delete Key." + "2483": "Encrypt." + "2484": "Decrypt." + "2485": "Sign hash." + "2486": "Secret agreement." + "2487": "Domain settings" + "2488": "Local settings" + "2489": "Add provider." + "2490": "Remove provider." + "2491": "Add context." + "2492": "Remove context." + "2493": "Add function." + "2494": "Remove function." + "2495": "Add function provider." + "2496": "Remove function provider." + "2497": "Add function property." + "2498": "Remove function property." + "2499": "Machine key." + "2500": "User key." + "2501": "Key Derivation." + "4352": "Device Access Bit 0" + "4353": "Device Access Bit 1" + "4354": "Device Access Bit 2" + "4355": "Device Access Bit 3" + "4356": "Device Access Bit 4" + "4357": "Device Access Bit 5" + "4358": "Device Access Bit 6" + "4359": "Device Access Bit 7" + "4360": "Device Access Bit 8" + "4361": "Undefined Access (no effect) Bit 9" + "4362": "Undefined Access (no effect) Bit 10" + "4363": "Undefined Access (no effect) Bit 11" + "4364": "Undefined Access (no effect) Bit 12" + "4365": "Undefined Access (no effect) Bit 13" + "4366": "Undefined Access (no effect) Bit 14" + "4367": "Undefined Access (no effect) Bit 15" + "4368": "Query directory" + "4369": "Traverse" + "4370": "Create object in directory" + "4371": "Create sub-directory" + "4372": "Undefined Access (no effect) Bit 4" + "4373": "Undefined Access (no effect) Bit 5" + "4374": "Undefined Access (no effect) Bit 6" + "4375": "Undefined Access (no effect) Bit 7" + "4376": "Undefined Access (no effect) Bit 8" + "4377": "Undefined Access (no effect) Bit 9" + "4378": "Undefined Access (no effect) Bit 10" + "4379": "Undefined Access (no effect) Bit 11" + "4380": "Undefined Access (no effect) Bit 12" + "4381": "Undefined Access (no effect) Bit 13" + "4382": "Undefined Access (no effect) Bit 14" + "4383": "Undefined Access (no effect) Bit 15" + "4384": "Query event state" + "4385": "Modify event state" + "4386": "Undefined Access (no effect) Bit 2" + "4387": "Undefined Access (no effect) Bit 3" + "4388": "Undefined Access (no effect) Bit 4" + "4389": "Undefined Access (no effect) Bit 5" + "4390": "Undefined Access (no effect) Bit 6" + "4391": "Undefined Access (no effect) Bit 7" + "4392": "Undefined Access (no effect) Bit 8" + "4393": "Undefined Access (no effect) Bit 9" + "4394": "Undefined Access (no effect) Bit 10" + "4395": "Undefined Access (no effect) Bit 11" + "4396": "Undefined Access (no effect) Bit 12" + "4397": "Undefined Access (no effect) Bit 13" + "4398": "Undefined Access (no effect) Bit 14" + "4399": "Undefined Access (no effect) Bit 15" + "4416": "ReadData (or ListDirectory)" + "4417": "WriteData (or AddFile)" + "4418": "AppendData (or AddSubdirectory or CreatePipeInstance)" + "4419": "ReadEA" + "4420": "WriteEA" + "4421": "Execute/Traverse" + "4422": "DeleteChild" + "4423": "ReadAttributes" + "4424": "WriteAttributes" + "4425": "Undefined Access (no effect) Bit 9" + "4426": "Undefined Access (no effect) Bit 10" + "4427": "Undefined Access (no effect) Bit 11" + "4428": "Undefined Access (no effect) Bit 12" + "4429": "Undefined Access (no effect) Bit 13" + "4430": "Undefined Access (no effect) Bit 14" + "4431": "Undefined Access (no effect) Bit 15" + "4432": "Query key value" + "4433": "Set key value" + "4434": "Create sub-key" + "4435": "Enumerate sub-keys" + "4436": "Notify about changes to keys" + "4437": "Create Link" + "4438": "Undefined Access (no effect) Bit 6" + "4439": "Undefined Access (no effect) Bit 7" + "4440": "Enable 64(or 32) bit application to open 64 bit key" + "4441": "Enable 64(or 32) bit application to open 32 bit key" + "4442": "Undefined Access (no effect) Bit 10" + "4443": "Undefined Access (no effect) Bit 11" + "4444": "Undefined Access (no effect) Bit 12" + "4445": "Undefined Access (no effect) Bit 13" + "4446": "Undefined Access (no effect) Bit 14" + "4447": "Undefined Access (no effect) Bit 15" + "4448": "Query mutant state" + "4449": "Undefined Access (no effect) Bit 1" + "4450": "Undefined Access (no effect) Bit 2" + "4451": "Undefined Access (no effect) Bit 3" + "4452": "Undefined Access (no effect) Bit 4" + "4453": "Undefined Access (no effect) Bit 5" + "4454": "Undefined Access (no effect) Bit 6" + "4455": "Undefined Access (no effect) Bit 7" + "4456": "Undefined Access (no effect) Bit 8" + "4457": "Undefined Access (no effect) Bit 9" + "4458": "Undefined Access (no effect) Bit 10" + "4459": "Undefined Access (no effect) Bit 11" + "4460": "Undefined Access (no effect) Bit 12" + "4461": "Undefined Access (no effect) Bit 13" + "4462": "Undefined Access (no effect) Bit 14" + "4463": "Undefined Access (no effect) Bit 15" + "4464": "Communicate using port" + "4465": "Undefined Access (no effect) Bit 1" + "4466": "Undefined Access (no effect) Bit 2" + "4467": "Undefined Access (no effect) Bit 3" + "4468": "Undefined Access (no effect) Bit 4" + "4469": "Undefined Access (no effect) Bit 5" + "4470": "Undefined Access (no effect) Bit 6" + "4471": "Undefined Access (no effect) Bit 7" + "4472": "Undefined Access (no effect) Bit 8" + "4473": "Undefined Access (no effect) Bit 9" + "4474": "Undefined Access (no effect) Bit 10" + "4475": "Undefined Access (no effect) Bit 11" + "4476": "Undefined Access (no effect) Bit 12" + "4477": "Undefined Access (no effect) Bit 13" + "4478": "Undefined Access (no effect) Bit 14" + "4479": "Undefined Access (no effect) Bit 15" + "4480": "Force process termination" + "4481": "Create new thread in process" + "4482": "Set process session ID" + "4483": "Perform virtual memory operation" + "4484": "Read from process memory" + "4485": "Write to process memory" + "4486": "Duplicate handle into or out of process" + "4487": "Create a subprocess of process" + "4488": "Set process quotas" + "4489": "Set process information" + "4490": "Query process information" + "4491": "Set process termination port" + "4492": "Undefined Access (no effect) Bit 12" + "4493": "Undefined Access (no effect) Bit 13" + "4494": "Undefined Access (no effect) Bit 14" + "4495": "Undefined Access (no effect) Bit 15" + "4496": "Control profile" + "4497": "Undefined Access (no effect) Bit 1" + "4498": "Undefined Access (no effect) Bit 2" + "4499": "Undefined Access (no effect) Bit 3" + "4500": "Undefined Access (no effect) Bit 4" + "4501": "Undefined Access (no effect) Bit 5" + "4502": "Undefined Access (no effect) Bit 6" + "4503": "Undefined Access (no effect) Bit 7" + "4504": "Undefined Access (no effect) Bit 8" + "4505": "Undefined Access (no effect) Bit 9" + "4506": "Undefined Access (no effect) Bit 10" + "4507": "Undefined Access (no effect) Bit 11" + "4508": "Undefined Access (no effect) Bit 12" + "4509": "Undefined Access (no effect) Bit 13" + "4510": "Undefined Access (no effect) Bit 14" + "4511": "Undefined Access (no effect) Bit 15" + "4512": "Query section state" + "4513": "Map section for write" + "4514": "Map section for read" + "4515": "Map section for execute" + "4516": "Extend size" + "4517": "Undefined Access (no effect) Bit 5" + "4518": "Undefined Access (no effect) Bit 6" + "4519": "Undefined Access (no effect) Bit 7" + "4520": "Undefined Access (no effect) Bit 8" + "4521": "Undefined Access (no effect) Bit 9" + "4522": "Undefined Access (no effect) Bit 10" + "4523": "Undefined Access (no effect) Bit 11" + "4524": "Undefined Access (no effect) Bit 12" + "4525": "Undefined Access (no effect) Bit 13" + "4526": "Undefined Access (no effect) Bit 14" + "4527": "Undefined Access (no effect) Bit 15" + "4528": "Query semaphore state" + "4529": "Modify semaphore state" + "4530": "Undefined Access (no effect) Bit 2" + "4531": "Undefined Access (no effect) Bit 3" + "4532": "Undefined Access (no effect) Bit 4" + "4533": "Undefined Access (no effect) Bit 5" + "4534": "Undefined Access (no effect) Bit 6" + "4535": "Undefined Access (no effect) Bit 7" + "4536": "Undefined Access (no effect) Bit 8" + "4537": "Undefined Access (no effect) Bit 9" + "4538": "Undefined Access (no effect) Bit 10" + "4539": "Undefined Access (no effect) Bit 11" + "4540": "Undefined Access (no effect) Bit 12" + "4541": "Undefined Access (no effect) Bit 13" + "4542": "Undefined Access (no effect) Bit 14" + "4543": "Undefined Access (no effect) Bit 15" + "4544": "Use symbolic link" + "4545": "Undefined Access (no effect) Bit 1" + "4546": "Undefined Access (no effect) Bit 2" + "4547": "Undefined Access (no effect) Bit 3" + "4548": "Undefined Access (no effect) Bit 4" + "4549": "Undefined Access (no effect) Bit 5" + "4550": "Undefined Access (no effect) Bit 6" + "4551": "Undefined Access (no effect) Bit 7" + "4552": "Undefined Access (no effect) Bit 8" + "4553": "Undefined Access (no effect) Bit 9" + "4554": "Undefined Access (no effect) Bit 10" + "4555": "Undefined Access (no effect) Bit 11" + "4556": "Undefined Access (no effect) Bit 12" + "4557": "Undefined Access (no effect) Bit 13" + "4558": "Undefined Access (no effect) Bit 14" + "4559": "Undefined Access (no effect) Bit 15" + "4560": "Force thread termination" + "4561": "Suspend or resume thread" + "4562": "Send an alert to thread" + "4563": "Get thread context" + "4564": "Set thread context" + "4565": "Set thread information" + "4566": "Query thread information" + "4567": "Assign a token to the thread" + "4568": "Cause thread to directly impersonate another thread" + "4569": "Directly impersonate this thread" + "4570": "Undefined Access (no effect) Bit 10" + "4571": "Undefined Access (no effect) Bit 11" + "4572": "Undefined Access (no effect) Bit 12" + "4573": "Undefined Access (no effect) Bit 13" + "4574": "Undefined Access (no effect) Bit 14" + "4575": "Undefined Access (no effect) Bit 15" + "4576": "Query timer state" + "4577": "Modify timer state" + "4578": "Undefined Access (no effect) Bit 2" + "4579": "Undefined Access (no effect) Bit 3" + "4580": "Undefined Access (no effect) Bit 4" + "4581": "Undefined Access (no effect) Bit 5" + "4582": "Undefined Access (no effect) Bit 6" + "4584": "Undefined Access (no effect) Bit 8" + "4585": "Undefined Access (no effect) Bit 9" + "4586": "Undefined Access (no effect) Bit 10" + "4587": "Undefined Access (no effect) Bit 11" + "4588": "Undefined Access (no effect) Bit 12" + "4589": "Undefined Access (no effect) Bit 13" + "4590": "Undefined Access (no effect) Bit 14" + "4591": "Undefined Access (no effect) Bit 15" + "4592": "AssignAsPrimary" + "4593": "Duplicate" + "4594": "Impersonate" + "4595": "Query" + "4596": "QuerySource" + "4597": "AdjustPrivileges" + "4598": "AdjustGroups" + "4599": "AdjustDefaultDacl" + "4600": "AdjustSessionID" + "4601": "Undefined Access (no effect) Bit 9" + "4602": "Undefined Access (no effect) Bit 10" + "4603": "Undefined Access (no effect) Bit 11" + "4604": "Undefined Access (no effect) Bit 12" + "4605": "Undefined Access (no effect) Bit 13" + "4606": "Undefined Access (no effect) Bit 14" + "4607": "Undefined Access (no effect) Bit 15" + "4608": "Create instance of object type" + "4609": "Undefined Access (no effect) Bit 1" + "4610": "Undefined Access (no effect) Bit 2" + "4611": "Undefined Access (no effect) Bit 3" + "4612": "Undefined Access (no effect) Bit 4" + "4613": "Undefined Access (no effect) Bit 5" + "4614": "Undefined Access (no effect) Bit 6" + "4615": "Undefined Access (no effect) Bit 7" + "4616": "Undefined Access (no effect) Bit 8" + "4617": "Undefined Access (no effect) Bit 9" + "4618": "Undefined Access (no effect) Bit 10" + "4619": "Undefined Access (no effect) Bit 11" + "4620": "Undefined Access (no effect) Bit 12" + "4621": "Undefined Access (no effect) Bit 13" + "4622": "Undefined Access (no effect) Bit 14" + "4623": "Undefined Access (no effect) Bit 15" + "4864": "Query State" + "4865": "Modify State" + "5120": "Channel read message" + "5121": "Channel write message" + "5122": "Channel query information" + "5123": "Channel set information" + "5124": "Undefined Access (no effect) Bit 4" + "5125": "Undefined Access (no effect) Bit 5" + "5126": "Undefined Access (no effect) Bit 6" + "5127": "Undefined Access (no effect) Bit 7" + "5128": "Undefined Access (no effect) Bit 8" + "5129": "Undefined Access (no effect) Bit 9" + "5130": "Undefined Access (no effect) Bit 10" + "5131": "Undefined Access (no effect) Bit 11" + "5132": "Undefined Access (no effect) Bit 12" + "5133": "Undefined Access (no effect) Bit 13" + "5134": "Undefined Access (no effect) Bit 14" + "5135": "Undefined Access (no effect) Bit 15" + "5136": "Assign process" + "5137": "Set Attributes" + "5138": "Query Attributes" + "5139": "Terminate Job" + "5140": "Set Security Attributes" + "5141": "Undefined Access (no effect) Bit 5" + "5142": "Undefined Access (no effect) Bit 6" + "5143": "Undefined Access (no effect) Bit 7" + "5144": "Undefined Access (no effect) Bit 8" + "5145": "Undefined Access (no effect) Bit 9" + "5146": "Undefined Access (no effect) Bit 10" + "5147": "Undefined Access (no effect) Bit 11" + "5148": "Undefined Access (no effect) Bit 12" + "5149": "Undefined Access (no effect) Bit 13" + "5150": "Undefined Access (no effect) Bit 14" + "5151": "Undefined Access (no effect) Bit 15" + "5376": "ConnectToServer" + "5377": "ShutdownServer" + "5378": "InitializeServer" + "5379": "CreateDomain" + "5380": "EnumerateDomains" + "5381": "LookupDomain" + "5382": "Undefined Access (no effect) Bit 6" + "5383": "Undefined Access (no effect) Bit 7" + "5384": "Undefined Access (no effect) Bit 8" + "5385": "Undefined Access (no effect) Bit 9" + "5386": "Undefined Access (no effect) Bit 10" + "5387": "Undefined Access (no effect) Bit 11" + "5388": "Undefined Access (no effect) Bit 12" + "5389": "Undefined Access (no effect) Bit 13" + "5390": "Undefined Access (no effect) Bit 14" + "5391": "Undefined Access (no effect) Bit 15" + "5392": "ReadPasswordParameters" + "5393": "WritePasswordParameters" + "5394": "ReadOtherParameters" + "5395": "WriteOtherParameters" + "5396": "CreateUser" + "5397": "CreateGlobalGroup" + "5398": "CreateLocalGroup" + "5399": "GetLocalGroupMembership" + "5400": "ListAccounts" + "5401": "LookupIDs" + "5402": "AdministerServer" + "5403": "Undefined Access (no effect) Bit 11" + "5404": "Undefined Access (no effect) Bit 12" + "5405": "Undefined Access (no effect) Bit 13" + "5406": "Undefined Access (no effect) Bit 14" + "5407": "Undefined Access (no effect) Bit 15" + "5408": "ReadInformation" + "5409": "WriteAccount" + "5410": "AddMember" + "5411": "RemoveMember" + "5412": "ListMembers" + "5413": "Undefined Access (no effect) Bit 5" + "5414": "Undefined Access (no effect) Bit 6" + "5415": "Undefined Access (no effect) Bit 7" + "5416": "Undefined Access (no effect) Bit 8" + "5417": "Undefined Access (no effect) Bit 9" + "5418": "Undefined Access (no effect) Bit 10" + "5419": "Undefined Access (no effect) Bit 11" + "5420": "Undefined Access (no effect) Bit 12" + "5421": "Undefined Access (no effect) Bit 13" + "5422": "Undefined Access (no effect) Bit 14" + "5423": "Undefined Access (no effect) Bit 15" + "5424": "AddMember" + "5425": "RemoveMember" + "5426": "ListMembers" + "5427": "ReadInformation" + "5428": "WriteAccount" + "5429": "Undefined Access (no effect) Bit 5" + "5430": "Undefined Access (no effect) Bit 6" + "5431": "Undefined Access (no effect) Bit 7" + "5432": "Undefined Access (no effect) Bit 8" + "5433": "Undefined Access (no effect) Bit 9" + "5434": "Undefined Access (no effect) Bit 10" + "5435": "Undefined Access (no effect) Bit 11" + "5436": "Undefined Access (no effect) Bit 12" + "5437": "Undefined Access (no effect) Bit 13" + "5438": "Undefined Access (no effect) Bit 14" + "5439": "Undefined Access (no effect) Bit 15" + "5440": "ReadGeneralInformation" + "5441": "ReadPreferences" + "5442": "WritePreferences" + "5443": "ReadLogon" + "5444": "ReadAccount" + "5445": "WriteAccount" + "5446": "ChangePassword (with knowledge of old password)" + "5447": "SetPassword (without knowledge of old password)" + "5448": "ListGroups" + "5449": "ReadGroupMembership" + "5450": "ChangeGroupMembership" + "5451": "Undefined Access (no effect) Bit 11" + "5452": "Undefined Access (no effect) Bit 12" + "5453": "Undefined Access (no effect) Bit 13" + "5454": "Undefined Access (no effect) Bit 14" + "5455": "Undefined Access (no effect) Bit 15" + "5632": "View non-sensitive policy information" + "5633": "View system audit requirements" + "5634": "Get sensitive policy information" + "5635": "Modify domain trust relationships" + "5636": "Create special accounts (for assignment of user rights)" + "5637": "Create a secret object" + "5638": "Create a privilege" + "5639": "Set default quota limits" + "5640": "Change system audit requirements" + "5641": "Administer audit log attributes" + "5642": "Enable/Disable LSA" + "5643": "Lookup Names/SIDs" + "5648": "Change secret value" + "5649": "Query secret value" + "5650": "Undefined Access (no effect) Bit 2" + "5651": "Undefined Access (no effect) Bit 3" + "5652": "Undefined Access (no effect) Bit 4" + "5653": "Undefined Access (no effect) Bit 5" + "5654": "Undefined Access (no effect) Bit 6" + "5655": "Undefined Access (no effect) Bit 7" + "5656": "Undefined Access (no effect) Bit 8" + "5657": "Undefined Access (no effect) Bit 9" + "5658": "Undefined Access (no effect) Bit 10" + "5659": "Undefined Access (no effect) Bit 11" + "5660": "Undefined Access (no effect) Bit 12" + "5661": "Undefined Access (no effect) Bit 13" + "5662": "Undefined Access (no effect) Bit 14" + "5663": "Undefined Access (no effect) Bit 15" + "5664": "Query trusted domain name/SID" + "5665": "Retrieve the controllers in the trusted domain" + "5666": "Change the controllers in the trusted domain" + "5667": "Query the Posix ID offset assigned to the trusted domain" + "5668": "Change the Posix ID offset assigned to the trusted domain" + "5669": "Undefined Access (no effect) Bit 5" + "5670": "Undefined Access (no effect) Bit 6" + "5671": "Undefined Access (no effect) Bit 7" + "5672": "Undefined Access (no effect) Bit 8" + "5673": "Undefined Access (no effect) Bit 9" + "5674": "Undefined Access (no effect) Bit 10" + "5675": "Undefined Access (no effect) Bit 11" + "5676": "Undefined Access (no effect) Bit 12" + "5677": "Undefined Access (no effect) Bit 13" + "5678": "Undefined Access (no effect) Bit 14" + "5679": "Undefined Access (no effect) Bit 15" + "5680": "Query account information" + "5681": "Change privileges assigned to account" + "5682": "Change quotas assigned to account" + "5683": "Change logon capabilities assigned to account" + "5684": "Change the Posix ID offset assigned to the accounted domain" + "5685": "Undefined Access (no effect) Bit 5" + "5686": "Undefined Access (no effect) Bit 6" + "5687": "Undefined Access (no effect) Bit 7" + "5688": "Undefined Access (no effect) Bit 8" + "5689": "Undefined Access (no effect) Bit 9" + "5690": "Undefined Access (no effect) Bit 10" + "5691": "Undefined Access (no effect) Bit 11" + "5692": "Undefined Access (no effect) Bit 12" + "5693": "Undefined Access (no effect) Bit 13" + "5694": "Undefined Access (no effect) Bit 14" + "5695": "Undefined Access (no effect) Bit 15" + "5696": "KeyedEvent Wait" + "5697": "KeyedEvent Wake" + "5698": "Undefined Access (no effect) Bit 2" + "5699": "Undefined Access (no effect) Bit 3" + "5700": "Undefined Access (no effect) Bit 4" + "5701": "Undefined Access (no effect) Bit 5" + "5702": "Undefined Access (no effect) Bit 6" + "5703": "Undefined Access (no effect) Bit 7" + "5704": "Undefined Access (no effect) Bit 8" + "5705": "Undefined Access (no effect) Bit 9" + "5706": "Undefined Access (no effect) Bit 10" + "5707": "Undefined Access (no effect) Bit 11" + "5708": "Undefined Access (no effect) Bit 12" + "5709": "Undefined Access (no effect) Bit 13" + "5710": "Undefined Access (no effect) Bit 14" + "5711": "Undefined Access (no effect) Bit 15" + "6656": "Enumerate desktops" + "6657": "Read attributes" + "6658": "Access Clipboard" + "6659": "Create desktop" + "6660": "Write attributes" + "6661": "Access global atoms" + "6662": "Exit windows" + "6663": "Unused Access Flag" + "6664": "Include this windowstation in enumerations" + "6665": "Read screen" + "6672": "Read Objects" + "6673": "Create window" + "6674": "Create menu" + "6675": "Hook control" + "6676": "Journal (record)" + "6677": "Journal (playback)" + "6678": "Include this desktop in enumerations" + "6679": "Write objects" + "6680": "Switch to this desktop" + "6912": "Administer print server" + "6913": "Enumerate printers" + "6930": "Full Control" + "6931": "Print" + "6948": "Administer Document" + "7168": "Connect to service controller" + "7169": "Create a new service" + "7170": "Enumerate services" + "7171": "Lock service database for exclusive access" + "7172": "Query service database lock state" + "7173": "Set last-known-good state of service database" + "7184": "Query service configuration information" + "7185": "Set service configuration information" + "7186": "Query status of service" + "7187": "Enumerate dependencies of service" + "7188": "Start the service" + "7189": "Stop the service" + "7190": "Pause or continue the service" + "7191": "Query information from service" + "7192": "Issue service-specific control commands" + "7424": "DDE Share Read" + "7425": "DDE Share Write" + "7426": "DDE Share Initiate Static" + "7427": "DDE Share Initiate Link" + "7428": "DDE Share Request" + "7429": "DDE Share Advise" + "7430": "DDE Share Poke" + "7431": "DDE Share Execute" + "7432": "DDE Share Add Items" + "7433": "DDE Share List Items" + "7680": "Create Child" + "7681": "Delete Child" + "7682": "List Contents" + "7683": "Write Self" + "7684": "Read Property" + "7685": "Write Property" + "7686": "Delete Tree" + "7687": "List Object" + "7688": "Control Access" + "7689": "Undefined Access (no effect) Bit 9" + "7690": "Undefined Access (no effect) Bit 10" + "7691": "Undefined Access (no effect) Bit 11" + "7692": "Undefined Access (no effect) Bit 12" + "7693": "Undefined Access (no effect) Bit 13" + "7694": "Undefined Access (no effect) Bit 14" + "7695": "Undefined Access (no effect) Bit 15" + "7936": "Audit Set System Policy" + "7937": "Audit Query System Policy" + "7938": "Audit Set Per User Policy" + "7939": "Audit Query Per User Policy" + "7940": "Audit Enumerate Users" + "7941": "Audit Set Options" + "7942": "Audit Query Options" + "8064": "Port sharing (read)" + "8065": "Port sharing (write)" + "8096": "Default credentials" + "8097": "Credentials manager" + "8098": "Fresh credentials" + "8192": "Kerberos" + "8193": "Preshared key" + "8194": "Unknown authentication" + "8195": "DES" + "8196": "3DES" + "8197": "MD5" + "8198": "SHA1" + "8199": "Local computer" + "8200": "Remote computer" + "8201": "No state" + "8202": "Sent first (SA) payload" + "8203": "Sent second (KE) payload" + "8204": "Sent third (ID) payload" + "8205": "Initiator" + "8206": "Responder" + "8207": "No state" + "8208": "Sent first (SA) payload" + "8209": "Sent final payload" + "8210": "Complete" + "8211": "Unknown" + "8212": "Transport" + "8213": "Tunnel" + "8214": "IKE/AuthIP DoS prevention mode started" + "8215": "IKE/AuthIP DoS prevention mode stopped" + "8216": "Enabled" + "8217": "Not enabled" + "8218": "No state" + "8219": "Sent first (EM attributes) payload" + "8220": "Sent second (SSPI) payload" + "8221": "Sent third (hash) payload" + "8222": "IKEv1" + "8223": "AuthIP" + "8224": "Anonymous" + "8225": "NTLM V2" + "8226": "CGA" + "8227": "Certificate" + "8228": "SSL" + "8229": "None" + "8230": "DH group 1" + "8231": "DH group 2" + "8232": "DH group 14" + "8233": "DH group ECP 256" + "8234": "DH group ECP 384" + "8235": "AES-128" + "8236": "AES-192" + "8237": "AES-256" + "8238": "Certificate ECDSA P256" + "8239": "Certificate ECDSA P384" + "8240": "SSL ECDSA P256" + "8241": "SSL ECDSA P384" + "8242": "SHA 256" + "8243": "SHA 384" + "8244": "IKEv2" + "8245": "EAP payload sent" + "8246": "Authentication payload sent" + "8247": "EAP" + "8248": "DH group 24" + "8272": "System" + "8273": "Logon/Logoff" + "8274": "Object Access" + "8275": "Privilege Use" + "8276": "Detailed Tracking" + "8277": "Policy Change" + "8278": "Account Management" + "8279": "DS Access" + "8280": "Account Logon" + "8448": "Success removed" + "8449": "Success Added" + "8450": "Failure removed" + "8451": "Failure Added" + "8452": "Success include removed" + "8453": "Success include added" + "8454": "Success exclude removed" + "8455": "Success exclude added" + "8456": "Failure include removed" + "8457": "Failure include added" + "8458": "Failure exclude removed" + "8459": "Failure exclude added" + "12288": "Security State Change" + "12289": "Security System Extension" + "12290": "System Integrity" + "12291": "IPsec Driver" + "12292": "Other System Events" + "12544": "Logon" + "12545": "Logoff" + "12546": "Account Lockout" + "12547": "IPsec Main Mode" + "12548": "Special Logon" + "12549": "IPsec Quick Mode" + "12550": "IPsec Extended Mode" + "12551": "Other Logon/Logoff Events" + "12552": "Network Policy Server" + "12553": "User / Device Claims" + "12554": "Group Membership" + "12800": "File System" + "12801": "Registry" + "12802": "Kernel Object" + "12803": "SAM" + "12804": "Other Object Access Events" + "12805": "Certification Services" + "12806": "Application Generated" + "12807": "Handle Manipulation" + "12808": "File Share" + "12809": "Filtering Platform Packet Drop" + "12810": "Filtering Platform Connection" + "12811": "Detailed File Share" + "12812": "Removable Storage" + "12813": "Central Policy Staging" + "13056": "Sensitive Privilege Use" + "13057": "Non Sensitive Privilege Use" + "13058": "Other Privilege Use Events" + "13312": "Process Creation" + "13313": "Process Termination" + "13314": "DPAPI Activity" + "13315": "RPC Events" + "13316": "Plug and Play Events" + "13317": "Token Right Adjusted Events" + "13568": "Audit Policy Change" + "13569": "Authentication Policy Change" + "13570": "Authorization Policy Change" + "13571": "MPSSVC Rule-Level Policy Change" + "13572": "Filtering Platform Policy Change" + "13573": "Other Policy Change Events" + "13824": "User Account Management" + "13825": "Computer Account Management" + "13826": "Security Group Management" + "13827": "Distribution Group Management" + "13828": "Application Group Management" + "13829": "Other Account Management Events" + "14080": "Directory Service Access" + "14081": "Directory Service Changes" + "14082": "Directory Service Replication" + "14083": "Detailed Directory Service Replication" + "14336": "Credential Validation" + "14337": "Kerberos Service Ticket Operations" + "14338": "Other Account Logon Events" + "14339": "Kerberos Authentication Service" + "14592": "Inbound" + "14593": "Outbound" + "14594": "Forward" + "14595": "Bidirectional" + "14596": "IP Packet" + "14597": "Transport" + "14598": "Forward" + "14599": "Stream" + "14600": "Datagram Data" + "14601": "ICMP Error" + "14602": "MAC 802.3" + "14603": "MAC Native" + "14604": "vSwitch" + "14608": "Resource Assignment" + "14609": "Listen" + "14610": "Receive/Accept" + "14611": "Connect" + "14612": "Flow Established" + "14614": "Resource Release" + "14615": "Endpoint Closure" + "14616": "Connect Redirect" + "14617": "Bind Redirect" + "14624": "Stream Packet" + "14640": "ICMP Echo-Request" + "14641": "vSwitch Ingress" + "14642": "vSwitch Egress" + "14672": "" + "14673": "[NULL]" + "14674": "Value Added" + "14675": "Value Deleted" + "14676": "Active Directory Domain Services" + "14677": "Active Directory Lightweight Directory Services" + "14678": "Yes" + "14679": "No" + "14680": "Value Added With Expiration Time" + "14681": "Value Deleted With Expiration Time" + "14688": "Value Auto Deleted With Expiration Time" + "16384": "Add" + "16385": "Delete" + "16386": "Boot-time" + "16387": "Persistent" + "16388": "Not persistent" + "16389": "Block" + "16390": "Permit" + "16391": "Callout" + "16392": "MD5" + "16393": "SHA-1" + "16394": "SHA-256" + "16395": "AES-GCM 128" + "16396": "AES-GCM 192" + "16397": "AES-GCM 256" + "16398": "DES" + "16399": "3DES" + "16400": "AES-128" + "16401": "AES-192" + "16402": "AES-256" + "16403": "Transport" + "16404": "Tunnel" + "16405": "Responder" + "16406": "Initiator" + "16407": "AES-GMAC 128" + "16408": "AES-GMAC 192" + "16409": "AES-GMAC 256" + "16416": "AuthNoEncap Transport" + "16896": "Enable WMI Account" + "16897": "Execute Method" + "16898": "Full Write" + "16899": "Partial Write" + "16900": "Provider Write" + "16901": "Remote Access" + "16902": "Subscribe" + "16903": "Publish" + AccessMaskDescriptions: + "0x00000001": Create Child + "0x00000002": Delete Child + "0x00000004": List Contents + "0x00000008": SELF + "0x00000010": Read Property + "0x00000020": Write Property + "0x00000040": Delete Treee + "0x00000080": List Object + "0x00000100": Control Access + "0x00010000": DELETE + "0x00020000": READ_CONTROL + "0x00040000": WRITE_DAC + "0x00080000": WRITE_OWNER + "0x00100000": SYNCHRONIZE + "0x00F00000": STANDARD_RIGHTS_REQUIRED + "0x001F0000": STANDARD_RIGHTS_ALL + "0x0000FFFF": SPECIFIC_RIGHTS_ALL + "0x01000000": ADS_RIGHT_ACCESS_SYSTEM_SECURITY + "0x10000000": ADS_RIGHT_GENERIC_ALL + "0x20000000": ADS_RIGHT_GENERIC_EXECUTE + "0x40000000": ADS_RIGHT_GENERIC_WRITE + "0x80000000": ADS_RIGHT_GENERIC_READ + source: |- + if (ctx?.winlog?.event_data?.FailureReason != null) { + def code = ctx.winlog.event_data.FailureReason.replace("%%",""); + if (params.descriptions.containsKey(code)) { + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("reason", params.descriptions[code]); + } + } + if (ctx?.winlog?.event_data?.AuditPolicyChanges != null) { + ArrayList results = new ArrayList(); + for (elem in ctx.winlog.event_data.AuditPolicyChanges.splitOnToken(",")) { + def code = elem.replace("%%","").trim(); + if (params.descriptions.containsKey(code)) { + results.add(params.descriptions[code]); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AuditPolicyChangesDescription", results); + } + } + if (ctx?.winlog?.event_data?.AccessList != null) { + ArrayList results = new ArrayList(); + for (elem in ctx.winlog.event_data.AccessList.splitOnToken(" ")) { + def code = elem.replace("%%","").trim(); + if (params.descriptions.containsKey(code)) { + results.add(params.descriptions[code]); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AccessListDescription", results); + } + } + if (ctx?.winlog?.event_data?.AccessMask != null) { + ArrayList results = new ArrayList(); + Long accessMask = Long.decode(ctx.winlog.event_data.AccessMask); + for (entry in params.AccessMaskDescriptions.entrySet()) { + Long accessFlag = Long.decode(entry.getKey()); + if ((accessMask.longValue() & accessFlag.longValue()) == accessFlag.longValue()) { + results.add(entry.getValue()); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AccessMaskDescription", results); + } + } + - script: + lang: painless + ignore_failure: false + tag: 4625 and 4776 Set Status and SubStatus + description: 4625 and 4776 Set Status and SubStatus + # Descriptions of failure status codes. + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4776 + params: + "0xc000005e": "There are currently no logon servers available to service the logon request." + "0xc0000064": "User logon with misspelled or bad user account" + "0xc000006a": "User logon with misspelled or bad password" + "0xc000006d": "This is either due to a bad username or authentication information" + "0xc000006e": "Unknown user name or bad password." + "0xc000006f": "User logon outside authorized hours" + "0xc0000070": "User logon from unauthorized workstation" + "0xc0000071": "User logon with expired password" + "0xc0000072": "User logon to account disabled by administrator" + "0xc00000dc": "Indicates the Sam Server was in the wrong state to perform the desired operation." + "0xc0000133": "Clocks between DC and other computer too far out of sync" + "0xc000015b": "The user has not been granted the requested logon type (aka logon right) at this machine" + "0xc000018c": "The logon request failed because the trust relationship between the primary domain and the trusted domain failed." + "0xc0000192": "An attempt was made to logon, but the Netlogon service was not started." + "0xc0000193": "User logon with expired account" + "0xc0000224": "User is required to change password at next logon" + "0xc0000225": "Evidently a bug in Windows and not a risk" + "0xc0000234": "User logon with account locked" + "0xc00002ee": "Failure Reason: An Error occurred during Logon" + "0xc0000413": "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine." + "0xc0000371": "The local account store does not contain secret material for the specified account" + "0x0": "Status OK." + source: |- + if (ctx?.winlog?.event_data?.Status == null || + ctx?.event?.code == null || + !["4625", "4776"].contains(ctx.event.code)) { + return; + } + if (params.containsKey(ctx.winlog.event_data.Status)) { + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("status", params[ctx.winlog.event_data.Status]); + } + if (ctx?.winlog?.event_data?.SubStatus == null || !params.containsKey(ctx.winlog.event_data.SubStatus)) { + return; + } + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("sub_status", params[ctx.winlog.event_data.SubStatus]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Type + description: Set Trust Type + # Trust Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "1": "TRUST_TYPE_DOWNLEVEL" + "2": "TRUST_TYPE_UPLEVEL" + "3": "TRUST_TYPE_MIT" + "4": "TRUST_TYPE_DCE" + source: |- + if (ctx?.winlog?.event_data?.TdoType == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoType)) { + return; + } + ctx.winlog.put("trustType", params[ctx.winlog.event_data.TdoType]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Direction + description: Set Trust Direction + # Trust Direction + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "0": "TRUST_DIRECTION_DISABLED" + "1": "TRUST_DIRECTION_INBOUND" + "2": "TRUST_DIRECTION_OUTBOUND" + "3": "TRUST_DIRECTION_BIDIRECTIONAL" + source: |- + if (ctx?.winlog?.event_data?.TdoDirection == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoDirection)) { + return; + } + ctx.winlog.put("trustDirection", params[ctx.winlog.event_data.TdoDirection]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Attributes + description: Set Trust Attributes + # Trust Attributes + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "0": "UNDEFINED" + "1": "TRUST_ATTRIBUTE_NON_TRANSITIVE" + "2": "TRUST_ATTRIBUTE_UPLEVEL_ONLY" + "4": "TRUST_ATTRIBUTE_QUARANTINED_DOMAIN" + "8": "TRUST_ATTRIBUTE_FOREST_TRANSITIVE" + "16": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION" + "32": "TRUST_ATTRIBUTE_WITHIN_FOREST" + "64": "TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL" + "128": "TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION" + "512": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION_NO_TGT_DELEGATION" + "1024": "TRUST_ATTRIBUTE_PIM_TRUST" + source: |- + if (ctx?.winlog?.event_data?.TdoAttributes == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoAttributes)) { + return; + } + ctx.winlog.put("trustAttribute", params[ctx.winlog.event_data.TdoAttributes]); + - script: + lang: painless + ignore_failure: false + tag: Add Session Events + description: Add Session Events + source: |- + if (ctx?.event?.code == null || + !["4778", "4779"].contains(ctx.event.code)) { + return; + } + //AccountName to user.name and related.user + if (ctx?.winlog?.event_data?.AccountName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.event_data.AccountName); + if (!ctx.related.user.contains(ctx.winlog.event_data.AccountName)) { + ctx.related.user.add(ctx.winlog.event_data.AccountName); + } + } + + //AccountDomain to user.domain + if (ctx?.winlog?.event_data?.AccountDomain != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.event_data.AccountDomain); + } + + //ClientAddress to source.ip and related.ip + if (ctx?.winlog?.event_data?.ClientAddress != null && + ctx.winlog.event_data.ClientAddress != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.ip == null) { + ArrayList al = new ArrayList(); + ctx.related.put("ip", al); + } + ctx.source.put("ip", ctx.winlog.event_data.ClientAddress); + if (!ctx.related.ip.contains(ctx.winlog.event_data.ClientAddress)) { + ctx.related.ip.add(ctx.winlog.event_data.ClientAddress); + } + } + + //ClientName to source.domain + if (ctx?.winlog?.event_data?.ClientName != null) { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("domain", ctx.winlog.event_data.ClientName); + } + + //LogonID to winlog.logon.id + if (ctx?.winlog?.event_data?.LogonID != null) { + if (ctx?.winlog?.logon == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + ctx.winlog.logon.put("id", ctx.winlog.event_data.LogonID); + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User + description: Copy Target User + source: |- + if (ctx?.event?.code == null || + !["4624", "4625", "4634", "4647", "4648", "4768", "4769", "4770", + "4771", "4776", "4964"].contains(ctx.event.code)) { + return; + } + + def targetUserId = ctx?.winlog?.event_data?.TargetUserSid; + if (targetUserId == null) { + targetUserId = ctx?.winlog?.event_data?.TargetSid; + } + + //TargetUserSid to user.id or user.target.id + if (targetUserId != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.id == null) { + ctx.user.put("id", targetUserId); + } else { + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("id", targetUserId); + } + } + + //TargetUserName to related.user and user.name or user.target.name + if (ctx?.winlog?.event_data?.TargetUserName != null) { + def tun = ctx.winlog.event_data.TargetUserName.splitOnToken("@"); + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.name == null) { + ctx.user.put("name", tun[0]); + } else { + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("name", tun[0]); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(tun[0])) { + ctx.related.user.add(tun[0]); + } + } + //TargetUserDomain to user.domain or user.target.domain + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.domain == null) { + ctx.user.put("domain", ctx.winlog.event_data.TargetDomainName); + } else { + if (ctx?.user?.target == null){ + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("domain", ctx.winlog.event_data.TargetDomainName); + } + } + - script: + lang: painless + ignore_failure: false + tag: Copy MemberName to User and User to Group + description: Copy MemberName to User and User to Group + source: |- + if (ctx?.event?.code == null || + !["4727", "4728", "4729", "4730", "4731", "4732", "4733", "4734", "4735", + "4737", "4744", "4745", "4746", "4747", "4748", "4749", "4750", "4751", + "4752", "4753", "4754", "4755", "4756", "4757", "4758", "4759", "4760", + "4761", "4762", "4763", "4764", "4799"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.MemberName != null) { + def memberNameParts = ctx.winlog.event_data.MemberName.splitOnToken(","); + def memberName = memberNameParts[0].replace("CN=","").replace("cn=",""); + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.target == null){ + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("name", memberName); + if (!ctx.related.user.contains(memberName)) { + ctx.related.user.add(memberName); + } + if (memberNameParts.length >= 4) { + def domain = memberNameParts[3].replace("DC=", "").replace("dc=", ""); + ctx.user.target.put("domain", domain); + } + } + if (ctx?.winlog?.event_data?.TargetUserSid != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("id", ctx.winlog.event_data.TargetUserSid); + } + if (ctx?.winlog?.event_data?.TargetSid != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("id", ctx.winlog.event_data.TargetSid); + } + if (ctx?.winlog?.event_data?.TargetUserName != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("name", ctx.winlog.event_data.TargetUserName); + } + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + def domain = ctx.winlog.event_data.TargetDomainName.replace("DC=", "").replace("dc=", ""); + ctx.group.put("domain", domain); + } + if (ctx?.user?.target != null) { + if (ctx?.user?.target?.group == null) { + HashMap hm = new HashMap(); + ctx.user.target.put("group", hm); + } + if (ctx?.group?.id != null) { + ctx.user.target.group.put("id", ctx.group.id); + } + if (ctx?.group?.name != null) { + ctx.user.target.group.put("name", ctx.group.name); + } + if (ctx?.group?.domain != null) { + ctx.user.target.group.put("domain", ctx.group.domain); + } + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Computer Object + description: Copy Target User to Computer Object + source: |- + if (ctx?.event?.code == null || + !["4741", "4742", "4743"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.TargetSid != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("id", ctx.winlog.event_data.TargetSid); + } + if (ctx?.winlog?.event_data?.TargetUserName != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("name", ctx.winlog.event_data.TargetUserName); + } + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("domain", ctx.winlog.event_data.TargetDomainName); + } + + - set: + field: winlog.logon.id + copy_from: winlog.event_data.TargetLogonId + ignore_failure: false + if: ctx?.event?.code != null && ["4634", "4647", "4964"].contains(ctx.event.code) + + - script: + lang: painless + ignore_failure: false + tag: Copy Subject User from Event Data + description: Copy Subject User from Event Data + source: |- + if (ctx?.event?.code == null || + !["4657", "4670", "4672", "4673", "4674", "4688", "4689", "4697", + "4698", "4699", "4700", "4701", "4702", "4706", "4707", "4713", + "4716", "4717", "4718", "4719", "4720", "4722", "4723", "4724", + "4725", "4726", "4727", "4728", "4729", "4730", "4731", "4732", + "4733", "4734", "4735", "4737", "4738", "4739", "4740", "4741", + "4742", "4743", "4744", "4745", "4746", "4747", "4748", "4749", + "4750", "4751", "4752", "4753", "4754", "4755", "4756", "4757", + "4758", "4759", "4760", "4761", "4762", "4763", "4764", "4767", + "4781", "4798", "4799", "4817", "4904", "4905", "4907", "4912", + "4648"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.SubjectUserSid != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("id", ctx.winlog.event_data.SubjectUserSid); + } + if (ctx?.winlog?.event_data?.SubjectUserName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.event_data.SubjectUserName); + if (!ctx.related.user.contains(ctx.winlog.event_data.SubjectUserName)) { + ctx.related.user.add(ctx.winlog.event_data.SubjectUserName); + } + } + if (ctx?.winlog?.event_data?.SubjectDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.event_data.SubjectDomainName); + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Target + description: Copy Target User to Target + source: |- + if (ctx?.event?.code == null || + !["4670", "4720", "4722", "4723", "4724", "4725", + "4726", "4738", "4740", "4767", "4798", "4817", + "4907"].contains(ctx.event.code)) { + return; + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + def userId = ctx?.winlog?.event_data?.TargetSid; + if (userId != null && userId != "" && userId != "-") ctx.user.target.id = userId; + def userName = ctx?.winlog?.event_data?.TargetUserName; + if (userName != null && userName != "" && userName != "-") { + ctx.user.target.name = userName; + def parts = userName.splitOnToken("@"); + if (parts.length > 1) { + ctx.user.target.name = parts[0]; + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.user.target.name)) { + ctx.related.user.add(ctx.user.target.name); + } + } + def userDomain = ctx?.winlog?.event_data?.TargetDomainName; + if (userDomain != null && userDomain != "" && userDomain != "-") ctx.user.target.domain = userDomain; + if (ctx.user?.target != null && ctx.user.target.size() == 0) ctx.user.remove("target"); + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Effective + description: Copy Target User to Effective + source: |- + if (ctx?.event?.code == null || + !["4648", "4688"].contains(ctx.event.code)) { + return; + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.effective == null) { + HashMap hm = new HashMap(); + ctx.user.put("effective", hm); + } + def userId = ctx?.winlog?.event_data?.TargetUserSid; + if (userId != null && userId != "" && userId != "-") ctx.user.effective.id = userId; + def userName = ctx?.winlog?.event_data?.TargetUserName; + if (userName != null && userName != "" && userName != "-") { + ctx.user.effective.name = userName; + def parts = userName.splitOnToken("@"); + if (parts.length > 1) { + ctx.user.effective.name = parts[0]; + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.user.effective.name)) { + ctx.related.user.add(ctx.user.effective.name); + } + } + def userDomain = ctx?.winlog?.event_data?.TargetDomainName; + if (userDomain != null && userDomain != "" && userDomain != "-") ctx.user.effective.domain = userDomain; + if (ctx.user?.effective != null && ctx.user.effective.size() == 0) ctx.user.remove("effective"); + + - script: + lang: painless + ignore_failure: false + tag: Copy Subject User from user_data + description: Copy Subject User from user_data + source: |- + if (ctx?.event?.code == null || + !["1102"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.user_data?.SubjectUserSid != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("id", ctx.winlog.user_data.SubjectUserSid); + } + if (ctx?.winlog?.user_data?.SubjectUserName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.user_data.SubjectUserName); + if (!ctx.related.user.contains(ctx.winlog.user_data.SubjectUserName)) { + ctx.related.user.add(ctx.winlog.user_data.SubjectUserName); + } + } + if (ctx?.winlog?.user_data?.SubjectDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.user_data.SubjectDomainName); + } + + - set: + field: winlog.logon.id + copy_from: winlog.event_data.SubjectLogonId + ignore_failure: true + + - set: + field: winlog.logon.id + copy_from: winlog.user_data.SubjectLogonId + ignore_failure: true + if: |- + ctx?.event?.code != null && + ["1102"].contains(ctx.event.code) + + - script: + lang: painless + ignore_failure: false + tag: Rename Common Auth Fields + description: Rename Common Auth Fields + source: |- + if (ctx?.event?.code == null || + !["1100", "1102", "1104", "1105", "1108", "4624", "4648", "4625", + "4670", "4673", "4674", "4689", "4697", "4719", "4720", "4722", + "4723", "4724", "4725", "4726", "4727", "4728", "4729", "4730", + "4731", "4732", "4733", "4734", "4735", "4737", "4738", "4740", + "4741", "4742", "4743", "4744", "4745", "4746", "4747", "4748", + "4749", "4750", "4751", "4752", "4753", "4754", "4755", "4756", + "4757", "4758", "4759", "4760", "4761", "4762", "4763", "4764", + "4767", "4768", "4769", "4770", "4771", "4798", "4799", "4817", + "4904", "4905", "4907", "4912"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.ProcessId != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx.winlog.event_data.ProcessId instanceof String) { + Long pid = Long.decode(ctx.winlog.event_data.ProcessId); + ctx.process.put("pid", pid.longValue()); + } else { + ctx.process.put("pid", ctx.winlog.event_data.ProcessId); + } + ctx.winlog.event_data.remove("ProcessId"); + } + if (ctx?.winlog?.event_data?.ProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("executable", ctx.winlog.event_data.ProcessName); + ctx.winlog.event_data.remove("ProcessName"); + } + if (ctx?.winlog?.event_data?.IpAddress != null && + ctx.winlog.event_data.IpAddress != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("ip", ctx.winlog.event_data.IpAddress); + ctx.winlog.event_data.remove("IpAddress"); + } + if (ctx?.winlog?.event_data?.IpPort != null && ctx.winlog.event_data.IpPort != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("port", Long.decode(ctx.winlog.event_data.IpPort)); + ctx.winlog.event_data.remove("IpPort"); + } + if (ctx?.winlog?.event_data?.WorkstationName != null) { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("domain", ctx.winlog.event_data.WorkstationName); + ctx.winlog.event_data.remove("WorkstationName"); + } + if (ctx?.winlog?.event_data?.ClientAddress != null && + ctx.winlog.event_data.ClientAddress != "-") { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + ctx.related.put("ip", ctx.winlog.event_data.ClientAddress); + ctx.winlog.event_data.remove("ClientAddress"); + } + if (ctx?.process?.name == null && ctx?.process?.executable != null) { + def parts = ctx.process.executable.splitOnToken("\\"); + ctx.process.put("name", parts[-1]); + } + + - script: + lang: painless + ignore_failure: false + tag: Process Event 4688 + description: Process Event 4688 + source: |- + if (ctx?.event?.code == null || + !["4688"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.NewProcessId != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx.winlog.event_data.NewProcessId instanceof String) { + Long pid = Long.decode(ctx.winlog.event_data.NewProcessId); + ctx.process.put("pid", pid.longValue()); + } else { + ctx.process.put("pid", ctx.winlog.event_data.NewProcessId); + } + ctx.winlog.event_data.remove("NewProcessId"); + } + if (ctx?.winlog?.event_data?.NewProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("executable", ctx.winlog.event_data.NewProcessName); + ctx.winlog.event_data.remove("NewProcessName"); + } + if (ctx?.winlog?.event_data?.ParentProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx?.process?.parent == null) { + HashMap hm = new HashMap(); + ctx.process.put("parent", hm); + } + ctx.process.parent.put("executable", ctx.winlog.event_data.ParentProcessName); + ctx.winlog.event_data.remove("ParentProcessName"); + } + if (ctx?.process?.name == null && ctx?.process?.executable != null) { + def parts = ctx.process.executable.splitOnToken("\\"); + ctx.process.put("name", parts[-1]); + } + if (ctx?.process?.parent?.name == null && ctx?.process?.parent?.executable != null) { + def parts = ctx.process.parent.executable.splitOnToken("\\"); + ctx.process.parent.put("name", parts[-1]); + } + if (ctx?.winlog?.event_data?.CommandLine != null) { + int start = 0; + int end = 0; + boolean in_quote = false; + ArrayList al = new ArrayList(); + for (int i = 0; i < ctx.winlog.event_data.CommandLine.length(); i++) { + end = i; + if (Character.compare(ctx.winlog.event_data.CommandLine.charAt(i), "\"".charAt(0)) == 0) { + if (in_quote) { + in_quote = false; + } else { + in_quote = true; + } + } + if (Character.isWhitespace(ctx.winlog.event_data.CommandLine.charAt(i)) && !in_quote) { + al.add(ctx.winlog.event_data.CommandLine.substring(start, end)); + start = i + 1; + } + if (i == ctx.winlog.event_data.CommandLine.length() - 1) { + al.add(ctx.winlog.event_data.CommandLine.substring(start, end + 1)); + } + } + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("args", al); + ctx.process.put("command_line", ctx.winlog.event_data.CommandLine); + } + if ((ctx?.winlog?.event_data?.TargetUserName != null) && + (!ctx.winlog.event_data.TargetUserName.equals("-"))) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.winlog.event_data.TargetUserName)) { + ctx.related.user.add(ctx.winlog.event_data.TargetUserName); + } + } + + - append: + field: related.user + value: '{{winlog.event_data.SubjectUserName}}' + allow_duplicates: false + if: |- + ctx?.event?.code != null && + ["4624", "4648"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.SubjectUserName != null && + ctx.winlog.event_data.SubjectUserName != "-" + + - append: + field: related.user + value: '{{winlog.event_data.TargetUserName}}' + allow_duplicates: false + if: |- + ctx?.event?.code != null && + ["4688", "4720", "4722", "4723", "4724", "4725", "4726", "4738", + "4740", "4767", "4798"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.TargetUserName != null && + ctx.winlog.event_data.TargetUserName != "-" + + - split: + field: winlog.event_data.PrivilegeList + separator: "\\s+" + if: |- + ctx?.event?.code != null && + ["4672", "4673", "4674", "4741", "4742", "4743"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.PrivilegeList != null + + - set: + field: user.target.name + copy_from: winlog.event_data.OldTargetUserName + ignore_empty_value: true + + - set: + field: user.changes.name + copy_from: winlog.event_data.NewTargetUserName + ignore_empty_value: true + + - append: + field: related.user + value: '{{winlog.event_data.NewTargetUserName}}' + allow_duplicates: false + if: |- + ctx?.winlog?.event_data?.NewTargetUserName != null && + ctx.winlog.event_data.NewTargetUserName != "-" + + - append: + field: related.user + value: '{{winlog.event_data.OldTargetUserName}}' + allow_duplicates: false + if: |- + ctx?.winlog?.event_data?.OldTargetUserName != null && + ctx.winlog.event_data.OldTargetUserName != "-" + + - gsub: + field: source.ip + pattern: "::ffff:" + replacement: "" + ignore_missing: true + + - append: + field: related.ip + value: '{{source.ip}}' + allow_duplicates: false + if: |- + ctx?.source?.ip != null && + ctx.source.ip != "-" + + - script: + lang: painless + ignore_failure: false + tag: Object Policy Change and SidListDesc + description: Object Policy Change and SidListDesc + # SDDL Ace Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 + # https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 + # SDDL Permissions + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 + # Known SIDs + # https://support.microsoft.com/en-au/help/243330/well-known-security-identifier"S-in-window"S-operating-systems + # https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings + # Domain-specific SIDs + # https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems + # Object Permission Flags + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b + params: + AccountSIDDescription: + AO: Account operators + RU: Alias to allow previous Windows 2000 + AN: Anonymous logon + AU: Authenticated users + BA: Built-in administrators + BG: Built-in guests + BO: Backup operators + BU: Built-in users + CA: Certificate server administrators + CG: Creator group + CO: Creator owner + DA: Domain administrators + DC: Domain computers + DD: Domain controllers + DG: Domain guests + DU: Domain users + EA: Enterprise administrators + ED: Enterprise domain controllers + WD: Everyone + PA: Group Policy administrators + IU: Interactively logged-on user + LA: Local administrator + LG: Local guest + LS: Local service account + SY: Local system + NU: Network logon user + "NO": Network configuration operators + NS: Network service account + PO: Printer operators + PS: Personal self + PU: Power users + RS: RAS servers group + RD: Terminal server users + RE: Replicator + RC: Restricted code + SA: Schema administrators + SO: Server operators + SU: Service logon user + S-1-0: Null Authority + S-1-0-0: Nobody + S-1-1: World Authority + S-1-1-0: Everyone + S-1-16-0: Untrusted Mandatory Level + S-1-16-12288: High Mandatory Level + S-1-16-16384: System Mandatory Level + S-1-16-20480: Protected Process Mandatory Level + S-1-16-28672: Secure Process Mandatory Level + S-1-16-4096: Low Mandatory Level + S-1-16-8192: Medium Mandatory Level + S-1-16-8448: Medium Plus Mandatory Level + S-1-2: Local Authority + S-1-2-0: Local + S-1-2-1: Console Logon + S-1-3: Creator Authority + S-1-3-0: Creator Owner + S-1-3-1: Creator Group + S-1-3-2: Creator Owner Server + S-1-3-3: Creator Group Server + S-1-3-4: Owner Rights + S-1-4: Non-unique Authority + S-1-5: NT Authority + S-1-5-1: Dialup + S-1-5-10: Principal Self + S-1-5-11: Authenticated Users + S-1-5-12: Restricted Code + S-1-5-13: Terminal Server Users + S-1-5-14: Remote Interactive Logon + S-1-5-15: This Organization + S-1-5-17: This Organization + S-1-5-18: Local System + S-1-5-19: NT Authority + S-1-5-2: Network + S-1-5-20: NT Authority + S-1-5-3: Batch + S-1-5-32-544: Administrators + S-1-5-32-545: Users + S-1-5-32-546: Guests + S-1-5-32-547: Power Users + S-1-5-32-548: Account Operators + S-1-5-32-549: Server Operators + S-1-5-32-550: Print Operators + S-1-5-32-551: Backup Operators + S-1-5-32-552: Replicators + S-1-5-32-554: Builtin\Pre-Windows 2000 Compatible Access + S-1-5-32-555: Builtin\Remote Desktop Users + S-1-5-32-556: Builtin\Network Configuration Operators + S-1-5-32-557: Builtin\Incoming Forest Trust Builders + S-1-5-32-558: Builtin\Performance Monitor Users + S-1-5-32-559: Builtin\Performance Log Users + S-1-5-32-560: Builtin\Windows Authorization Access Group + S-1-5-32-561: Builtin\Terminal Server License Servers + S-1-5-32-562: Builtin\Distributed COM Users + S-1-5-32-569: Builtin\Cryptographic Operators + S-1-5-32-573: Builtin\Event Log Readers + S-1-5-32-574: Builtin\Certificate Service DCOM Access + S-1-5-32-575: Builtin\RDS Remote Access Servers + S-1-5-32-576: Builtin\RDS Endpoint Servers + S-1-5-32-577: Builtin\RDS Management Servers + S-1-5-32-578: Builtin\Hyper-V Administrators + S-1-5-32-579: Builtin\Access Control Assistance Operators + S-1-5-32-580: Builtin\Remote Management Users + S-1-5-32-582: Storage Replica Administrators + S-1-5-4: Interactive + S-1-5-5-X-Y: Logon Session + S-1-5-6: Service + S-1-5-64-10: NTLM Authentication + S-1-5-64-14: SChannel Authentication + S-1-5-64-21: Digest Authentication + S-1-5-7: Anonymous + S-1-5-8: Proxy + S-1-5-80: NT Service + S-1-5-80-0: All Services + S-1-5-83-0: NT Virtual Machine\Virtual Machines + S-1-5-9: Enterprise Domain Controllers + S-1-5-90-0: Windows Manager\Windows Manager Group + AceTypes: + A: Access Allowed + D: Access Denied + OA: Object Access Allowed + OD: Object Access Denied + AU: System Audit + AL: System Alarm + OU: System Object Audit + OL: System Object Alarm + ML: System Mandatory Label + SP: Central Policy ID + DomainSpecificSID: + "498": Enterprise Read-only Domain Controllers + "500": Administrator + "501": Guest + "502": KRBTGT + "512": Domain Admins + "513": Domain Users + "514": Domain Guests + "515": Domain Computers + "516": Domain Controllers + "517": Cert Publishers + "518": Schema Admins + "519": Enterprise Admins + "520": Group Policy Creator Owners + "521": Read-only Domain Controllers + "522": Cloneable Domain Controllers + "526": Key Admins + "527": Enterprise Key Admins + "553": RAS and IAS Servers + "571": Allowed RODC Password Replication Group + "572": Denied RODC Password Replication Group + PermissionDescription: + GA: Generic All + GR: Generic Read + GW: Generic Write + GX: Generic Execute + RC: Read Permissions + SD: Delete + WD: Modify Permissions + WO: Modify Owner + RP: Read All Properties + WP: Write All Properties + CC: Create All Child Objects + DC: Delete All Child Objects + LC: List Contents + SW: All Validated + LO: List Object + DT: Delete Subtree + CR: All Extended Rights + FA: File All Access + FR: File Generic Read + FX: FILE GENERIC EXECUTE + FW: FILE GENERIC WRITE + KA: KEY ALL ACCESS + KR: KEY READ + KW: KEY WRITE + KX: KEY EXECUTE + PermsFlags: + "0x80000000": 'Generic Read' + "0x4000000": 'Generic Write' + "0x20000000": 'Generic Execute' + "0x10000000": 'Generic All' + "0x02000000": 'Maximum Allowed' + "0x01000000": 'Access System Security' + "0x00100000": 'Syncronize' + "0x00080000": 'Write Owner' + "0x00040000": 'Write DACL' + "0x00020000": 'Read Control' + "0x00010000": 'Delete' + source: |- + ArrayList translatePermissionMask(def mask, def params) { + ArrayList al = new ArrayList(); + Long permCode = Long.decode(mask); + for (entry in params.PermsFlags.entrySet()) { + Long permFlag = Long.decode(entry.getKey()); + if ((permCode.longValue() & permFlag.longValue()) == permFlag.longValue()) { + al.add(entry.getValue()); + } + } + if (al.length == 0) { + al.add(mask); + } + return al; + } + + HashMap translateACL(def dacl, def params) { + def aceArray = dacl.splitOnToken(";"); + HashMap hm = new HashMap(); + + if (aceArray.length >= 6 ) { + hm.put("grantee", translateSID(aceArray[5], params)); + } + + if (aceArray.length >= 1) { + hm.put("type", params.AceTypes[aceArray[0]]); + } + + if (aceArray.length >= 3) { + if (aceArray[2].startsWith("0x")) { + hm.put("perms", translatePermissionMask(aceArray[2], params)); + } else { + ArrayList al = new ArrayList(); + Pattern permPattern = /.{1,2}/; + Matcher permMatcher = permPattern.matcher(aceArray[2]); + while (permMatcher.find()) { + al.add(params.PermissionDescription[permMatcher.group(0)]); + } + hm.put("perms", al); + } + } + return hm; + } + String translateSID(def sid, def params) { + if (!params.AccountSIDDescription.containsKey(sid)) { + if (sid.startsWith("S-1-5-21")) { + Pattern uidPattern = /[0-9]{1,5}$/; + Matcher uidMatcher = uidPattern.matcher(sid); + if (uidMatcher.find()) { + return params.DomainSpecificSID[uidMatcher.group(0)]; + } + return sid; + } + return sid; + } + return params.AccountSIDDescription[sid]; + } + + void enrichSDDL(def sddlStr, def Sd, def params, def ctx) { + Pattern sdOwnerPattern = /^O\:[A-Z]{2}/; + Matcher sdOwnerMatcher = sdOwnerPattern.matcher(sddlStr); + if (sdOwnerMatcher.find()) { + ctx.winlog.event_data.put(Sd + "Owner", translateSID(sdOwnerMatcher.group(0), params)); + } + + Pattern sdGroupPattern = /^G\:[A-Z]{2}/; + Matcher sdGroupMatcher = sdGroupPattern.matcher(sddlStr); + if (sdGroupMatcher.find()) { + ctx.winlog.event_data.put(Sd + "Group", translateSID(sdGroupMatcher.group(0), params)); + } + + Pattern sdDaclPattern = /(D:([A-Z]*(\(.*\))*))/; + Matcher sdDaclMatcher = sdDaclPattern.matcher(sddlStr); + if (sdDaclMatcher.find()) { + Pattern dacListPattern = /\([^*\)]*\)/; + Matcher dacListMatcher = dacListPattern.matcher(sdDaclMatcher.group(1)); + for (def i = 0; dacListMatcher.find(); i++) { + def newDacl = translateACL(dacListMatcher.group(0).replace("(","").replace(")",""), params); + ctx.winlog.event_data.put(Sd + "Dacl" + i.toString(), newDacl['grantee'] + " :" + newDacl['type'] + " (" + newDacl['perms'] + ")"); + if (["Administrator", "Guest", "KRBTGT"].contains(newDacl['grantee'])) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(newDacl['grantee'])) { + ctx.related.user.add(newDacl['grantee']); + } + } + } + } + + Pattern sdSaclPattern = /(S:([A-Z]*(\(.*\))*))?$/; + Matcher sdSaclMatcher = sdSaclPattern.matcher(sddlStr); + if (sdSaclMatcher.find()) { + Pattern sacListPattern = /\([^*\)]*\)/; + Matcher sacListMatcher = sacListPattern.matcher(sdSaclMatcher.group(0)); + for (def i = 0; sacListMatcher.find(); i++) { + def newSacl = translateACL(sacListMatcher.group(0).replace("(","").replace(")",""), params); + ctx.winlog.event_data.put(Sd + "Sacl" + i.toString(), newSacl['grantee'] + " :" + newSacl['type'] + " (" + newSacl['perms'] + ")"); + if (["Administrator", "Guest", "KRBTGT"].contains(newSacl['grantee'])) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(newSacl['grantee'])) { + ctx.related.user.add(newSacl['grantee']); + } + } + } + } + } + + void splitSidList(def sids, def params, def ctx) { + ArrayList al = new ArrayList(); + def sidList = sids.splitOnToken(" "); + ctx.winlog.event_data.put("SidList", sidList); + for (def i = 0; i < sidList.length; i++ ) { + al.add(translateSID(sidList[i].replace("%", "").replace("{", "").replace("}", "").replace(" ",""), params)); + } + ctx.winlog.event_data.put("SidListDesc", al); + } + + if (ctx?.event?.code == null || + !["4670", "4817", "4907", "4908"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.OldSd != null) { + enrichSDDL(ctx.winlog.event_data.OldSd, "OldSd", params, ctx); + } + if (ctx?.winlog?.event_data?.NewSd != null) { + enrichSDDL(ctx.winlog.event_data.NewSd, "NewSd", params, ctx); + } + if (ctx?.winlog?.event_data?.SidList != null) { + splitSidList(ctx.winlog.event_data.SidList, params, ctx); + } + + - convert: + field: winlog.record_id + type: string + ignore_missing: true + + - convert: + field: winlog.event_id + type: string + ignore_missing: true + + - set: + field: ecs.version + value: '1.12.0' + + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true + +on_failure: + - set: + field: error.message + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/security/test/security_windows_test.go b/x-pack/winlogbeat/module/security/test/security_windows_test.go deleted file mode 100644 index 79c8d36cc59c..000000000000 --- a/x-pack/winlogbeat/module/security/test/security_windows_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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 test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields because they can be different on different versions -// of windows. -var ignoreFields = []string{ - "message", -} - -func TestSecurity(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-security.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js b/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js deleted file mode 100644 index c91649249f64..000000000000 --- a/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js +++ /dev/null @@ -1,1802 +0,0 @@ -// 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. - -// Polyfill for String startsWith. -if (!String.prototype.startsWith) { - Object.defineProperty(String.prototype, "startsWith", { - value: function (search, pos) { - pos = !pos || pos < 0 ? 0 : +pos; - return this.substring(pos, pos + search.length) === search; - }, - }); -} - -var sysmon = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - var net = require("net"); - - // Windows error codes for DNS. This list was generated using - // 'go run gen_dns_error_codes.go'. - var dnsQueryStatusCodes = { - "0": "SUCCESS", - "5": "ERROR_ACCESS_DENIED", - "8": "ERROR_NOT_ENOUGH_MEMORY", - "13": "ERROR_INVALID_DATA", - "14": "ERROR_OUTOFMEMORY", - "123": "ERROR_INVALID_NAME", - "1214": "ERROR_INVALID_NETNAME", - "1223": "ERROR_CANCELLED", - "1460": "ERROR_TIMEOUT", - "4312": "ERROR_OBJECT_NOT_FOUND", - "9001": "DNS_ERROR_RCODE_FORMAT_ERROR", - "9002": "DNS_ERROR_RCODE_SERVER_FAILURE", - "9003": "DNS_ERROR_RCODE_NAME_ERROR", - "9004": "DNS_ERROR_RCODE_NOT_IMPLEMENTED", - "9005": "DNS_ERROR_RCODE_REFUSED", - "9006": "DNS_ERROR_RCODE_YXDOMAIN", - "9007": "DNS_ERROR_RCODE_YXRRSET", - "9008": "DNS_ERROR_RCODE_NXRRSET", - "9009": "DNS_ERROR_RCODE_NOTAUTH", - "9010": "DNS_ERROR_RCODE_NOTZONE", - "9016": "DNS_ERROR_RCODE_BADSIG", - "9017": "DNS_ERROR_RCODE_BADKEY", - "9018": "DNS_ERROR_RCODE_BADTIME", - "9101": "DNS_ERROR_KEYMASTER_REQUIRED", - "9102": "DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE", - "9103": "DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1", - "9104": "DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS", - "9105": "DNS_ERROR_UNSUPPORTED_ALGORITHM", - "9106": "DNS_ERROR_INVALID_KEY_SIZE", - "9107": "DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE", - "9108": "DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION", - "9109": "DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR", - "9110": "DNS_ERROR_UNEXPECTED_CNG_ERROR", - "9111": "DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION", - "9112": "DNS_ERROR_KSP_NOT_ACCESSIBLE", - "9113": "DNS_ERROR_TOO_MANY_SKDS", - "9114": "DNS_ERROR_INVALID_ROLLOVER_PERIOD", - "9115": "DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET", - "9116": "DNS_ERROR_ROLLOVER_IN_PROGRESS", - "9117": "DNS_ERROR_STANDBY_KEY_NOT_PRESENT", - "9118": "DNS_ERROR_NOT_ALLOWED_ON_ZSK", - "9119": "DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD", - "9120": "DNS_ERROR_ROLLOVER_ALREADY_QUEUED", - "9121": "DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE", - "9122": "DNS_ERROR_BAD_KEYMASTER", - "9123": "DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD", - "9124": "DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT", - "9125": "DNS_ERROR_DNSSEC_IS_DISABLED", - "9126": "DNS_ERROR_INVALID_XML", - "9127": "DNS_ERROR_NO_VALID_TRUST_ANCHORS", - "9128": "DNS_ERROR_ROLLOVER_NOT_POKEABLE", - "9129": "DNS_ERROR_NSEC3_NAME_COLLISION", - "9130": "DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1", - "9501": "DNS_INFO_NO_RECORDS", - "9502": "DNS_ERROR_BAD_PACKET", - "9503": "DNS_ERROR_NO_PACKET", - "9504": "DNS_ERROR_RCODE", - "9505": "DNS_ERROR_UNSECURE_PACKET", - "9506": "DNS_REQUEST_PENDING", - "9551": "DNS_ERROR_INVALID_TYPE", - "9552": "DNS_ERROR_INVALID_IP_ADDRESS", - "9553": "DNS_ERROR_INVALID_PROPERTY", - "9554": "DNS_ERROR_TRY_AGAIN_LATER", - "9555": "DNS_ERROR_NOT_UNIQUE", - "9556": "DNS_ERROR_NON_RFC_NAME", - "9557": "DNS_STATUS_FQDN", - "9558": "DNS_STATUS_DOTTED_NAME", - "9559": "DNS_STATUS_SINGLE_PART_NAME", - "9560": "DNS_ERROR_INVALID_NAME_CHAR", - "9561": "DNS_ERROR_NUMERIC_NAME", - "9562": "DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER", - "9563": "DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION", - "9564": "DNS_ERROR_CANNOT_FIND_ROOT_HINTS", - "9565": "DNS_ERROR_INCONSISTENT_ROOT_HINTS", - "9566": "DNS_ERROR_DWORD_VALUE_TOO_SMALL", - "9567": "DNS_ERROR_DWORD_VALUE_TOO_LARGE", - "9568": "DNS_ERROR_BACKGROUND_LOADING", - "9569": "DNS_ERROR_NOT_ALLOWED_ON_RODC", - "9570": "DNS_ERROR_NOT_ALLOWED_UNDER_DNAME", - "9571": "DNS_ERROR_DELEGATION_REQUIRED", - "9572": "DNS_ERROR_INVALID_POLICY_TABLE", - "9573": "DNS_ERROR_ADDRESS_REQUIRED", - "9601": "DNS_ERROR_ZONE_DOES_NOT_EXIST", - "9602": "DNS_ERROR_NO_ZONE_INFO", - "9603": "DNS_ERROR_INVALID_ZONE_OPERATION", - "9604": "DNS_ERROR_ZONE_CONFIGURATION_ERROR", - "9605": "DNS_ERROR_ZONE_HAS_NO_SOA_RECORD", - "9606": "DNS_ERROR_ZONE_HAS_NO_NS_RECORDS", - "9607": "DNS_ERROR_ZONE_LOCKED", - "9608": "DNS_ERROR_ZONE_CREATION_FAILED", - "9609": "DNS_ERROR_ZONE_ALREADY_EXISTS", - "9610": "DNS_ERROR_AUTOZONE_ALREADY_EXISTS", - "9611": "DNS_ERROR_INVALID_ZONE_TYPE", - "9612": "DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP", - "9613": "DNS_ERROR_ZONE_NOT_SECONDARY", - "9614": "DNS_ERROR_NEED_SECONDARY_ADDRESSES", - "9615": "DNS_ERROR_WINS_INIT_FAILED", - "9616": "DNS_ERROR_NEED_WINS_SERVERS", - "9617": "DNS_ERROR_NBSTAT_INIT_FAILED", - "9618": "DNS_ERROR_SOA_DELETE_INVALID", - "9619": "DNS_ERROR_FORWARDER_ALREADY_EXISTS", - "9620": "DNS_ERROR_ZONE_REQUIRES_MASTER_IP", - "9621": "DNS_ERROR_ZONE_IS_SHUTDOWN", - "9622": "DNS_ERROR_ZONE_LOCKED_FOR_SIGNING", - "9651": "DNS_ERROR_PRIMARY_REQUIRES_DATAFILE", - "9652": "DNS_ERROR_INVALID_DATAFILE_NAME", - "9653": "DNS_ERROR_DATAFILE_OPEN_FAILURE", - "9654": "DNS_ERROR_FILE_WRITEBACK_FAILED", - "9655": "DNS_ERROR_DATAFILE_PARSING", - "9701": "DNS_ERROR_RECORD_DOES_NOT_EXIST", - "9702": "DNS_ERROR_RECORD_FORMAT", - "9703": "DNS_ERROR_NODE_CREATION_FAILED", - "9704": "DNS_ERROR_UNKNOWN_RECORD_TYPE", - "9705": "DNS_ERROR_RECORD_TIMED_OUT", - "9706": "DNS_ERROR_NAME_NOT_IN_ZONE", - "9707": "DNS_ERROR_CNAME_LOOP", - "9708": "DNS_ERROR_NODE_IS_CNAME", - "9709": "DNS_ERROR_CNAME_COLLISION", - "9710": "DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT", - "9711": "DNS_ERROR_RECORD_ALREADY_EXISTS", - "9712": "DNS_ERROR_SECONDARY_DATA", - "9713": "DNS_ERROR_NO_CREATE_CACHE_DATA", - "9714": "DNS_ERROR_NAME_DOES_NOT_EXIST", - "9715": "DNS_WARNING_PTR_CREATE_FAILED", - "9716": "DNS_WARNING_DOMAIN_UNDELETED", - "9717": "DNS_ERROR_DS_UNAVAILABLE", - "9718": "DNS_ERROR_DS_ZONE_ALREADY_EXISTS", - "9719": "DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE", - "9720": "DNS_ERROR_NODE_IS_DNAME", - "9721": "DNS_ERROR_DNAME_COLLISION", - "9722": "DNS_ERROR_ALIAS_LOOP", - "9751": "DNS_INFO_AXFR_COMPLETE", - "9752": "DNS_ERROR_AXFR", - "9753": "DNS_INFO_ADDED_LOCAL_WINS", - "9801": "DNS_STATUS_CONTINUE_NEEDED", - "9851": "DNS_ERROR_NO_TCPIP", - "9852": "DNS_ERROR_NO_DNS_SERVERS", - "9901": "DNS_ERROR_DP_DOES_NOT_EXIST", - "9902": "DNS_ERROR_DP_ALREADY_EXISTS", - "9903": "DNS_ERROR_DP_NOT_ENLISTED", - "9904": "DNS_ERROR_DP_ALREADY_ENLISTED", - "9905": "DNS_ERROR_DP_NOT_AVAILABLE", - "9906": "DNS_ERROR_DP_FSMO_ERROR", - "9911": "DNS_ERROR_RRL_NOT_ENABLED", - "9912": "DNS_ERROR_RRL_INVALID_WINDOW_SIZE", - "9913": "DNS_ERROR_RRL_INVALID_IPV4_PREFIX", - "9914": "DNS_ERROR_RRL_INVALID_IPV6_PREFIX", - "9915": "DNS_ERROR_RRL_INVALID_TC_RATE", - "9916": "DNS_ERROR_RRL_INVALID_LEAK_RATE", - "9917": "DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE", - "9921": "DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS", - "9922": "DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST", - "9923": "DNS_ERROR_VIRTUALIZATION_TREE_LOCKED", - "9924": "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME", - "9925": "DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE", - "9951": "DNS_ERROR_ZONESCOPE_ALREADY_EXISTS", - "9952": "DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST", - "9953": "DNS_ERROR_DEFAULT_ZONESCOPE", - "9954": "DNS_ERROR_INVALID_ZONESCOPE_NAME", - "9955": "DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES", - "9956": "DNS_ERROR_LOAD_ZONESCOPE_FAILED", - "9957": "DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED", - "9958": "DNS_ERROR_INVALID_SCOPE_NAME", - "9959": "DNS_ERROR_SCOPE_DOES_NOT_EXIST", - "9960": "DNS_ERROR_DEFAULT_SCOPE", - "9961": "DNS_ERROR_INVALID_SCOPE_OPERATION", - "9962": "DNS_ERROR_SCOPE_LOCKED", - "9963": "DNS_ERROR_SCOPE_ALREADY_EXISTS", - "9971": "DNS_ERROR_POLICY_ALREADY_EXISTS", - "9972": "DNS_ERROR_POLICY_DOES_NOT_EXIST", - "9973": "DNS_ERROR_POLICY_INVALID_CRITERIA", - "9974": "DNS_ERROR_POLICY_INVALID_SETTINGS", - "9975": "DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED", - "9976": "DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST", - "9977": "DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS", - "9978": "DNS_ERROR_SUBNET_DOES_NOT_EXIST", - "9979": "DNS_ERROR_SUBNET_ALREADY_EXISTS", - "9980": "DNS_ERROR_POLICY_LOCKED", - "9981": "DNS_ERROR_POLICY_INVALID_WEIGHT", - "9982": "DNS_ERROR_POLICY_INVALID_NAME", - "9983": "DNS_ERROR_POLICY_MISSING_CRITERIA", - "9984": "DNS_ERROR_INVALID_CLIENT_SUBNET_NAME", - "9985": "DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID", - "9986": "DNS_ERROR_POLICY_SCOPE_MISSING", - "9987": "DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED", - "9988": "DNS_ERROR_SERVERSCOPE_IS_REFERENCED", - "9989": "DNS_ERROR_ZONESCOPE_IS_REFERENCED", - "9990": "DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET", - "9991": "DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL", - "9992": "DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL", - "9993": "DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE", - "9994": "DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN", - "9995": "DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE", - "9996": "DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY", - "10054": "WSAECONNRESET", - "10055": "WSAENOBUFS", - "10060": "WSAETIMEDOUT", - }; - - // Windows DNS record type constants. - // https://docs.microsoft.com/en-us/windows/win32/dns/dns-constants - var dnsRecordTypes = { - "1": "A", - "2": "NS", - "3": "MD", - "4": "MF", - "5": "CNAME", - "6": "SOA", - "7": "MB", - "8": "MG", - "9": "MR", - "10": "NULL", - "11": "WKS", - "12": "PTR", - "13": "HINFO", - "14": "MINFO", - "15": "MX", - "16": "TXT", - "17": "RP", - "18": "AFSDB", - "19": "X25", - "20": "ISDN", - "21": "RT", - "22": "NSAP", - "23": "NSAPPTR", - "24": "SIG", - "25": "KEY", - "26": "PX", - "27": "GPOS", - "28": "AAAA", - "29": "LOC", - "30": "NXT", - "31": "EID", - "32": "NIMLOC", - "33": "SRV", - "34": "ATMA", - "35": "NAPTR", - "36": "KX", - "37": "CERT", - "38": "A6", - "39": "DNAME", - "40": "SINK", - "41": "OPT", - "43": "DS", - "46": "RRSIG", - "47": "NSEC", - "48": "DNSKEY", - "49": "DHCID", - "100": "UINFO", - "101": "UID", - "102": "GID", - "103": "UNSPEC", - "248": "ADDRS", - "249": "TKEY", - "250": "TSIG", - "251": "IXFR", - "252": "AXFR", - "253": "MAILB", - "254": "MAILA", - "255": "ANY", - "65281": "WINS", - "65282": "WINSR", - }; - - var setProcessNameUsingExe = function (evt) { - setProcessNameFromPath(evt, "process.executable", "process.name"); - }; - - var setParentProcessNameUsingExe = function (evt) { - setProcessNameFromPath( - evt, - "process.parent.executable", - "process.parent.name" - ); - }; - - var setProcessNameFromPath = function (evt, pathField, nameField) { - var name = evt.Get(nameField); - if (name) { - return; - } - var exe = evt.Get(pathField); - if (!exe) { - return; - } - evt.Put(nameField, path.basename(exe)); - }; - - var splitCommandLine = function (evt, source, target) { - var commandLine = evt.Get(source); - if (!commandLine) { - return; - } - evt.Put(target, windows.splitCommandLine(commandLine)); - }; - - var splitProcessArgs = function (evt) { - splitCommandLine(evt, "process.command_line", "process.args"); - }; - - var splitParentProcessArgs = function (evt) { - splitCommandLine( - evt, - "process.parent.command_line", - "process.parent.args" - ); - }; - - var addUser = function (evt) { - var id = evt.Get("winlog.user.identifier"); - if (id) { - evt.Put("user.id", id); - } - var userParts = evt.Get("winlog.event_data.User"); - if (!userParts) { - return; - } - userParts = userParts.split("\\"); - if (userParts.length === 2) { - evt.Put("user.domain", userParts[0]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - evt.Delete("winlog.event_data.User"); - } - }; - - var setRuleName = function (evt) { - var ruleName = evt.Get("winlog.event_data.RuleName"); - evt.Delete("winlog.event_data.RuleName"); - - if (!ruleName || ruleName === "-") { - return; - } - - evt.Put("rule.name", ruleName); - }; - - var addNetworkDirection = function (evt) { - switch (evt.Get("winlog.event_data.Initiated")) { - case "true": - evt.Put("network.direction", "egress"); - break; - case "false": - evt.Put("network.direction", "ingress"); - break; - } - evt.Delete("winlog.event_data.Initiated"); - }; - - var addNetworkType = function (evt) { - switch (evt.Get("winlog.event_data.SourceIsIpv6")) { - case "true": - evt.Put("network.type", "ipv6"); - break; - case "false": - evt.Put("network.type", "ipv4"); - break; - } - evt.Delete("winlog.event_data.SourceIsIpv6"); - evt.Delete("winlog.event_data.DestinationIsIpv6"); - }; - - var setRelatedIP = function (evt) { - var sourceIP = evt.Get("source.ip"); - if (sourceIP) { - evt.AppendTo("related.ip", sourceIP); - } - - var destIP = evt.Get("destination.ip"); - if (destIP) { - evt.AppendTo("related.ip", destIP); - } - }; - - var getHashPath = function (namespace, hashKey) { - if (hashKey === "imphash") { - return namespace + ".pe.imphash"; - } - - return namespace + ".hash." + hashKey; - }; - - var emptyHashRegex = /^0*$/; - - var hashIsEmpty = function (value) { - if (!value) { - return true; - } - - return emptyHashRegex.test(value); - } - - // Adds hashes from the given hashField in the event to the 'hash' key - // in the specified namespace. It also adds all the hashes to 'related.hash'. - var addHashes = function (evt, namespace, hashField) { - var hashes = evt.Get(hashField); - if (!hashes) { - return; - } - evt.Delete(hashField); - hashes.split(",").forEach(function (hash) { - var parts = hash.split("="); - if (parts.length !== 2) { - return; - } - - var key = parts[0].toLowerCase(); - var value = parts[1].toLowerCase(); - - if (hashIsEmpty(value)) { - return; - } - - var path = getHashPath(namespace, key); - - evt.Put(path, value); - evt.AppendTo("related.hash", value); - }); - }; - - var splitFileHashes = function (evt) { - addHashes(evt, "file", "winlog.event_data.Hashes"); - }; - - var splitFileHash = function (evt) { - addHashes(evt, "file", "winlog.event_data.Hash"); - }; - - var splitProcessHashes = function (evt) { - addHashes(evt, "process", "winlog.event_data.Hashes"); - }; - - var removeEmptyEventData = function (evt) { - var eventData = evt.Get("winlog.event_data"); - if (eventData && Object.keys(eventData).length === 0) { - evt.Delete("winlog.event_data"); - } - }; - - var translateDnsQueryStatus = function (evt) { - var statusCode = evt.Get("sysmon.dns.status"); - if (!statusCode) { - return; - } - var statusName = dnsQueryStatusCodes[statusCode]; - if (statusName === undefined) { - return; - } - evt.Put("sysmon.dns.status", statusName); - }; - - // Splits the QueryResults field that contains the DNS responses. - // Example: "type: 5 f2.taboola.map.fastly.net;::ffff:151.101.66.2;::ffff:151.101.130.2;::ffff:151.101.194.2;::ffff:151.101.2.2;" - var splitDnsQueryResults = function (evt) { - var results = evt.Get("winlog.event_data.QueryResults"); - if (!results) { - return; - } - results = results.split(";"); - - var answers = []; - var ips = []; - for (var i = 0; i < results.length; i++) { - var answer = results[i]; - if (!answer) { - continue; - } - - if (answer.startsWith("type:")) { - var parts = answer.split(/\s+/); - if (parts.length !== 3) { - throw "unexpected QueryResult format"; - } - - answers.push({ - type: dnsRecordTypes[parts[1]], - data: parts[2], - }); - } else { - // Convert V4MAPPED addresses. - answer = answer.replace("::ffff:", ""); - if (net.isIP(answer)) { - ips.push(answer); - - // Synthesize record type based on IP address type. - var type = "A"; - if (answer.indexOf(":") !== -1) { - type = "AAAA"; - } - answers.push({ - type: type, - data: answer, - }); - } - } - } - - if (answers.length > 0) { - evt.Put("dns.answers", answers); - } - if (ips.length > 0) { - evt.Put("dns.resolved_ip", ips); - } - evt.Delete("winlog.event_data.QueryResults"); - }; - - var parseUtcTime = new processor.Timestamp({ - field: "winlog.event_data.UtcTime", - target_field: "winlog.event_data.UtcTime", - timezone: "UTC", - layouts: ["2006-01-02 15:04:05.999"], - tests: ["2019-06-26 21:19:43.237"], - ignore_missing: true, - }); - - var setAdditionalSignatureFields = function (evt) { - var signed = evt.Get("winlog.event_data.Signed"); - if (!signed) { - return; - } - evt.Put("file.code_signature.signed", true); - var signatureStatus = evt.Get("winlog.event_data.SignatureStatus"); - evt.Put("file.code_signature.valid", signatureStatus === "Valid"); - }; - - var setAdditionalFileFieldsFromPath = function (evt) { - var filePath = evt.Get("file.path"); - if (!filePath) { - return; - } - - evt.Put("file.name", path.basename(filePath)); - evt.Put("file.directory", path.dirname(filePath)); - - // path returns extensions with a preceding ., e.g.: .tmp, .png - // according to ecs the expected format is without it, so we need to remove it. - var ext = path.extname(filePath); - if (!ext) { - return; - } - - if (ext.charAt(0) === ".") { - ext = ext.substr(1); - } - evt.Put("file.extension", ext); - }; - - // https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-hives - var commonRegistryHives = { - HKEY_CLASSES_ROOT: "HKCR", - HKCR: "HKCR", - HKEY_CURRENT_CONFIG: "HKCC", - HKCC: "HKCC", - HKEY_CURRENT_USER: "HKCU", - HKCU: "HKCU", - HKEY_DYN_DATA: "HKDD", - HKDD: "HKDD", - HKEY_LOCAL_MACHINE: "HKLM", - HKLM: "HKLM", - HKEY_PERFORMANCE_DATA: "HKPD", - HKPD: "HKPD", - HKEY_USERS: "HKU", - HKU: "HKU", - }; - - var qwordRegex = new RegExp(/QWORD \(((0x\d{8})-(0x\d{8}))\)/, "i"); - var dwordRegex = new RegExp(/DWORD \((0x\d{8})\)/, "i"); - - var setRegistryFields = function (evt) { - var path = evt.Get("winlog.event_data.TargetObject"); - if (!path) { - return; - } - evt.Put("registry.path", path); - var pathTokens = path.split("\\"); - var hive = commonRegistryHives[pathTokens[0]]; - if (hive) { - evt.Put("registry.hive", hive); - pathTokens.splice(0, 1); - if (pathTokens.length > 0) { - evt.Put("registry.key", pathTokens.join("\\")); - } - } - var value = pathTokens[pathTokens.length - 1]; - evt.Put("registry.value", value); - var data = evt.Get("winlog.event_data.Details"); - if (!data) { - return; - } - // sysmon only returns details of a registry modification - // if it's a qword or dword - var dataType; - var dataValue; - var match = qwordRegex.exec(data); - if (match && match.length > 0) { - var parsedHighByte = parseInt(match[2]); - var parsedLowByte = parseInt(match[3]); - if (!isNaN(parsedHighByte) && !isNaN(parsedLowByte)) { - dataValue = "" + ((parsedHighByte << 8) + parsedLowByte); - dataType = "SZ_QWORD"; - } - } else { - match = dwordRegex.exec(data); - if (match && match.length > 0) { - var parsedValue = parseInt(match[1]); - if (!isNaN(parsedValue)) { - dataType = "SZ_DWORD"; - dataValue = "" + parsedValue; - } - } - } - if (dataType) { - evt.Put("registry.data.strings", [dataValue]); - evt.Put("registry.data.type", dataType); - } - }; - - // Event ID 1 - Process Create. - var event1 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["start", "process_start"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.CommandLine", - to: "process.command_line", - }, - { - from: "winlog.event_data.CurrentDirectory", - to: "process.working_directory", - }, - { - from: "winlog.event_data.ParentProcessGuid", - to: "process.parent.entity_id", - }, - { - from: "winlog.event_data.ParentProcessId", - to: "process.parent.pid", - type: "long", - }, - { - from: "winlog.event_data.ParentImage", - to: "process.parent.executable", - }, - { - from: "winlog.event_data.ParentCommandLine", - to: "process.parent.command_line", - }, - { - from: "winlog.event_data.OriginalFileName", - to: "process.pe.original_file_name", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Company", - to: "process.pe.company", - }, - { - from: "winlog.event_data.Description", - to: "process.pe.description", - }, - { - from: "winlog.event_data.FileVersion", - to: "process.pe.file_version", - }, - { - from: "winlog.event_data.Product", - to: "process.pe.product", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(splitProcessArgs) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setParentProcessNameUsingExe) - .Add(splitParentProcessArgs) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 2 - File creation time changed. - var event2 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 3 - Network connection detected. - var event3 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["network"], - type: ["connection", "start", "protocol"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Protocol", - to: "network.transport", - }, - { - from: "winlog.event_data.SourceIp", - to: "source.ip", - type: "ip", - }, - { - from: "winlog.event_data.SourceHostname", - to: "source.domain", - type: "string", - }, - { - from: "winlog.event_data.SourcePort", - to: "source.port", - type: "long", - }, - { - from: "winlog.event_data.DestinationIp", - to: "destination.ip", - type: "ip", - }, - { - from: "winlog.event_data.DestinationHostname", - to: "destination.domain", - type: "string", - }, - { - from: "winlog.event_data.DestinationPort", - to: "destination.port", - type: "long", - }, - { - from: "winlog.event_data.DestinationPortName", - to: "network.protocol", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRelatedIP) - .Add(setProcessNameUsingExe) - .Add(addUser) - .Add(addNetworkDirection) - .Add(addNetworkType) - .CommunityID() - .Add(removeEmptyEventData) - .Build(); - - // Event ID 4 - Sysmon service state changed. - var event4 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 5 - Process terminated. - var event5 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["end", "process_end"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 6 - Driver loaded. - var event6 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["driver"], - type: ["start"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ImageLoaded", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Signature", - to: "file.code_signature.subject_name", - }, - { - from: "winlog.event_data.SignatureStatus", - to: "file.code_signature.status", - }, - ], - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setAdditionalSignatureFields) - .Add(splitFileHashes) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 7 - Image loaded. - var event7 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.ImageLoaded", - to: "file.path", - }, - { - from: "winlog.event_data.OriginalFileName", - to: "file.pe.original_file_name", - }, - - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Signature", - to: "file.code_signature.subject_name", - }, - { - from: "winlog.event_data.SignatureStatus", - to: "file.code_signature.status", - }, - { - from: "winlog.event_data.Company", - to: "file.pe.company", - }, - { - from: "winlog.event_data.Description", - to: "file.pe.description", - }, - { - from: "winlog.event_data.FileVersion", - to: "file.pe.file_version", - }, - { - from: "winlog.event_data.Product", - to: "file.pe.product", - }, - ], - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setAdditionalSignatureFields) - .Add(setProcessNameUsingExe) - .Add(splitFileHashes) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 8 - CreateRemoteThread detected. - var event8 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.SourceProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.SourceProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.SourceImage", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 9 - RawAccessRead detected. - var event9 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Device", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 10 - Process accessed. - var event10 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.SourceProcessGUID", - to: "process.entity_id", - }, - { - from: "winlog.event_data.SourceProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.SourceThreadId", - to: "process.thread.id", - type: "long", - }, - { - from: "winlog.event_data.SourceImage", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 11 - File created. - var event11 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["creation"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 12 - Registry object added or deleted. - var event12 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 13 - Registry value set. - var event13 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 14 - Registry object renamed. - var event14 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 15 - File stream created. - var event15 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(splitFileHash) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 16 - Sysmon config state changed. - var event16 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 17 - Pipe Created. - var event17 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["creation"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.PipeName", - to: "file.name", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 18 - Pipe Connected. - var event18 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.PipeName", - to: "file.name", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 19 - WmiEventFilter activity detected. - var event19 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 20 - WmiEventConsumer activity detected. - var event20 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.Destination", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 21 - WmiEventConsumerToFilter activity detected. - var event21 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 22 - DNSEvent (DNS query). - var event22 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["network"], - type: ["connection", "protocol", "info"], - }, - target: "event", - }) - .AddFields({ - fields: { - protocol: "dns", - }, - target: "network", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.QueryName", - to: "dns.question.name", - }, - { - from: "winlog.event_data.QueryStatus", - to: "sysmon.dns.status", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .RegisteredDomain({ - ignore_failure: true, - ignore_missing: true, - field: "dns.question.name", - target_field: "dns.question.registered_domain", - target_subdomain_field: "dns.question.subdomain", - target_etld_field: "dns.question.top_level_domain", - }) - .Add(setRuleName) - .Add(translateDnsQueryStatus) - .Add(splitDnsQueryResults) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 23 - FileDelete (A file delete was detected). - var event23 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["deletion"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.RuleName", - to: "rule.name", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 24 - ClipboardChange (New content in the clipboard). - var event24 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 25 - ProcessTampering (Process image change). - var event25 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 255 - Error report. - var event255 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ID", - to: "error.code", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - return { - 1: event1.Run, - 2: event2.Run, - 3: event3.Run, - 4: event4.Run, - 5: event5.Run, - 6: event6.Run, - 7: event7.Run, - 8: event8.Run, - 9: event9.Run, - 10: event10.Run, - 11: event11.Run, - 12: event12.Run, - 13: event13.Run, - 14: event14.Run, - 15: event15.Run, - 16: event16.Run, - 17: event17.Run, - 18: event18.Run, - 19: event19.Run, - 20: event20.Run, - 21: event21.Run, - 22: event22.Run, - 23: event23.Run, - 24: event24.Run, - 25: event25.Run, - 255: event255.Run, - - process: function (evt) { - var event_id = evt.Get("winlog.event_id"); - var processor = this[event_id]; - if (processor === undefined) { - throw "unexpected sysmon event_id"; - } - evt.Put("event.module", "sysmon"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return sysmon.process(evt); -} diff --git a/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml b/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml new file mode 100644 index 000000000000..db28eb13cf78 --- /dev/null +++ b/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml @@ -0,0 +1,1253 @@ +--- +description: Pipeline for Windows Sysmon Event Logs +processors: +## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - rename: + field: winlog.level + target_field: log.level + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + target_field: event.created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + - date: + field: winlog.event_data.UtcTime + formats: + - yyyy-MM-dd HH:mm:ss.SSS + timezone: UTC + ignore_failure: true + if: ctx?.winlog?.event_data?.UtcTime != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + + - script: + description: Set event category and type for all event types. + lang: painless + params: + "1": + category: + - process + type: + - start + "2": + category: + - file + type: + - change + "3": + category: + - network + type: + - start + - connection + - protocol + "4": + category: + - process + type: + - change + "5": + category: + - process + type: + - end + "6": + category: + - driver + type: + - start + "7": + category: + - process + type: + - change + "10": + category: + - process + type: + - access + "11": + category: + - file + type: + - creation + "12": + category: + - configuration + - registry + type: + - change + "13": + category: + - configuration + - registry + type: + - change + "14": + category: + - configuration + - registry + type: + - change + "15": + category: + - file + type: + - access + "16": + category: + - configuration + type: + - change + "17": + category: + - file + type: + - creation + "18": + category: + - file + type: + - access + "22": + category: + - network + type: + - connection + - protocol + - info + "23": + category: + - file + type: + - deletion + "24": + type: + - change + "25": + category: + - process + type: + - change + tag: Add ECS categorization fields + source: |- + if (ctx?.event?.code == null || params.get(ctx.event.code) == null) { + return; + } + def hm = new HashMap(params[ctx.event.code]); + hm.forEach((k, v) -> ctx.event[k] = v); + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + - rename: + field: winlog.event_data.ID + target_field: error.code + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "255" && ctx.winlog?.event_data?.ID != null && ctx.winlog?.event_data?.ID != "" + + - rename: + field: winlog.event_data.RuleName + target_field: rule.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RuleName != null && ctx?.winlog?.event_data?.RuleName != "" && ctx?.winlog?.event_data?.RuleName != "-" + + + - rename: + field: winlog.event_data.Type + target_field: message + ignore_missing: true + ignore_failure: true + if: ctx.event.code == "25" && ctx?.winlog?.event_data?.Type != null && ctx?.winlog?.event_data?.Type != "" + + - rename: + field: winlog.event_data.Hash + target_field: winlog.event_data.Hashes + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Hash != null && ctx?.winlog?.event_data?.Hash != "" + - kv: + field: winlog.event_data.Hashes + target_field: _temp.hashes + field_split: "," + value_split: "=" + ignore_failure: true + if: ctx?.winlog?.event_data?.Hashes != null + - script: + lang: painless + if: ctx?._temp?.hashes != null + source: |- + def hashIsEmpty(String hash) { + if (hash == "") { + return true; + } + + Pattern emptyHashRegex = /^0*$/; + def matcher = emptyHashRegex.matcher(hash); + + return matcher.matches(); + } + + def hashes = new HashMap(); + def related = [ + "hash": new ArrayList() + ]; + for (entry in ctx._temp.hashes.entrySet()) { + def key = entry.getKey().toString().toLowerCase(); + def value = entry.getValue().toString().toLowerCase(); + + if (hashIsEmpty(value)) { + continue; + } + + hashes[key] = value; + related.hash.add(value); + } + + ctx._temp.hashes = hashes; + if (related.hash.length > 0) { + ctx.related = related; + } + +## Process fields + + - rename: + field: _temp.hashes + target_field: process.hash + if: |- + ctx?._temp?.hashes != null && + ["1", "23", "24", "25"].contains(ctx.event.code) + - rename: + field: process.hash.imphash + target_field: process.pe.imphash + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.ProcessGuid + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ProcessGuid != null && ctx?.winlog?.event_data?.ProcessGuid != "" + - convert: + field: winlog.event_data.ProcessId + target_field: process.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ProcessId != null && ctx?.winlog?.event_data?.ProcessId != "" + - rename: + field: winlog.event_data.Image + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Image != null && ctx?.winlog?.event_data?.Image != "" + - rename: + field: winlog.event_data.SourceProcessGuid + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceProcessGuid != null && ctx?.winlog?.event_data?.SourceProcessGuid != "" + - rename: + field: winlog.event_data.SourceProcessGUID + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceProcessGUID != null && ctx?.winlog?.event_data?.SourceProcessGUID != "" + - convert: + field: winlog.event_data.SourceProcessId + target_field: process.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceProcessId != null && ctx?.winlog?.event_data?.SourceProcessId != "" + - convert: + field: winlog.event_data.SourceThreadId + target_field: process.thread.id + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceThreadId != null && ctx?.winlog?.event_data?.SourceThreadId != "" + - rename: + field: winlog.event_data.SourceImage + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceImage != null && ctx?.winlog?.event_data?.SourceImage != "" + - rename: + field: winlog.event_data.Destination + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Destination != null && ctx?.winlog?.event_data?.Destination != "" + - rename: + field: winlog.event_data.CommandLine + target_field: process.command_line + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.CommandLine != null && ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CurrentDirectory + target_field: process.working_directory + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.CurrentDirectory != null && ctx?.winlog?.event_data?.CurrentDirectory != "" + - rename: + field: winlog.event_data.ParentProcessGuid + target_field: process.parent.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentProcessGuid != null && ctx?.winlog?.event_data?.ParentProcessGuid != "" + - convert: + field: winlog.event_data.ParentProcessId + target_field: process.parent.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ParentProcessId != null && ctx?.winlog?.event_data?.ParentProcessId != "" + - rename: + field: winlog.event_data.ParentImage + target_field: process.parent.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentImage != null && ctx?.winlog?.event_data?.ParentImage != "" + - rename: + field: winlog.event_data.ParentCommandLine + target_field: process.parent.command_line + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentCommandLine != null && ctx?.winlog?.event_data?.ParentCommandLine != "" + - rename: + field: winlog.event_data.OriginalFileName + target_field: process.pe.original_file_name + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "7" && ctx?.winlog?.event_data?.OriginalFileName != null && ctx?.winlog?.event_data?.OriginalFileName != "" + - set: + field: process.pe.company + copy_from: winlog.event_data.Company + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.description + copy_from: winlog.event_data.Description + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.file_version + copy_from: winlog.event_data.FileVersion + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.product + copy_from: winlog.event_data.Product + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: |- + (ctx?.process?.command_line != null && ctx.process.command_line != "") || + (ctx?.process?.parent?.command_line != null && ctx.process.parent.command_line != "") + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + def cmd = ctx?.process?.command_line; + if (cmd != null && cmd != "") { + ctx.process.args = commandLineToArgv(cmd); + ctx.process.args_count = ctx.process.args.length; + } + + def parentCmd = ctx?.process?.parent?.command_line; + if (parentCmd != null && parentCmd != "") { + ctx.process.parent.args = commandLineToArgv(parentCmd); + ctx.process.parent.args_count = ctx.process.parent.args.length; + } + + - script: + description: Adds process name information. + lang: painless + if: |- + (ctx?.process?.executable != null && ctx.process.executable.length() > 1) || + (ctx?.process?.parent?.executable != null && ctx.process.parent.executable.length() > 1) + source: |- + def getProcessName(def path) { + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + return path.substring(idx+1); + } + return ""; + } + + def cmd = ctx?.process?.executable; + if (cmd != null && cmd != "" && ctx?.process?.name == null) { + def name = getProcessName(cmd); + if (name != "") { + ctx.process.name = name; + } + } + + def parentCmd = ctx?.process?.parent?.executable; + if (parentCmd != null && parentCmd != "" && ctx?.process?.parent?.name == null) { + def name = getProcessName(parentCmd); + if (name != "") { + ctx.process.parent.name = name; + } + } + +## File fields + + - rename: + field: _temp.hashes + target_field: file.hash + if: |- + ctx?._temp?.hashes != null && + ["6", "7", "15"].contains(ctx.event.code) + - rename: + field: file.hash.imphash + target_field: file.pe.imphash + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.TargetFilename + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.TargetFilename != null && ctx?.winlog?.event_data?.TargetFilename != "" + - rename: + field: winlog.event_data.Device + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Device != null && ctx?.winlog?.event_data?.Device != "" + - rename: + field: winlog.event_data.PipeName + target_field: file.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipeName != null && ctx?.winlog?.event_data?.PipeName != "" + - rename: + field: winlog.event_data.ImageLoaded + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ImageLoaded != null && ctx?.winlog?.event_data?.ImageLoaded != "" + - set: + field: file.code_signature.subject_name + copy_from: winlog.event_data.Signature + ignore_failure: true + ignore_empty_value: true + - set: + field: file.code_signature.status + copy_from: winlog.event_data.SignatureStatus + ignore_failure: true + ignore_empty_value: true + - rename: + field: winlog.event_data.OriginalFileName + target_field: file.pe.original_file_name + ignore_missing: true + ignore_failure: true + if: ctx.event.code == "7" && ctx?.winlog?.event_data?.OriginalFileName != null && ctx?.winlog?.event_data?.OriginalFileName != "" + - set: + field: file.pe.company + copy_from: winlog.event_data.Company + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.description + copy_from: winlog.event_data.Description + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.file_version + copy_from: winlog.event_data.FileVersion + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.product + copy_from: winlog.event_data.Product + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.code_signature.signed + value: true + if: ctx?.winlog?.event_data?.Signed != null && ctx.winlog.event_data.Signed == true + - set: + field: file.code_signature.valid + value: true + if: ctx?.winlog?.event_data?.SignatureStatus != null && ctx?.winlog?.event_data?.SignatureStatus == "Valid" + + - script: + description: Adds file information. + lang: painless + if: ctx?.file?.path != null && ctx.file.path.length() > 1 + source: |- + def path = ctx.file.path; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + +## Network, Destination, and Source fields + + - rename: + field: winlog.event_data.Protocol + target_field: network.transport + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Protocol != null && ctx?.winlog?.event_data?.Protocol != "" + - rename: + field: winlog.event_data.DestinationPortName + target_field: network.protocol + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "22" && ctx?.winlog?.event_data?.DestinationPortName != null && ctx?.winlog?.event_data?.DestinationPortName != "" + - rename: + field: winlog.event_data.SourcePortName + target_field: network.protocol + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "22" && ctx?.winlog?.event_data?.SourcePortName != null && ctx?.winlog?.event_data?.SourcePortName != "" + - set: + field: network.protocol + value: dns + if: ctx.event.code == "22" + - convert: + field: winlog.event_data.SourceIp + target_field: source.ip + type: ip + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceIp != null && ctx?.winlog?.event_data?.SourceIp != "" + - rename: + field: winlog.event_data.SourceHostname + target_field: source.domain + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceHostname != null && ctx?.winlog?.event_data?.SourceHostname != "" + - convert: + field: winlog.event_data.SourcePort + target_field: source.port + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourcePort != null && ctx?.winlog?.event_data?.SourcePort != "" + - convert: + field: winlog.event_data.DestinationIp + target_field: destination.ip + type: ip + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DestinationIp != null && ctx?.winlog?.event_data?.DestinationIp != "" + - rename: + field: winlog.event_data.DestinationHostname + target_field: destination.domain + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.DestinationHostname != null && ctx?.winlog?.event_data?.DestinationHostname != "" + - convert: + field: winlog.event_data.DestinationPort + target_field: destination.port + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DestinationPort != null && ctx?.winlog?.event_data?.DestinationPort != "" + - rename: + field: winlog.event_data.QueryName + target_field: dns.question.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.QueryName != null && ctx?.winlog?.event_data?.QueryName != "" + - set: + field: network.direction + value: egress + if: ctx?.winlog?.event_data?.Initiated != null && ctx?.winlog?.event_data?.Initiated == "true" + - set: + field: network.direction + value: ingress + if: ctx?.winlog?.event_data?.Initiated != null && ctx?.winlog?.event_data?.Initiated == "false" + - set: + field: network.type + value: ipv4 + if: ctx?.winlog?.event_data?.SourceIsIpv6 != null && ctx?.winlog?.event_data?.SourceIsIpv6 == "false" + - set: + field: network.type + value: ipv6 + if: ctx?.winlog?.event_data?.SourceIsIpv6 != null && ctx?.winlog?.event_data?.SourceIsIpv6 == "true" + - script: + description: | + Splits the QueryResults field that contains the DNS responses. + Example: "type: 5 f2.taboola.map.fastly.net;::ffff:151.101.66.2;::ffff:151.101.130.2;::ffff:151.101.194.2;::ffff:151.101.2.2;" + lang: painless + if: ctx?.winlog?.event_data?.QueryResults != null && ctx?.winlog?.event_data?.QueryResults != "" + params: + "1": "A" + "2": "NS" + "3": "MD" + "4": "MF" + "5": "CNAME" + "6": "SOA" + "7": "MB" + "8": "MG" + "9": "MR" + "10": "NULL" + "11": "WKS" + "12": "PTR" + "13": "HINFO" + "14": "MINFO" + "15": "MX" + "16": "TXT" + "17": "RP" + "18": "AFSDB" + "19": "X25" + "20": "ISDN" + "21": "RT" + "22": "NSAP" + "23": "NSAPPTR" + "24": "SIG" + "25": "KEY" + "26": "PX" + "27": "GPOS" + "28": "AAAA" + "29": "LOC" + "30": "NXT" + "31": "EID" + "32": "NIMLOC" + "33": "SRV" + "34": "ATMA" + "35": "NAPTR" + "36": "KX" + "37": "CERT" + "38": "A6" + "39": "DNAME" + "40": "SINK" + "41": "OPT" + "43": "DS" + "46": "RRSIG" + "47": "NSEC" + "48": "DNSKEY" + "49": "DHCID" + "100": "UINFO" + "101": "UID" + "102": "GID" + "103": "UNSPEC" + "248": "ADDRS" + "249": "TKEY" + "250": "TSIG" + "251": "IXFR" + "252": "AXFR" + "253": "MAILB" + "254": "MAILA" + "255": "ANY" + "65281": "WINS" + "65282": "WINSR" + source: |- + def results = /;/.split(ctx.winlog.event_data.QueryResults); + def answers = new ArrayList(); + def ips = new ArrayList(); + def relatedHosts = new ArrayList(); + for (def i = 0; i < results.length; i++) { + def answer = results[i]; + if (answer == "") { + continue; + } + + if (answer.startsWith("type:")) { + def parts = /\s+/.split(answer); + if (parts.length != 3) { + throw new Exception("unexpected QueryResult format"); + } + + answers.add([ + "type": params[parts[1]], + "data": parts[2] + ]); + relatedHosts.add(parts[2]); + } else { + answer = answer.replace("::ffff:", ""); + ips.add(answer); + } + } + + if (answers.length > 0) { + ctx.dns.answers = answers; + } + if (ips.length > 0) { + ctx.dns.resolved_ip = ips; + } + if (relatedHosts.length > 0) { + if (ctx?.related == null) { + ctx.related = new HashMap(); + } + ctx.related.hosts = relatedHosts; + } + - foreach: + field: dns.resolved_ip + ignore_missing: true + processor: + convert: + field: _ingest._value + type: ip + on_failure: + - remove: + field: _ingest._value + - script: + description: Convert V4MAPPED addresses. + lang: painless + if: ctx?.dns?.resolved_ip != null + source: |- + if (ctx.dns.answers == null) { + ctx.dns.answers = new ArrayList(); + } + for (def i = 0; i < ctx.dns.resolved_ip.length; i++) { + def ip = ctx.dns.resolved_ip[i]; + if (ip == null) { + ctx.dns.resolved_ip.remove(i); + continue; + } + + // Synthesize record type based on IP address type. + def type = "A"; + if (ip.indexOf(":") != -1) { + type = "AAAA"; + } + ctx.dns.answers.add([ + "type": type, + "data": ip + ]); + } + - registered_domain: + field: dns.question.name + target_field: dns.question + ignore_failure: true + ignore_missing: true + - append: + field: related.hosts + value: "{{dns.question.name}}" + allow_duplicates: false + if: ctx?.dns?.question?.name != null && ctx?.dns?.question?.name != "" + - remove: + description: Remove dns.question.domain because it is not part of ECS and is redundant with dns.question.name. + field: dns.question.domain + ignore_missing: true + ignore_failure: true + - foreach: + field: dns.resolved_ip + ignore_missing: true + processor: + append: + field: related.ip + value: "{{_ingest._value}}" + allow_duplicates: false + ignore_failure: true + - community_id: + ignore_failure: true + ignore_missing: false + +## User fields + + - set: + field: user.id + copy_from: winlog.user.identifier + ignore_empty_value: true + ignore_failure: true + - split: + field: winlog.event_data.User + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.User != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + +## Sysmon fields + + - rename: + field: winlog.event_data.QueryStatus + target_field: sysmon.dns.status + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.QueryStatus != null && ctx?.winlog?.event_data?.QueryStatus != "" + - script: + description: Translate DNS Query status. + lang: painless + params: + "5": "ERROR_ACCESS_DENIED" + "0": "SUCCESS" + "8": "ERROR_NOT_ENOUGH_MEMORY" + "13": "ERROR_INVALID_DATA" + "14": "ERROR_OUTOFMEMORY" + "123": "ERROR_INVALID_NAME" + "1214": "ERROR_INVALID_NETNAME" + "1223": "ERROR_CANCELLED" + "1460": "ERROR_TIMEOUT" + "4312": "ERROR_OBJECT_NOT_FOUND" + "9001": "DNS_ERROR_RCODE_FORMAT_ERROR" + "9002": "DNS_ERROR_RCODE_SERVER_FAILURE" + "9003": "DNS_ERROR_RCODE_NAME_ERROR" + "9004": "DNS_ERROR_RCODE_NOT_IMPLEMENTED" + "9005": "DNS_ERROR_RCODE_REFUSED" + "9006": "DNS_ERROR_RCODE_YXDOMAIN" + "9007": "DNS_ERROR_RCODE_YXRRSET" + "9008": "DNS_ERROR_RCODE_NXRRSET" + "9009": "DNS_ERROR_RCODE_NOTAUTH" + "9010": "DNS_ERROR_RCODE_NOTZONE" + "9016": "DNS_ERROR_RCODE_BADSIG" + "9017": "DNS_ERROR_RCODE_BADKEY" + "9018": "DNS_ERROR_RCODE_BADTIME" + "9101": "DNS_ERROR_KEYMASTER_REQUIRED" + "9102": "DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE" + "9103": "DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1" + "9104": "DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS" + "9105": "DNS_ERROR_UNSUPPORTED_ALGORITHM" + "9106": "DNS_ERROR_INVALID_KEY_SIZE" + "9107": "DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE" + "9108": "DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION" + "9109": "DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR" + "9110": "DNS_ERROR_UNEXPECTED_CNG_ERROR" + "9111": "DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION" + "9112": "DNS_ERROR_KSP_NOT_ACCESSIBLE" + "9113": "DNS_ERROR_TOO_MANY_SKDS" + "9114": "DNS_ERROR_INVALID_ROLLOVER_PERIOD" + "9115": "DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET" + "9116": "DNS_ERROR_ROLLOVER_IN_PROGRESS" + "9117": "DNS_ERROR_STANDBY_KEY_NOT_PRESENT" + "9118": "DNS_ERROR_NOT_ALLOWED_ON_ZSK" + "9119": "DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD" + "9120": "DNS_ERROR_ROLLOVER_ALREADY_QUEUED" + "9121": "DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE" + "9122": "DNS_ERROR_BAD_KEYMASTER" + "9123": "DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD" + "9124": "DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT" + "9125": "DNS_ERROR_DNSSEC_IS_DISABLED" + "9126": "DNS_ERROR_INVALID_XML" + "9127": "DNS_ERROR_NO_VALID_TRUST_ANCHORS" + "9128": "DNS_ERROR_ROLLOVER_NOT_POKEABLE" + "9129": "DNS_ERROR_NSEC3_NAME_COLLISION" + "9130": "DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1" + "9501": "DNS_INFO_NO_RECORDS" + "9502": "DNS_ERROR_BAD_PACKET" + "9503": "DNS_ERROR_NO_PACKET" + "9504": "DNS_ERROR_RCODE" + "9505": "DNS_ERROR_UNSECURE_PACKET" + "9506": "DNS_REQUEST_PENDING" + "9551": "DNS_ERROR_INVALID_TYPE" + "9552": "DNS_ERROR_INVALID_IP_ADDRESS" + "9553": "DNS_ERROR_INVALID_PROPERTY" + "9554": "DNS_ERROR_TRY_AGAIN_LATER" + "9555": "DNS_ERROR_NOT_UNIQUE" + "9556": "DNS_ERROR_NON_RFC_NAME" + "9557": "DNS_STATUS_FQDN" + "9558": "DNS_STATUS_DOTTED_NAME" + "9559": "DNS_STATUS_SINGLE_PART_NAME" + "9560": "DNS_ERROR_INVALID_NAME_CHAR" + "9561": "DNS_ERROR_NUMERIC_NAME" + "9562": "DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER" + "9563": "DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION" + "9564": "DNS_ERROR_CANNOT_FIND_ROOT_HINTS" + "9565": "DNS_ERROR_INCONSISTENT_ROOT_HINTS" + "9566": "DNS_ERROR_DWORD_VALUE_TOO_SMALL" + "9567": "DNS_ERROR_DWORD_VALUE_TOO_LARGE" + "9568": "DNS_ERROR_BACKGROUND_LOADING" + "9569": "DNS_ERROR_NOT_ALLOWED_ON_RODC" + "9570": "DNS_ERROR_NOT_ALLOWED_UNDER_DNAME" + "9571": "DNS_ERROR_DELEGATION_REQUIRED" + "9572": "DNS_ERROR_INVALID_POLICY_TABLE" + "9573": "DNS_ERROR_ADDRESS_REQUIRED" + "9601": "DNS_ERROR_ZONE_DOES_NOT_EXIST" + "9602": "DNS_ERROR_NO_ZONE_INFO" + "9603": "DNS_ERROR_INVALID_ZONE_OPERATION" + "9604": "DNS_ERROR_ZONE_CONFIGURATION_ERROR" + "9605": "DNS_ERROR_ZONE_HAS_NO_SOA_RECORD" + "9606": "DNS_ERROR_ZONE_HAS_NO_NS_RECORDS" + "9607": "DNS_ERROR_ZONE_LOCKED" + "9608": "DNS_ERROR_ZONE_CREATION_FAILED" + "9609": "DNS_ERROR_ZONE_ALREADY_EXISTS" + "9610": "DNS_ERROR_AUTOZONE_ALREADY_EXISTS" + "9611": "DNS_ERROR_INVALID_ZONE_TYPE" + "9612": "DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP" + "9613": "DNS_ERROR_ZONE_NOT_SECONDARY" + "9614": "DNS_ERROR_NEED_SECONDARY_ADDRESSES" + "9615": "DNS_ERROR_WINS_INIT_FAILED" + "9616": "DNS_ERROR_NEED_WINS_SERVERS" + "9617": "DNS_ERROR_NBSTAT_INIT_FAILED" + "9618": "DNS_ERROR_SOA_DELETE_INVALID" + "9619": "DNS_ERROR_FORWARDER_ALREADY_EXISTS" + "9620": "DNS_ERROR_ZONE_REQUIRES_MASTER_IP" + "9621": "DNS_ERROR_ZONE_IS_SHUTDOWN" + "9622": "DNS_ERROR_ZONE_LOCKED_FOR_SIGNING" + "9651": "DNS_ERROR_PRIMARY_REQUIRES_DATAFILE" + "9652": "DNS_ERROR_INVALID_DATAFILE_NAME" + "9653": "DNS_ERROR_DATAFILE_OPEN_FAILURE" + "9654": "DNS_ERROR_FILE_WRITEBACK_FAILED" + "9655": "DNS_ERROR_DATAFILE_PARSING" + "9701": "DNS_ERROR_RECORD_DOES_NOT_EXIST" + "9702": "DNS_ERROR_RECORD_FORMAT" + "9703": "DNS_ERROR_NODE_CREATION_FAILED" + "9704": "DNS_ERROR_UNKNOWN_RECORD_TYPE" + "9705": "DNS_ERROR_RECORD_TIMED_OUT" + "9706": "DNS_ERROR_NAME_NOT_IN_ZONE" + "9707": "DNS_ERROR_CNAME_LOOP" + "9708": "DNS_ERROR_NODE_IS_CNAME" + "9709": "DNS_ERROR_CNAME_COLLISION" + "9710": "DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT" + "9711": "DNS_ERROR_RECORD_ALREADY_EXISTS" + "9712": "DNS_ERROR_SECONDARY_DATA" + "9713": "DNS_ERROR_NO_CREATE_CACHE_DATA" + "9714": "DNS_ERROR_NAME_DOES_NOT_EXIST" + "9715": "DNS_WARNING_PTR_CREATE_FAILED" + "9716": "DNS_WARNING_DOMAIN_UNDELETED" + "9717": "DNS_ERROR_DS_UNAVAILABLE" + "9718": "DNS_ERROR_DS_ZONE_ALREADY_EXISTS" + "9719": "DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE" + "9720": "DNS_ERROR_NODE_IS_DNAME" + "9721": "DNS_ERROR_DNAME_COLLISION" + "9722": "DNS_ERROR_ALIAS_LOOP" + "9751": "DNS_INFO_AXFR_COMPLETE" + "9752": "DNS_ERROR_AXFR" + "9753": "DNS_INFO_ADDED_LOCAL_WINS" + "9801": "DNS_STATUS_CONTINUE_NEEDED" + "9851": "DNS_ERROR_NO_TCPIP" + "9852": "DNS_ERROR_NO_DNS_SERVERS" + "9901": "DNS_ERROR_DP_DOES_NOT_EXIST" + "9902": "DNS_ERROR_DP_ALREADY_EXISTS" + "9903": "DNS_ERROR_DP_NOT_ENLISTED" + "9904": "DNS_ERROR_DP_ALREADY_ENLISTED" + "9905": "DNS_ERROR_DP_NOT_AVAILABLE" + "9906": "DNS_ERROR_DP_FSMO_ERROR" + "9911": "DNS_ERROR_RRL_NOT_ENABLED" + "9912": "DNS_ERROR_RRL_INVALID_WINDOW_SIZE" + "9913": "DNS_ERROR_RRL_INVALID_IPV4_PREFIX" + "9914": "DNS_ERROR_RRL_INVALID_IPV6_PREFIX" + "9915": "DNS_ERROR_RRL_INVALID_TC_RATE" + "9916": "DNS_ERROR_RRL_INVALID_LEAK_RATE" + "9917": "DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE" + "9921": "DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS" + "9922": "DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST" + "9923": "DNS_ERROR_VIRTUALIZATION_TREE_LOCKED" + "9924": "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME" + "9925": "DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE" + "9951": "DNS_ERROR_ZONESCOPE_ALREADY_EXISTS" + "9952": "DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST" + "9953": "DNS_ERROR_DEFAULT_ZONESCOPE" + "9954": "DNS_ERROR_INVALID_ZONESCOPE_NAME" + "9955": "DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES" + "9956": "DNS_ERROR_LOAD_ZONESCOPE_FAILED" + "9957": "DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED" + "9958": "DNS_ERROR_INVALID_SCOPE_NAME" + "9959": "DNS_ERROR_SCOPE_DOES_NOT_EXIST" + "9960": "DNS_ERROR_DEFAULT_SCOPE" + "9961": "DNS_ERROR_INVALID_SCOPE_OPERATION" + "9962": "DNS_ERROR_SCOPE_LOCKED" + "9963": "DNS_ERROR_SCOPE_ALREADY_EXISTS" + "9971": "DNS_ERROR_POLICY_ALREADY_EXISTS" + "9972": "DNS_ERROR_POLICY_DOES_NOT_EXIST" + "9973": "DNS_ERROR_POLICY_INVALID_CRITERIA" + "9974": "DNS_ERROR_POLICY_INVALID_SETTINGS" + "9975": "DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED" + "9976": "DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST" + "9977": "DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS" + "9978": "DNS_ERROR_SUBNET_DOES_NOT_EXIST" + "9979": "DNS_ERROR_SUBNET_ALREADY_EXISTS" + "9980": "DNS_ERROR_POLICY_LOCKED" + "9981": "DNS_ERROR_POLICY_INVALID_WEIGHT" + "9982": "DNS_ERROR_POLICY_INVALID_NAME" + "9983": "DNS_ERROR_POLICY_MISSING_CRITERIA" + "9984": "DNS_ERROR_INVALID_CLIENT_SUBNET_NAME" + "9985": "DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID" + "9986": "DNS_ERROR_POLICY_SCOPE_MISSING" + "9987": "DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED" + "9988": "DNS_ERROR_SERVERSCOPE_IS_REFERENCED" + "9989": "DNS_ERROR_ZONESCOPE_IS_REFERENCED" + "9990": "DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET" + "9991": "DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL" + "9992": "DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL" + "9993": "DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE" + "9994": "DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN" + "9995": "DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE" + "9996": "DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY" + "10054": "WSAECONNRESET" + "10055": "WSAENOBUFS" + "10060": "WSAETIMEDOUT" + if: ctx?.sysmon?.dns?.status != null && ctx?.sysmon?.dns?.status != "" + source: |- + def status = params[ctx.sysmon.dns.status]; + if (status != null) { + ctx.sysmon.dns.status = status; + } + - convert: + field: winlog.event_data.Archived + target_field: sysmon.file.archived + type: boolean + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Archived != null && ctx?.winlog?.event_data?.Archived != "" + - convert: + field: winlog.event_data.IsExecutable + target_field: sysmon.file.is_executable + type: boolean + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.IsExecutable != null && ctx?.winlog?.event_data?.IsExecutable != "" + +## Related fields + + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null && ctx.user.name != "" + - append: + field: related.ip + value: "{{source.ip}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.source?.ip != null && ctx.source.ip != "" + - append: + field: related.ip + value: "{{destination.ip}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.destination?.ip != null && ctx.destination.ip != "" + +## Registry fields + + - script: + description: Set registry fields. + lang: painless + if: |- + ctx?.winlog?.event_data?.TargetObject != null && ctx?.winlog?.event_data?.TargetObject != "" && + ["12", "13", "14"].contains(ctx.event.code) + params: + HKEY_CLASSES_ROOT: "HKCR" + HKCR: "HKCR" + HKEY_CURRENT_CONFIG: "HKCC" + HKCC: "HKCC" + HKEY_CURRENT_USER: "HKCU" + HKCU: "HKCU" + HKEY_DYN_DATA: "HKDD" + HKDD: "HKDD" + HKEY_LOCAL_MACHINE: "HKLM" + HKLM: "HKLM" + HKEY_PERFORMANCE_DATA: "HKPD" + HKPD: "HKPD" + HKEY_USERS: "HKU" + HKU: "HKU" + source: |- + ctx.registry = new HashMap(); + Pattern qwordRegex = /(?i)QWORD \(((0x\d{8})-(0x\d{8}))\)/; + Pattern dwordRegex = /(?i)DWORD \((0x\d{8})\)/; + + def path = ctx.winlog.event_data.TargetObject; + ctx.registry.path = path; + + def pathTokens = Arrays.asList(/\\/.split(path)); + def hive = params[pathTokens[0]]; + if (hive != null) { + ctx.registry.hive = hive; + if (pathTokens.length > 1) { + ctx.registry.key = pathTokens.subList(1, pathTokens.length).join("\\"); + } + } + + def value = pathTokens[pathTokens.length - 1]; + ctx.registry.value = value; + + def data = ctx?.winlog?.event_data?.Details; + if (data != null && data != "") { + def prefixLen = 2; // to remove 0x prefix + def dataValue = ""; + def dataType = ""; + def matcher = qwordRegex.matcher(data); + if (matcher.matches()) { + def parsedHighByte = Long.parseLong(matcher.group(2).substring(prefixLen), 16); + def parsedLowByte = Long.parseLong(matcher.group(3).substring(prefixLen), 16); + if (!Double.isNaN(parsedHighByte) && !Double.isNaN(parsedLowByte)) { + dataType = "SZ_QWORD"; + dataValue = Long.toString(((parsedHighByte << 8) + parsedLowByte)); + } + } else { + matcher = dwordRegex.matcher(data); + if (matcher.matches()) { + def parsedValue = Long.parseLong(matcher.group(1).substring(prefixLen), 16); + if (!Double.isNaN(parsedValue)) { + dataType = "SZ_DWORD"; + dataValue = matcher.group(1); + } + } + } + + if (dataType != "") { + ctx.registry.data = [ + "strings": [dataValue], + "type": dataType + ]; + } + } + +## Cleanup + + - remove: + field: + - _temp + - winlog.event_data.ProcessId + - winlog.event_data.ParentProcessId + - winlog.event_data.SourceProcessId + - winlog.event_data.SourceThreadId + - winlog.event_data.SourceIp + - winlog.event_data.SourcePort + - winlog.event_data.SourcePortName + - winlog.event_data.DestinationIp + - winlog.event_data.DestinationPort + - winlog.event_data.DestinationPortName + - winlog.event_data.RuleName + - winlog.event_data.User + - winlog.event_data.Initiated + - winlog.event_data.SourceIsIpv6 + - winlog.event_data.DestinationIsIpv6 + - winlog.event_data.QueryStatus + - winlog.event_data.Archived + - winlog.event_data.IsExecutable + - winlog.event_data.QueryResults + - winlog.event_data.UtcTime + - winlog.event_data.Hash + - winlog.event_data.Hashes + - winlog.event_data.TargetObject + - winlog.event_data.Details + - winlog.time_created + - winlog.level + ignore_failure: true + ignore_missing: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("") || entry.getValue().equals("-")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go b/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go deleted file mode 100644 index 1f4d78ad017c..000000000000 --- a/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields so that the tests will pass if Sysmon is not installed. -var ignoreFields = []string{ - "event.action", - "message", - "winlog.opcode", - "winlog.task", - - // Ignore these fields as under some circumstances they are not populated. - // (observed under Windows 7). - "winlog.user.type", - "winlog.user.name", - "winlog.user.domain", -} - -func TestSysmon(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-sysmon.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index d74e971638a3..0868d8c8027a 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -20,6 +20,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. @@ -38,58 +43,17 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js # ================================== General =================================== diff --git a/x-pack/winlogbeat/winlogbeat.yml b/x-pack/winlogbeat/winlogbeat.yml index 15c1e10fdcc3..6ae52cd3f3a6 100644 --- a/x-pack/winlogbeat/winlogbeat.yml +++ b/x-pack/winlogbeat/winlogbeat.yml @@ -27,58 +27,17 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js # ====================== Elasticsearch template settings ======================= @@ -162,6 +121,9 @@ output.elasticsearch: #username: "elastic" #password: "changeme" + # Pipeline to route events to security, sysmon, or powershell pipelines. + pipeline: "winlogbeat-%{[agent.version]}-routing" + # ------------------------------ Logstash Output ------------------------------- #output.logstash: # The Logstash hosts From cb8f4d3c701570abbb5d508e5ab77b869806e803 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 4 Jan 2022 18:45:50 +0100 Subject: [PATCH 143/172] [packaging] Bump golang-crossbuild version debian8 (#23872) --- dev-tools/mage/crossbuild.go | 4 +- x-pack/auditbeat/magefile.go | 97 ------------------------------------ 2 files changed, 2 insertions(+), 99 deletions(-) diff --git a/dev-tools/mage/crossbuild.go b/dev-tools/mage/crossbuild.go index b2349310abc4..9f56fd125c3e 100644 --- a/dev-tools/mage/crossbuild.go +++ b/dev-tools/mage/crossbuild.go @@ -242,8 +242,8 @@ func CrossBuildImage(platform string) (string, error) { tagSuffix = "s390x" case strings.HasPrefix(platform, "linux"): // Use an older version of libc to gain greater OS compatibility. - // Debian 7 uses glibc 2.13. - tagSuffix = "main-debian7" + // Debian 8 uses glibc 2.19. + tagSuffix = "main-debian8" } goVersion, err := GoVersion() diff --git a/x-pack/auditbeat/magefile.go b/x-pack/auditbeat/magefile.go index b2d52ebbcbcf..72253937d475 100644 --- a/x-pack/auditbeat/magefile.go +++ b/x-pack/auditbeat/magefile.go @@ -12,8 +12,6 @@ import ( "time" "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" - "github.com/pkg/errors" auditbeat "github.com/elastic/beats/v7/auditbeat/scripts/mage" devtools "github.com/elastic/beats/v7/dev-tools/mage" @@ -45,9 +43,6 @@ func Build() error { // GolangCrossBuild build the Beat binary inside of the golang-builder. // Do not use directly, use crossBuild instead. func GolangCrossBuild() error { - if d, ok := deps[devtools.Platform.Name]; ok { - mg.Deps(d) - } return devtools.GolangCrossBuild(devtools.DefaultGolangCrossBuildArgs()) } @@ -125,95 +120,3 @@ func ExportDashboard() error { func Dashboards() error { return devtools.KibanaDashboards(devtools.OSSBeatDir("module"), "module") } - -// ----------------------------------------------------------------------------- -// - Install the librpm-dev package -var ( - deps = map[string]func() error{ - "linux/386": installLinux386, - "linux/amd64": installLinuxAMD64, - "linux/arm64": installLinuxARM64, - "linux/armv5": installLinuxARMEL, - "linux/armv6": installLinuxARMEL, - "linux/armv7": installLinuxARMHF, - "linux/mips": installLinuxMIPS, - "linux/mipsle": installLinuxMIPSEL, - "linux/mips64le": installLinuxMIPS64EL, - "linux/ppc64le": installLinuxPPC64EL, - "linux/s390x": installLinuxS390X, - - //"linux/ppc64": installLinuxPpc64, - //"linux/mips64": installLinuxMips64, - } -) - -const ( - librpmDevPkgName = "librpm-dev" - - // Dependency of librpm-dev in ARM architectures, that needs to be explicitly - // installed to replace other conflicting packages pre-installed in the image. - libicuDevPkgName = "libicu-dev" -) - -func installLinuxAMD64() error { - return installDependencies("", librpmDevPkgName) -} - -func installLinuxARM64() error { - return installDependencies("arm64", librpmDevPkgName+":arm64") -} - -func installLinuxARMHF() error { - return installDependencies("armhf", librpmDevPkgName+":armhf", libicuDevPkgName+":armhf") -} - -func installLinuxARMEL() error { - return installDependencies("armel", librpmDevPkgName+":armel", libicuDevPkgName+":armel") -} - -func installLinux386() error { - return installDependencies("i386", librpmDevPkgName+":i386") -} - -func installLinuxMIPS() error { - return installDependencies("mips", librpmDevPkgName+":mips") -} - -func installLinuxMIPS64EL() error { - return installDependencies("mips64el", librpmDevPkgName+":mips64el") -} - -func installLinuxMIPSEL() error { - return installDependencies("mispel", librpmDevPkgName+":mipsel") -} - -func installLinuxPPC64EL() error { - return installDependencies("ppc64el", librpmDevPkgName+":ppc64el") -} - -func installLinuxS390X() error { - return installDependencies("s390x", librpmDevPkgName+":s390x") -} - -func installDependencies(arch string, pkgs ...string) error { - if len(pkgs) == 0 { - return nil - } - if arch != "" { - err := sh.Run("dpkg", "--add-architecture", arch) - if err != nil { - return errors.Wrap(err, "error while adding architecture") - } - } - - // TODO: This is only for debian 7 and should be removed when move to a newer OS. This flag is - // going to be used unnecessary when building using non-debian7 images - // (like when making the linux/arm binaries) and we should remove it soonish. - // See https://github.com/elastic/beats/v7/issues/11750 for more details. - if err := sh.Run("apt-get", "update", "-o", "Acquire::Check-Valid-Until=false"); err != nil { - return err - } - - args := append([]string{"install", "-y", "--no-install-recommends"}, pkgs...) - return sh.Run("apt-get", args...) -} From 827e152b350d63607c84221b1184244bb05c4672 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 4 Jan 2022 12:09:48 -0800 Subject: [PATCH 144/172] Fix example command to avoid showing system module under windows (#29569) --- filebeat/docs/filebeat-modules-options.asciidoc | 2 +- filebeat/docs/getting-started.asciidoc | 9 +++++---- libbeat/docs/tab-widgets/start.asciidoc | 6 +++--- metricbeat/docs/getting-started.asciidoc | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/filebeat/docs/filebeat-modules-options.asciidoc b/filebeat/docs/filebeat-modules-options.asciidoc index bf404588c03f..8c39c56c9a66 100644 --- a/filebeat/docs/filebeat-modules-options.asciidoc +++ b/filebeat/docs/filebeat-modules-options.asciidoc @@ -1,4 +1,4 @@ -:modulename: system nginx mysql +:modulename: nginx [id="configuration-{beatname_lc}-modules"] == Configure modules diff --git a/filebeat/docs/getting-started.asciidoc b/filebeat/docs/getting-started.asciidoc index d51a267b91f2..08f2bc311a5b 100644 --- a/filebeat/docs/getting-started.asciidoc +++ b/filebeat/docs/getting-started.asciidoc @@ -1,4 +1,4 @@ -:modulename: system nginx mysql +:modulename: nginx //TODO: Remove release-state override before merging. @@ -20,6 +20,8 @@ You'll learn how to: [role="screenshot"] image::./images/kibana-system.png[{beatname_uc} System dashboard] +//TODO: We should replace this with an nginx dashboard rather than system + [float] === Before you begin @@ -79,14 +81,13 @@ include::{libbeat-dir}/tab-widgets/list-modules-widget.asciidoc[] -- . From the installation directory, enable one or more modules. For example, the -following command enables the `system`, `nginx`, and `mysql` module -configs: +following command enables the +{modulename}+ module config: + -- include::{libbeat-dir}/tab-widgets/enable-modules-widget.asciidoc[] -- -. In the module configs under `modules.d`, enable the desired datasets and +. In the module config under `modules.d`, enable the desired datasets and change the module settings to match your environment. + For example, log locations are set based on the OS. If your logs aren't in diff --git a/libbeat/docs/tab-widgets/start.asciidoc b/libbeat/docs/tab-widgets/start.asciidoc index 0dd2728d53c0..5882655dec86 100644 --- a/libbeat/docs/tab-widgets/start.asciidoc +++ b/libbeat/docs/tab-widgets/start.asciidoc @@ -45,7 +45,7 @@ ifdef::has_modules_command[] ["source","sh",subs="attributes,callouts"] ---------------------------------------------------------------------- sudo chown root {beatname_lc}.yml <1> -sudo chown root modules.d/system.yml <1> +sudo chown root modules.d/{modulename}.yml <1> sudo ./{beatname_lc} -e ---------------------------------------------------------------------- <1> You'll be running {beatname_uc} as root, so you need to change ownership of the @@ -94,7 +94,7 @@ ifdef::has_modules_command[] ["source","sh",subs="attributes,callouts"] ---------------------------------------------------------------------- sudo chown root /usr/local/etc/{beatname_lc}/{beatname_lc}.yml <1> -sudo chown root /usr/local/etc/{beatname_lc}/modules.d/system.yml <1> +sudo chown root /usr/local/etc/{beatname_lc}/modules.d/{modulename}.yml <1> sudo {beatname_lc} -e ---------------------------------------------------------------------- <1> You'll be running {beatname_uc} as root, so you need to change ownership of the @@ -124,7 +124,7 @@ ifdef::has_modules_command[] ["source","sh",subs="attributes,callouts"] ---------------------------------------------------------------------- sudo chown root {beatname_lc}.yml <1> -sudo chown root modules.d/system.yml <1> +sudo chown root modules.d/{modulename}.yml <1> sudo ./{beatname_lc} -e ---------------------------------------------------------------------- <1> You'll be running {beatname_uc} as root, so you need to change ownership of the diff --git a/metricbeat/docs/getting-started.asciidoc b/metricbeat/docs/getting-started.asciidoc index a300cb43c98d..9cd837dfc423 100644 --- a/metricbeat/docs/getting-started.asciidoc +++ b/metricbeat/docs/getting-started.asciidoc @@ -1,4 +1,4 @@ -:modulename: apache mysql +:modulename: nginx [id="{beatname_lc}-installation-configuration"] == {beatname_uc} quick start: installation and configuration @@ -82,8 +82,8 @@ include::{libbeat-dir}/tab-widgets/list-modules-widget.asciidoc[] default configuration without enabling additional modules, {beatname_uc} collects system metrics only. + -The following command enables the `apache` and `mysql` configs in the -`modules.d` directory: +The following command enables the +{modulename}+ config in the `modules.d` +directory: + -- include::{libbeat-dir}/tab-widgets/enable-modules-widget.asciidoc[] @@ -92,7 +92,7 @@ include::{libbeat-dir}/tab-widgets/enable-modules-widget.asciidoc[] See the <> to learn more about this command. If you are using a Docker image, see <>. -. In the module configs under `modules.d`, change the module settings to match +. In the module config under `modules.d`, change the module settings to match your environment. See <> for more about available settings. From b8cfea6ef601b10fb378b4e51cdde9f2ad84a3b1 Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Wed, 5 Jan 2022 02:14:37 -0500 Subject: [PATCH 145/172] [Automation] Update elastic stack version to 8.1.0-1f83f9c5 for testing (#29702) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index eea246eaeb8c..ac189d5f5bc3 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-c1a942c7-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-1f83f9c5-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-c1a942c7-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-1f83f9c5-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-c1a942c7-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-1f83f9c5-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index ae706a3d2e83..87360a081e1e 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-c1a942c7-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-1f83f9c5-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-c1a942c7-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-1f83f9c5-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 31c009927b0d6c36075b05260e12a1b6240f49f1 Mon Sep 17 00:00:00 2001 From: Michel Laterman <82832767+michel-laterman@users.noreply.github.com> Date: Wed, 5 Jan 2022 13:08:27 -0800 Subject: [PATCH 146/172] Allow elastic agent in containers to use basic auth to get service token (#29651) * Allow elastic agent in containers to use basic auth to get service token Allow the agent to use basic auth defined by env vars to retrieve a service token from Elasticsearch and inject it into the config used for the agent and fleet. * Fix linter * Use Kibana API for all requests. Change from using the ES api to gather the token to the Kibana API. --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../elastic-agent/pkg/agent/cmd/container.go | 56 +++++++++++++++++++ .../pkg/agent/cmd/setup_config.go | 9 +-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 8164397c26eb..40cecf51b90b 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -93,6 +93,7 @@ - Fix lazy acker to only add new actions to the batch. {pull}27981[27981] - Allow HTTP metrics to run in bootstrap mode. Add ability to adjust timeouts for Fleet Server. {pull}28260[28260] - Fix agent configuration overwritten by default fleet config. {pull}29297[29297] +- Allow agent containers to use basic auth to create a service token. {pull}29651[29651] ==== New features diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index f127d972bf10..33f46728b656 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -109,6 +109,8 @@ The following actions are possible and grouped based on the actions. KIBANA_FLEET_SETUP - set to 1 enables the setup of Fleet in Kibana by Elastic Agent. This was previously FLEET_SETUP. KIBANA_FLEET_HOST - Kibana host accessible from fleet-server. [$KIBANA_HOST] + KIBANA_FLEET_USERNAME - kibana username to service token [$KIBANA_USERNAME] + KIBANA_FLEET_PASSWORD - kibana password to service token [$KIBANA_PASSWORD] KIBANA_FLEET_CA - path to certificate authority to use with communicate with Kibana [$KIBANA_CA] KIBANA_REQUEST_RETRY_SLEEP - specifies sleep duration taken when agent performs a request to kibana [default 1s] KIBANA_REQUEST_RETRY_COUNT - specifies number of retries agent performs when executing a request to kibana [default 30] @@ -117,8 +119,12 @@ The following environment variables are provided as a convenience to prevent a l be used when the same credentials will be used across all the possible actions above. ELASTICSEARCH_HOST - elasticsearch host [http://elasticsearch:9200] + ELASTICSEARCH_USERNAME - elasticsearch username [elastic] + ELASTICSEARCH_PASSWORD - elasticsearch password [changeme] ELASTICSEARCH_CA - path to certificate authority to use with communicate with elasticsearch KIBANA_HOST - kibana host [http://kibana:5601] + KIBANA_FLEET_USERNAME - kibana username to enable Fleet [$ELASTICSEARCH_USERNAME] + KIBANA_FLEET_PASSWORD - kibana password to enable Fleet [$ELASTICSEARCH_PASSWORD] KIBANA_CA - path to certificate authority to use with communicate with Kibana [$ELASTICSEARCH_CA] @@ -193,6 +199,11 @@ func containerCmd(streams *cli.IOStreams, cmd *cobra.Command) error { } } + err = ensureServiceToken(streams, &cfg) + if err != nil { + return err + } + // start apm-server legacy process when in cloud mode var wg sync.WaitGroup var apmProc *process.Info @@ -268,6 +279,7 @@ func runContainerCmd(streams *cli.IOStreams, cmd *cobra.Command, cfg setupConfig if err != nil { return err } + logInfo(streams, "Performing setup of Fleet in Kibana\n") err = kibanaSetup(cfg, client, streams) if err != nil { @@ -318,6 +330,48 @@ func runContainerCmd(streams *cli.IOStreams, cmd *cobra.Command, cfg setupConfig return run(streams, logToStderr) } +// TokenResp is used to decode a response for generating a service token +type TokenResp struct { + Name string `json:"name"` + Value string `json:"value"` +} + +// ensureServiceToken will ensure that the cfg specified has the service_token attributes filled. +// +// If no token is specified it will use the elasticsearch username/password to request a new token from Kibana +func ensureServiceToken(streams *cli.IOStreams, cfg *setupConfig) error { + // There's already a service token + if cfg.Kibana.Fleet.ServiceToken != "" || cfg.FleetServer.Elasticsearch.ServiceToken != "" { + return nil + } + if cfg.Kibana.Fleet.Username == "" || cfg.Kibana.Fleet.Password == "" { + return fmt.Errorf("username/password must be provided to retrieve service token") + } + + logInfo(streams, "Requesting service_token from Kibana.") + client, err := kibanaClient(cfg.Kibana, cfg.Kibana.Headers) + if err != nil { + return err + } + + code, r, err := client.Connection.Request("POST", "/api/fleet/service-tokens", nil, nil, nil) + if err != nil { + return fmt.Errorf("request to get security token from Kibana failed: %w", err) + } + if code >= 400 { + return fmt.Errorf("request to get security token from Kibana failed with status %d, body: %s", code, string(r)) + } + t := TokenResp{} + err = json.Unmarshal(r, &t) + if err != nil { + return fmt.Errorf("unable to decode response: %w", err) + } + logInfo(streams, "Created service_token named:", t.Name) + cfg.Kibana.Fleet.ServiceToken = t.Value + cfg.FleetServer.Elasticsearch.ServiceToken = t.Value + return nil +} + func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string, error) { args := []string{ "enroll", "-f", @@ -472,6 +526,8 @@ func kibanaClient(cfg kibanaConfig, headers map[string]string) (*kibana.Client, return kibana.NewClientWithConfigDefault(&kibana.ClientConfig{ Host: cfg.Fleet.Host, + Username: cfg.Fleet.Username, + Password: cfg.Fleet.Password, ServiceToken: cfg.Fleet.ServiceToken, IgnoreVersion: true, Transport: transport, diff --git a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go index 39cf43de28c2..ab163f4b5e79 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/setup_config.go @@ -58,6 +58,8 @@ type kibanaFleetConfig struct { CA string `config:"ca"` Host string `config:"host"` Setup bool `config:"setup"` + Username string `config:"username"` + Password string `config:"password"` ServiceToken string `config:"service_token"` } @@ -104,11 +106,10 @@ func defaultAccessConfig() (setupConfig, error) { }, Kibana: kibanaConfig{ Fleet: kibanaFleetConfig{ - // Remove FLEET_SETUP in 8.x - // The FLEET_SETUP environment variable boolean is a fallback to the old name. The name was updated to - // reflect that its setting up Fleet in Kibana versus setting up Fleet Server. - Setup: envBool("KIBANA_FLEET_SETUP", "FLEET_SETUP"), + Setup: envBool("KIBANA_FLEET_SETUP"), Host: envWithDefault("http://kibana:5601", "KIBANA_FLEET_HOST", "KIBANA_HOST"), + Username: envWithDefault("elastic", "KIBANA_FLEET_USERNAME", "ELASTICSEARCH_USERNAME"), + Password: envWithDefault("changeme", "KIBANA_FLEET_PASSWORD", "ELASTICSEARCH_PASSWORD"), ServiceToken: envWithDefault("", "KIBANA_FLEET_SERVICE_TOKEN", "FLEET_SERVER_SERVICE_TOKEN"), CA: envWithDefault("", "KIBANA_FLEET_CA", "KIBANA_CA", "ELASTICSEARCH_CA"), }, From 1071786b3bc994645e52ba5783103804faf3f3c7 Mon Sep 17 00:00:00 2001 From: Petr Studeny Date: Thu, 6 Jan 2022 01:22:22 +0100 Subject: [PATCH 147/172] docs: reorder kubernetes provider section (#29443) * docs: reorder kubernetes provider configuration setting section * docs: reorder kubernetes provider template configuration intro * docs: fix beatname_lc reference expansion https://asciidoc-py.github.io/userguide.html#X81 Co-authored-by: DeDe Morton * docs: reorder docker provider configuration setting section * docs: reorder jolokia provider configuration setting section reword interfaces items description * docs: reorder nomad provider configuration setting section * docs: reorder nomad provider template configuration intro Co-authored-by: DeDe Morton --- libbeat/docs/shared-autodiscover.asciidoc | 273 +++++++++++----------- 1 file changed, 136 insertions(+), 137 deletions(-) diff --git a/libbeat/docs/shared-autodiscover.asciidoc b/libbeat/docs/shared-autodiscover.asciidoc index 5b863f4307db..40492d1e0ac6 100644 --- a/libbeat/docs/shared-autodiscover.asciidoc +++ b/libbeat/docs/shared-autodiscover.asciidoc @@ -23,6 +23,23 @@ start/stop events. This ensures you don't need to worry about state, but only de The Docker autodiscover provider watches for Docker containers to start and stop. +It has the following settings: + +`host`:: (Optional) Docker socket (UNIX or TCP socket). It uses +`unix:///var/run/docker.sock` by default. +`ssl`:: (Optional) SSL configuration to use when connecting to the Docker +socket. +`cleanup_timeout`:: (Optional) Specify the time of inactivity before stopping the +running configuration for a container, +ifeval::["{beatname_lc}"=="filebeat"] + 60s by default. +endif::[] +ifeval::["{beatname_lc}"!="filebeat"] + disabled by default. +endif::[] +`labels.dedot`:: (Optional) Default to be false. If set to true, replace dots in + labels with `_`. + These are the fields available within config templating. The `docker.*` fields will be available on each emitted event. event: @@ -109,13 +126,24 @@ autodiscover.providers: paths: - "/mnt/logs/${data.docker.container.id}/*.log" ------------------------------------------------------------------------------------- +======================================= +endif::[] -It has the following settings: -`host`:: (Optional) Docker socket (UNIX or TCP socket). It uses -`unix:///var/run/docker.sock` by default. -`ssl`:: (Optional) SSL configuration to use when connecting to the Docker -socket. +[float] +===== Kubernetes + +The Kubernetes autodiscover provider watches for Kubernetes nodes, pods, services to start, update, and stop. + +The `kubernetes` autodiscover provider has the following configuration settings: + +`node`:: (Optional) Specify the node to scope {beatname_lc} to in case it + cannot be accurately detected, as when running {beatname_lc} in host network + mode. +`namespace`:: (Optional) Select the namespace from which to collect the + metadata. If it is not set, the processor collects metadata from all + namespaces. It is unset by default. The namespace configuration only applies to + kubernetes resources that are namespace scoped. `cleanup_timeout`:: (Optional) Specify the time of inactivity before stopping the running configuration for a container, ifeval::["{beatname_lc}"=="filebeat"] @@ -124,17 +152,57 @@ endif::[] ifeval::["{beatname_lc}"!="filebeat"] disabled by default. endif::[] -`labels.dedot`:: (Optional) Default to be false. If set to true, replace dots in - labels with `_`. +`kube_config`:: (Optional) Use given config file as configuration for Kubernetes + client. If kube_config is not set, KUBECONFIG environment variable will be + checked and if not present it will fall back to InCluster. +`kube_client_options`:: (Optional) Additional options can be configured for Kubernetes + client. Currently client QPS and burst are supported, if not set Kubernetes client's + https://pkg.go.dev/k8s.io/client-go/rest#pkg-constants[default QPS and burst] will be used. + Example: +["source","yaml",subs="attributes"] +------------------------------------------------------------------------------------- + kube_client_options: + qps: 5 + burst: 10 +------------------------------------------------------------------------------------- -======================================= -endif::[] +`resource`:: (Optional) Select the resource to do discovery on. Currently supported + Kubernetes resources are `pod`, `service` and `node`. If not configured `resource` + defaults to `pod`. +`scope`:: (Optional) Specify at what level autodiscover needs to be done at. `scope` can + either take `node` or `cluster` as values. `node` scope allows discovery of resources in + the specified node. `cluster` scope allows cluster wide discovery. Only `pod` and `node` resources + can be discovered at node scope. +`add_resource_metadata`:: (Optional) Specify labels and annotations filters for the extra metadata coming from Node and Namespace. + `add_resource_metadata` can be done for `node` or `namespace`. By default all labels will be included + while annotations are not added by default. This settings are useful when labels' and annotations' + storing requires special handling to avoid overloading the storage output. The enrichment of `node` or `namespace` metadata + can be individually disabled by setting `enabled: false`. If resource is `pod` and it is created from a `deployment`, by default + the deployment name is added, this can be disabled by set to `false`. + Example: +["source","yaml",subs="attributes"] +------------------------------------------------------------------------------------- + add_resource_metadata: + namespace: + include_labels: ["namespacelabel1"] + node: + include_labels: ["nodelabel2"] + include_annotations: ["nodeannotation1"] + deployment: false +------------------------------------------------------------------------------------- -[float] -===== Kubernetes +`unique`:: (Optional) Defaults to `false`. Marking an autodiscover provider as unique results into + making the provider to enable the provided templates only when it will gain the leader lease. + This setting can only be combined with `cluster` scope. When `unique` is enabled enabled, `resource` + and `add_resource_metadata` settings are not taken into account. +`leader_lease`:: (Optional) Defaults to +{beatname_lc}-cluster-leader+. This will be name of the lock lease. + One can monitor the status of the lease with `kubectl describe lease beats-cluster-leader`. + Different Beats that refer to the same leader lease will be competitors in holding the lease + and only one will be elected as leader each time. -The Kubernetes autodiscover provider watches for Kubernetes nodes, pods, services to start, update, and stop. +The configuration of templates and conditions is similar to that of the Docker provider. Configuration templates can +contain variables from the autodiscover event. They can be accessed under data namespace. These are the fields available within config templating. The `kubernetes.*` fields will be available on each emitted event. @@ -211,75 +279,6 @@ For example: } ------------------------------------------------------------------------------------- -The configuration of templates and conditions is similar to that of the Docker provider. Configuration templates can -contain variables from the autodiscover event. They can be accessed under data namespace. - -The `kubernetes` autodiscover provider has the following configuration settings: - -`node`:: (Optional) Specify the node to scope {beatname_lc} to in case it - cannot be accurately detected, as when running {beatname_lc} in host network - mode. -`namespace`:: (Optional) Select the namespace from which to collect the - metadata. If it is not set, the processor collects metadata from all - namespaces. It is unset by default. The namespace configuration only applies to - kubernetes resources that are namespace scoped. -`cleanup_timeout`:: (Optional) Specify the time of inactivity before stopping the -running configuration for a container, -ifeval::["{beatname_lc}"=="filebeat"] - 60s by default. -endif::[] -ifeval::["{beatname_lc}"!="filebeat"] - disabled by default. -endif::[] -`kube_config`:: (Optional) Use given config file as configuration for Kubernetes - client. If kube_config is not set, KUBECONFIG environment variable will be - checked and if not present it will fall back to InCluster. -`kube_client_options`:: (Optional) Additional options can be configured for Kubernetes - client. Currently client QPS and burst are supported, if not set Kubernetes client's - https://pkg.go.dev/k8s.io/client-go/rest#pkg-constants[default QPS and burst] will be used. - Example: -["source","yaml",subs="attributes"] -------------------------------------------------------------------------------------- - kube_client_options: - qps: 5 - burst: 10 -------------------------------------------------------------------------------------- - -`resource`:: (Optional) Select the resource to do discovery on. Currently supported - Kubernetes resources are `pod`, `service` and `node`. If not configured `resource` - defaults to `pod`. -`scope`:: (Optional) Specify at what level autodiscover needs to be done at. `scope` can - either take `node` or `cluster` as values. `node` scope allows discovery of resources in - the specified node. `cluster` scope allows cluster wide discovery. Only `pod` and `node` resources - can be discovered at node scope. -`add_resource_metadata`:: (Optional) Specify labels and annotations filters for the extra metadata coming from Node and Namespace. - `add_resource_metadata` can be done for `node` or `namespace`. By default all labels will be included - while annotations are not added by default. This settings are useful when labels' and annotations' - storing requires special handling to avoid overloading the storage output. The enrichment of `node` or `namespace` metadata - can be individually disabled by setting `enabled: false`. If resource is `pod` and it is created from a `deployment`, by default - the deployment name is added, this can be disabled by set to `false`. - Example: - -["source","yaml",subs="attributes"] -------------------------------------------------------------------------------------- - add_resource_metadata: - namespace: - include_labels: ["namespacelabel1"] - node: - include_labels: ["nodelabel2"] - include_annotations: ["nodeannotation1"] - deployment: false -------------------------------------------------------------------------------------- - -`unique`:: (Optional) Defaults to `false`. Marking an autodiscover provider as unique results into - making the provider to enable the provided templates only when it will gain the leader lease. - This setting can only be combined with `cluster` scope. When `unique` is enabled enabled, `resource` - and `add_resource_metadata` settings are not taken into account. -`leader_lease`:: (Optional) Defaults to `{beatname_lc}-cluster-leader`. This will be name of the lock lease. - One can monitor the status of the lease with `kubectl describe lease beats-cluster-leader`. - Different Beats that refer to the same leader lease will be competitors in holding the lease - and only one will be elected as leader each time. - ifeval::["{beatname_lc}"=="metricbeat"] Example: @@ -317,6 +316,19 @@ ifdef::autodiscoverJolokia[] The Jolokia autodiscover provider uses Jolokia Discovery to find agents running in your host or your network. +The configuration of this provider consists in a set of network interfaces, as +well as a set of templates as in other providers. The network interfaces will be +the ones used for discovery probes, each item of `interfaces` has these settings: + +`name`:: the name of the interface (e.g. `br0`), it can contain a wildcard + as suffix to apply the same settings to multiple network interfaces of + the same type (e.g. `br*`). +`interval`:: time between probes (defaults to 10s) + `grace_period`:: time since the last reply to consider an instance stopped + (defaults to 30s) +`probe_timeout`:: max time to wait for responses since a probe is sent + (defaults to 1s) + Jolokia Discovery mechanism is supported by any Jolokia agent since version 1.2.0, it is enabled by default when Jolokia is included in the application as a JVM agent, but disabled in other cases as the OSGI or WAR (Java EE) agents. @@ -347,19 +359,6 @@ These are the available fields during within config templating. The `jolokia.*` * jolokia.server.version * jolokia.url -The configuration of this provider consists in a set of network interfaces, as -well as a set of templates as in other providers. The network interfaces will be -the ones used for discovery probes, they have these settings: - -`name`:: the name of the interface (e.g. `br0`), it can contain a wildcard - as suffix to apply the same settings to multiple network interfaces of - the same type (e.g. `br*`). -`interval`:: time between probes (defaults to 10s) - `grace_period`:: time since the last reply to consider an instance stopped - (defaults to 30s) -`probe_timeout`:: max time to wait for responses since a probe is sent - (defaults to 1s) - include::../../{beatname_lc}/docs/autodiscover-jolokia-config.asciidoc[] endif::autodiscoverJolokia[] @@ -418,6 +417,49 @@ experimental[] The Nomad autodiscover provider watches for Nomad jobs to start, update, and stop. +The `nomad` autodiscover provider has the following configuration settings: + +`address`:: (Optional) Specify the address of the Nomad agent. By default it will try to talk to a + Nomad agent running locally (`http://127.0.0.1:4646`). + +`region`:: (Optional) Region to use. If not provided, the default agent region is used. + +`namespace`:: (Optional) Namespace to use. If not provided the `default` namespace is used. + +`secret_id`:: (Optional) SecretID to use if ACL is enabled in Nomad. This is an +example ACL policy to apply to the token. + +[source,hcl] +---- +namespace "*" { + policy = "read" +} +node { + policy = "read" +} +agent { + policy = "read" +} +---- + +`node`:: (Optional) Specify the node to scope {beatname_lc} to in case it + cannot be accurately detected when `node` scope is used. + +`scope`:: (Optional) Specify at what level autodiscover needs to be done at. `scope` can + either take `node` or `cluster` as values. `node` scope allows discovery of resources in + the specified node. `cluster` scope allows cluster wide discovery. Defaults to `node`. + +`wait_time`:: (Optional) Limits how long a Watch will block. If not specified (or set to `0`) the + default configuration from the agent will be used. + +`allow_stale`:: (Optional) allows any Nomad server (non-leader) to service a read. This normally + means that the local node where filebeat is allocated will service filebeat's requests. + Defaults to `true`. + +The configuration of templates and conditions is similar to that of the Docker provider. +Configuration templates can contain variables from the autodiscover event. They can be accessed under +`data` namespace. + These are the available fields during config templating. The `nomad.*` fields will be available on each emitted event. @@ -482,49 +524,6 @@ For example: } ------------------------------------------------------------------------------------- -The configuration of templates and conditions is similar to that of the Docker provider. -Configuration templates can contain variables from the autodiscover event. They can be accessed under -`data` namespace. - -The `nomad` autodiscover provider has the following configuration settings: - -`address`:: (Optional) Specify the address of the Nomad agent. By default it will try to talk to a - Nomad agent running locally (`http://127.0.0.1:4646`). - -`region`:: (Optional) Region to use. If not provided, the default agent region is used. - -`namespace`:: (Optional) Namespace to use. If not provided the `default` namespace is used. - -`secret_id`:: (Optional) SecretID to use if ACL is enabled in Nomad. This is an -example ACL policy to apply to the token. - -[source,hcl] ----- -namespace "*" { - policy = "read" -} -node { - policy = "read" -} -agent { - policy = "read" -} ----- - -`node`:: (Optional) Specify the node to scope {beatname_lc} to in case it - cannot be accurately detected when `node` scope is used. - -`scope`:: (Optional) Specify at what level autodiscover needs to be done at. `scope` can - either take `node` or `cluster` as values. `node` scope allows discovery of resources in - the specified node. `cluster` scope allows cluster wide discovery. Defaults to `node`. - -`wait_time`:: (Optional) Limits how long a Watch will block. If not specified (or set to `0`) the - default configuration from the agent will be used. - -`allow_stale`:: (Optional) allows any Nomad server (non-leader) to service a read. This normally - means that the local node where filebeat is allocated will service filebeat's requests. - Defaults to `true`. - include::../../{beatname_lc}/docs/autodiscover-nomad-config.asciidoc[] endif::autodiscoverNomad[] From f8247f7c3ed5334ab54dbcab6e60526b39d9f3cb Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Thu, 6 Jan 2022 02:10:40 -0500 Subject: [PATCH 148/172] [Automation] Update elastic stack version to 8.1.0-af114d16 for testing (#29721) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index ac189d5f5bc3..d530f5ed06b8 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-1f83f9c5-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-af114d16-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-1f83f9c5-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-af114d16-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-1f83f9c5-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-af114d16-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 87360a081e1e..82eb3ced013e 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-1f83f9c5-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-af114d16-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-1f83f9c5-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-af114d16-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 897df4c86911dc1510f358eac80965672e348b34 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Thu, 6 Jan 2022 14:39:26 +0100 Subject: [PATCH 149/172] cluster_stats: use correct license value (#29711) * add integration test * target correct license property * fix license path * cluster_stats: use correct license value * changelog entry --- CHANGELOG.next.asciidoc | 1 + .../module/elasticsearch/cluster_stats/data.go | 17 +---------------- .../module/elasticsearch/test_elasticsearch.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 439d12787327..97ff013a69f2 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -110,6 +110,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Enhance filter check in kubernetes event metricset. {pull}29470[29470] - Fix gcp metrics metricset apply aligner to all metric_types {pull}29514[29513] - Extract correct index property in kibana.stats metricset {pull}29622[29622] +- Fixed bug with `elasticsearch/cluster_stats` metricset not recording license expiration date correctly. {pull}29711[29711] *Packetbeat* diff --git a/metricbeat/module/elasticsearch/cluster_stats/data.go b/metricbeat/module/elasticsearch/cluster_stats/data.go index 8de27d715612..a75f58f3a440 100644 --- a/metricbeat/module/elasticsearch/cluster_stats/data.go +++ b/metricbeat/module/elasticsearch/cluster_stats/data.go @@ -303,22 +303,7 @@ func eventMapping(r mb.ReporterV2, httpClient *helper.HTTP, info elasticsearch.I metricSetFields, _ := schema.Apply(data) metricSetFields.Put("stack", stackData) - metricSetFields.Put("license", struct { - Status string `json:"status"` - Type string `json:"type"` - ExpiryDateMs int `json:"expiry_date_in_millis"` - }{ - Status: license.Status, - Type: license.Type, - ExpiryDateMs: license.ExpiryDateInMillis, - }) - - if license.ExpiryDateInMillis != 0 { - // We don't want to record a 0 expiry date as this means the license has expired - // in the Stack Monitoring UI - metricSetFields.Put("expiry_date_in_millis", license.ExpiryDateInMillis) - } - + metricSetFields.Put("license", l) metricSetFields.Put("state", clusterStateReduced) if err = elasticsearch.PassThruField("version", clusterState, event.ModuleFields); err != nil { diff --git a/metricbeat/module/elasticsearch/test_elasticsearch.py b/metricbeat/module/elasticsearch/test_elasticsearch.py index 7a48efdfb152..9726f26838d9 100644 --- a/metricbeat/module/elasticsearch/test_elasticsearch.py +++ b/metricbeat/module/elasticsearch/test_elasticsearch.py @@ -140,6 +140,17 @@ def test_xpack_cluster_stats(self): proc.check_kill_and_wait() self.assert_no_logged_warnings() + docs = self.read_output_json() + for doc in docs: + t = doc["metricset"]["name"] + if t != "cluster_stats": + continue + license = doc["elasticsearch"]["cluster"]["stats"]["license"] + issue_date = license["issue_date_in_millis"] + self.assertIsNot(type(issue_date), float) + + self.assertNotIn("expiry_date_in_millis", license) + def create_ml_job(self): # Check if an ml job already exists response = self.ml_es.get_jobs() From 27f2d00521f9a4bc51723caf9ea8cc0f73d5dac0 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Thu, 6 Jan 2022 16:20:45 -0600 Subject: [PATCH 150/172] [Heartbeat] Separate http req per task (#29697) This is an attempt to fix the race reported in #29580 by instantiating a separate http request per HTTP task. The theory being that the HTTP library modifies the headers and that the req object is not safe to share. This has passed manual testing using mode: all against endpoints with multiple A records. Tests are not included here due to the tricky nature of testing here, but we will do so in a follow-up --- CHANGELOG.next.asciidoc | 1 + heartbeat/monitors/active/http/task.go | 47 +++++++++++++-------- heartbeat/monitors/active/http/task_test.go | 2 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 97ff013a69f2..6bd26ec48673 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -102,6 +102,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* - Fix broken monitors with newer versions of image relying on dup3. {pull}28938[pull] +- Fix race condition in http monitors using `mode:all` that can cause crashes. {pull}29697[pull] *Metricbeat* diff --git a/heartbeat/monitors/active/http/task.go b/heartbeat/monitors/active/http/task.go index f273b0a4cc72..9ee5f3fa1e8d 100644 --- a/heartbeat/monitors/active/http/task.go +++ b/heartbeat/monitors/active/http/task.go @@ -45,6 +45,8 @@ import ( "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) +type requestFactory func() (*http.Request, error) + func newHTTPMonitorHostJob( addr string, config *Config, @@ -54,10 +56,7 @@ func newHTTPMonitorHostJob( validator multiValidator, ) (jobs.Job, error) { - request, err := buildRequest(addr, config, enc) - if err != nil { - return nil, err - } + var reqFactory requestFactory = func() (*http.Request, error) { return buildRequest(addr, config, enc) } return jobs.MakeSimpleJob(func(event *beat.Event) error { var redirects []string @@ -67,7 +66,13 @@ func newHTTPMonitorHostJob( Transport: transport, Timeout: config.Transport.Timeout, } - _, _, err := execPing(event, client, request, body, config.Transport.Timeout, validator, config.Response) + + req, err := reqFactory() + if err != nil { + return fmt.Errorf("could not make http request: %w", err) + } + + _, _, err = execPing(event, client, req, body, config.Transport.Timeout, validator, config.Response) if len(redirects) > 0 { event.PutValue("http.response.redirects", redirects) } @@ -84,17 +89,14 @@ func newHTTPMonitorIPsJob( validator multiValidator, ) (jobs.Job, error) { - req, err := buildRequest(addr, config, enc) - if err != nil { - return nil, err - } + var reqFactory requestFactory = func() (*http.Request, error) { return buildRequest(addr, config, enc) } - hostname, port, err := splitHostnamePort(req) + hostname, port, err := splitHostnamePort(addr) if err != nil { return nil, err } - pingFactory := createPingFactory(config, port, tls, req, body, validator) + pingFactory := createPingFactory(config, port, tls, reqFactory, body, validator) job, err := monitors.MakeByHostJob(hostname, config.Mode, monitors.NewStdResolver(), pingFactory) return job, err @@ -104,14 +106,19 @@ func createPingFactory( config *Config, port uint16, tls *tlscommon.TLSConfig, - request *http.Request, + reqFactory requestFactory, body []byte, validator multiValidator, ) func(*net.IPAddr) jobs.Job { timeout := config.Transport.Timeout - isTLS := request.URL.Scheme == "https" return monitors.MakePingIPFactory(func(event *beat.Event, ip *net.IPAddr) error { + req, err := reqFactory() + if err != nil { + return fmt.Errorf("could not create http request: %w", err) + } + isTLS := req.URL.Scheme == "https" + addr := net.JoinHostPort(ip.String(), strconv.Itoa(int(port))) d := &dialchain.DialerChain{ Net: dialchain.MakeConstAddrDialer(addr, dialchain.TCPDialer(timeout)), @@ -163,7 +170,7 @@ func createPingFactory( Transport: httpcommon.HeaderRoundTripper(transport, map[string]string{"User-Agent": userAgent}), } - _, end, err := execPing(event, client, request, body, timeout, validator, config.Response) + _, end, err := execPing(event, client, req, body, timeout, validator, config.Response) cbMutex.Lock() defer cbMutex.Unlock() @@ -313,11 +320,15 @@ func execRequest(client *http.Client, req *http.Request) (start time.Time, resp return start, resp, nil } -func splitHostnamePort(requ *http.Request) (string, uint16, error) { - host := requ.URL.Host +func splitHostnamePort(addr string) (string, uint16, error) { + u, err := url.Parse(addr) + if err != nil { + return "", 0, err + } + host := u.Host // Try to add a default port if needed if strings.LastIndex(host, ":") == -1 { - switch requ.URL.Scheme { + switch u.Scheme { case urlSchemaHTTP: host += ":80" case urlSchemaHTTPS: @@ -330,7 +341,7 @@ func splitHostnamePort(requ *http.Request) (string, uint16, error) { } p, err := strconv.ParseUint(port, 10, 16) if err != nil { - return "", 0, fmt.Errorf("'%v' is no valid port number in '%v'", port, requ.URL.Host) + return "", 0, fmt.Errorf("'%v' is no valid port number in '%v'", port, u.Host) } return host, uint16(p), nil } diff --git a/heartbeat/monitors/active/http/task_test.go b/heartbeat/monitors/active/http/task_test.go index 358a4a6ec2b2..71b9720cbed3 100644 --- a/heartbeat/monitors/active/http/task_test.go +++ b/heartbeat/monitors/active/http/task_test.go @@ -106,7 +106,7 @@ func TestSplitHostnamePort(t *testing.T) { request := &http.Request{ URL: url, } - host, port, err := splitHostnamePort(request) + host, port, err := splitHostnamePort(request.URL.String()) if err != nil { if test.expectedError == nil { From 7b095dae991763ab612d673f85fcbec920b2fb53 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Thu, 6 Jan 2022 22:46:37 -0600 Subject: [PATCH 151/172] [Heartbeat] Use timer.reset now that golang has been updated (#29729) Undoes https://github.com/elastic/beats/pull/27006/files (while preserving the new test), and also cleaning up the syntax using `time.Until`. Since the The golang bug I reported in https://github.com/golang/go/issues/47329 has been fixed since somewhere in go 1.16.x (it's hard to track the exact version). This should be backported to 7.16.x since that already uses go 1.17.x and is safe. --- heartbeat/scheduler/timerqueue/queue.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/heartbeat/scheduler/timerqueue/queue.go b/heartbeat/scheduler/timerqueue/queue.go index 61d4e0ac933d..760dd353f38a 100644 --- a/heartbeat/scheduler/timerqueue/queue.go +++ b/heartbeat/scheduler/timerqueue/queue.go @@ -88,7 +88,7 @@ func (tq *TimerQueue) Start() { if tq.th.Len() > 0 { nr := tq.th[0].runAt tq.nextRunAt = &nr - tq.timer = time.NewTimer(time.Until(nr)) + tq.timer.Reset(time.Until(nr)) } else { tq.timer.Stop() tq.nextRunAt = nil @@ -107,18 +107,7 @@ func (tq *TimerQueue) pushInternal(tt *timerTask) { if tq.nextRunAt != nil && !tq.timer.Stop() { <-tq.timer.C } - // Originally the line below this comment was - // - // tq.timer.Reset(time.Until(tt.runAt)) - // - // however this broke in go1.16rc1, specifically on the commit b4b014465216790e01aa66f9120d03230e4aff46 - //, specifically on this line: - // https://github.com/golang/go/commit/b4b014465216790e01aa66f9120d03230e4aff46#diff-73699b6edfe5dbb3f6824e66bb3566bce9405e9a8c810cac55c8199459f0ac19R652 - // where some nice new optimizations don't actually work reliably - // This can be worked around by instantiating a new timer rather than resetting the timer. - // since that internally calls deltimer in runtime/timer.go rather than modtimer, - // I suspect that the problem is in modtimer's setting of &pp.timerModifiedEarliest - tq.timer = time.NewTimer(time.Until(tt.runAt)) + tq.timer.Reset(time.Until(tt.runAt)) tq.nextRunAt = &tt.runAt } } From 6531ae66ab3e5ac60a99d56cb3dec72a1ce2a7ee Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Fri, 7 Jan 2022 02:32:14 -0500 Subject: [PATCH 152/172] [Automation] Update elastic stack version to 8.1.0-5e490954 for testing (#29737) Co-authored-by: apmmachine --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index d530f5ed06b8..b3c6eaa2976c 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-af114d16-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-5e490954-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-af114d16-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-5e490954-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-af114d16-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-5e490954-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 82eb3ced013e..204cc33baced 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-af114d16-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-5e490954-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-af114d16-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-5e490954-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From a1617c7c4eef6d12542ad117be8c68795d61ee40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Fri, 7 Jan 2022 11:38:46 +0100 Subject: [PATCH 153/172] Do not mention removal if version is not specified in `cfgwarn` messages (#29727) --- libbeat/common/cfgwarn/cfgwarn.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libbeat/common/cfgwarn/cfgwarn.go b/libbeat/common/cfgwarn/cfgwarn.go index e102ed20e4b6..0295b0b6d3b9 100644 --- a/libbeat/common/cfgwarn/cfgwarn.go +++ b/libbeat/common/cfgwarn/cfgwarn.go @@ -33,9 +33,13 @@ func Beta(format string, v ...interface{}) { } // Deprecate logs a deprecation message. -// The version string contains the version when the future will be removed +// The version string contains the version when the future will be removed. +// If version is empty, the message will not mention the removal of the feature. func Deprecate(version string, format string, v ...interface{}) { - postfix := fmt.Sprintf(" Will be removed in version: %s", version) + var postfix string + if version != "" { + postfix = fmt.Sprintf(" Will be removed in version: %s", version) + } logp.NewLogger(selector, zap.AddCallerSkip(1)).Warnf("DEPRECATED: "+format+postfix, v...) } From 2874b62f4ee2b93c9776cdf45e505f4cce65cf52 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Sat, 8 Jan 2022 14:46:49 +0100 Subject: [PATCH 154/172] System/socket: Support kernel_clone() replacement for _do_fork() (#29744) Updates the system/socket dataset to support kernels 5.10+ where the _do_fork kernel function is replaced by kernel_clone. This was preventing Auditbeat to start. --- CHANGELOG.next.asciidoc | 1 + x-pack/auditbeat/module/system/socket/template.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 6bd26ec48673..3829e9bb2b05 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -91,6 +91,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - system/package: Fix an error that can occur while trying to persist package metadata. {issue}18536[18536] {pull}18887[18887] - system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] - system/socket: Fix process name and arg truncation for long names, paths and args lists. {issue}24667[24667] {pull}29410[29410] +- system/socket: Fix startup errors on newer 5.x kernels due to missing _do_fork function. {issue}29607[29607] {pull}29744[29744] *Filebeat* diff --git a/x-pack/auditbeat/module/system/socket/template.go b/x-pack/auditbeat/module/system/socket/template.go index 7b90a2a4daaa..43d520cd1c9a 100644 --- a/x-pack/auditbeat/module/system/socket/template.go +++ b/x-pack/auditbeat/module/system/socket/template.go @@ -41,7 +41,7 @@ var functionAlternatives = map[string][]string{ "SYS_EXECVE": syscallAlternatives("execve"), "SYS_GETTIMEOFDAY": syscallAlternatives("gettimeofday"), "SYS_UNAME": syscallAlternatives("newuname"), - "DO_FORK": {"_do_fork", "do_fork"}, + "DO_FORK": {"_do_fork", "do_fork", "kernel_clone"}, } func syscallAlternatives(syscall string) []string { From 03bf16907bea9768427f8305a5c345368b55d834 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Mon, 10 Jan 2022 09:54:30 +0100 Subject: [PATCH 155/172] auditd: Store program arguments in process.args array (#29601) Changes Filebeat's auditd module to store program arguments (from an EXECVE call) in process.args (arg0 also in process.executable). Previously it was using fields arg0 to argN under auditd.log. This prevents too many fields being created. When a call contained more than 10.000 arguments, this lead to an ingest error and contributed to very large indices: > Could not index event to Elasticsearch: "status"=>400, > "error"=>{ > "type"=>"illegal_argument_exception", > "reason"=>"Limit of total fields [10000] has been exceeded"}} --- CHANGELOG.next.asciidoc | 1 + .../module/auditd/log/ingest/pipeline.yml | 25 +- .../test/audit-cent7-node.log-expected.json | 10 - .../log/test/audit-rhel6.log-expected.json | 14 +- .../log/test/audit-rhel7.log-expected.json | 100 - .../test/audit-ubuntu1604.log-expected.json | 6 - .../auditd/log/test/avc.log-expected.json | 3 - filebeat/module/auditd/log/test/execve.log | 91 + .../auditd/log/test/execve.log-expected.json | 1917 +++++++++++++++++ .../auditd/log/test/test.log-expected.json | 22 +- .../auditd/log/test/useradd.log-expected.json | 8 - filebeat/tests/system/test_modules.py | 109 +- 12 files changed, 2097 insertions(+), 209 deletions(-) create mode 100644 filebeat/module/auditd/log/test/execve.log create mode 100644 filebeat/module/auditd/log/test/execve.log-expected.json diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 3829e9bb2b05..a139a02ba2b3 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -41,6 +41,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - With the default configuration the cloud modules (aws, azure, googlecloud, o365, okta) - With the default configuration the cef and panw modules will no longer send the `host` - Add `while_pattern` type to multiline reader. {pull}19662[19662] +- auditd dataset: Use process.args to store program arguments instead of auditd.log.aNNN fields. {pull}29601[29601] *Heartbeat* - Only add monitor.status to browser events when summary. {pull}29460[29460] diff --git a/filebeat/module/auditd/log/ingest/pipeline.yml b/filebeat/module/auditd/log/ingest/pipeline.yml index b5c6d56412a2..b169fb4dd581 100644 --- a/filebeat/module/auditd/log/ingest/pipeline.yml +++ b/filebeat/module/auditd/log/ingest/pipeline.yml @@ -2102,6 +2102,29 @@ processors: ignore_failure: true field: auditd.log.msg target_field: message +- script: + lang: painless + description: Extracts process information from execve calls + if: 'ctx.process?.args_count != null && ctx.auditd?.log != null' + source: >- + long argc = ctx.process.args_count; + List args = new ArrayList(); + def[] fmt = new def[] {0}; + for (long i=0; i Date: Mon, 10 Jan 2022 15:57:46 +0100 Subject: [PATCH 156/172] Forward port 7.16.3 changelog to master (#29777) --- CHANGELOG.asciidoc | 10 ++++++++++ CHANGELOG.next.asciidoc | 2 -- libbeat/docs/release.asciidoc | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index dfad0bb2de10..aa5c9f9a5ace 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -17,6 +17,16 @@ Changes will be described in a later alpha / beta. === Beats version 8.0.0-alpha1 Changes will be described in a later alpha / beta. +[[release-notes-7.16.3]] +=== Beats version 7.16.3 +https://github.com/elastic/beats/compare/v7.16.2...v7.16.3[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fields of type `match_only_text` (i.e. `message`) and `wildcard` were missing from the template's `default_field` list. {issue}29633[29633] {pull}29634[29634] + [[release-notes-7.16.2]] === Beats version 7.16.2 https://github.com/elastic/beats/compare/v7.16.1...v7.16.2[View commits] diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index a139a02ba2b3..9dff67877304 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -83,7 +83,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* -- Fields of type `match_only_text` (i.e. `message`) and `wildcard` were missing from the template's default_field list. {issue}29633[29633] {pull}29634[29634] *Auditbeat* @@ -103,7 +102,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* -- Fix broken monitors with newer versions of image relying on dup3. {pull}28938[pull] - Fix race condition in http monitors using `mode:all` that can cause crashes. {pull}29697[pull] *Metricbeat* diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index 26e1bd6b14d2..fa53cf52e5b6 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -11,6 +11,7 @@ upgrade. * <> * <> * <> +* <> * <> * <> * <> From bcb83e893669960b2024e6cf588d2ade1174bd36 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Mon, 10 Jan 2022 17:00:55 +0100 Subject: [PATCH 157/172] Filebeat tests: Restore `@timestamp` field validation (#29772) This restores the `@timestamp` field in Filebeat's module tests, so that it is properly validated. Temporarily disable timestamp validation in ibmmq module --- .../error/test/sublevel.log-expected.json | 2 +- .../test/audit-cent7-node.log-expected.json | 10 ++ .../log/test/audit-rhel6.log-expected.json | 12 +++ .../log/test/audit-rhel7.log-expected.json | 100 ++++++++++++++++++ .../test/audit-ubuntu1604.log-expected.json | 6 ++ .../auditd/log/test/avc.log-expected.json | 3 + .../auditd/log/test/execve.log-expected.json | 91 ++++++++++++++++ .../auditd/log/test/test.log-expected.json | 15 +++ .../auditd/log/test/useradd.log-expected.json | 8 ++ filebeat/tests/system/test_modules.py | 3 +- .../cisco/asa/test/asa.log-expected.json | 100 ++++++++++++++++++ .../asa/test/hostnames.log-expected.json | 2 + .../cisco/asa/test/not-ip.log-expected.json | 3 + .../cisco/asa/test/sample.log-expected.json | 87 +++++++++++++++ ...lear_users_history_start.log-expected.json | 2 +- ..._clear_users_history_end.log-expected.json | 2 +- ...tor_dr_replication_start.log-expected.json | 2 +- ...nitor_dr_replication_end.log-expected.json | 2 +- ...7_monitor_fw_rules_start.log-expected.json | 2 +- ...358_monitor_fw_rules_end.log-expected.json | 2 +- ...ault_certificate_is_sha1.log-expected.json | 2 +- .../59_clear_safe_history.log-expected.json | 2 +- .../test/88_set_password.log-expected.json | 2 +- .../audit/test/legacysyslog.log-expected.json | 2 +- .../test/AMQERR01_QM1.log-expected.json | 46 ++++---- .../xg/test/anti-spam.log-expected.json | 11 ++ .../xg/test/anti-virus.log-expected.json | 8 ++ .../sophos/xg/test/atp.log-expected.json | 4 + .../sophos/xg/test/cfilter.log-expected.json | 9 ++ .../sophos/xg/test/event.log-expected.json | 19 ++++ .../sophos/xg/test/firewall.log-expected.json | 22 ++++ .../sophos/xg/test/idp.log-expected.json | 5 + .../sophos/xg/test/sandbox.log-expected.json | 6 ++ .../xg/test/system-health.log-expected.json | 5 + .../sophos/xg/test/waf.log-expected.json | 5 + .../sophos/xg/test/wifi.log-expected.json | 2 + 36 files changed, 569 insertions(+), 35 deletions(-) diff --git a/filebeat/module/apache/error/test/sublevel.log-expected.json b/filebeat/module/apache/error/test/sublevel.log-expected.json index 26ad0e275386..43ed49a67c50 100644 --- a/filebeat/module/apache/error/test/sublevel.log-expected.json +++ b/filebeat/module/apache/error/test/sublevel.log-expected.json @@ -18,4 +18,4 @@ "process.thread.id": 140413273032448, "service.type": "apache" } -] +] \ No newline at end of file diff --git a/filebeat/module/auditd/log/test/audit-cent7-node.log-expected.json b/filebeat/module/auditd/log/test/audit-cent7-node.log-expected.json index 854ebd16841e..b435807ebaac 100644 --- a/filebeat/module/auditd/log/test/audit-cent7-node.log-expected.json +++ b/filebeat/module/auditd/log/test/audit-cent7-node.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-07-06T16:38:34.588Z", "auditd.log.format": "raw", "auditd.log.kernel": "3.10.0-1062.9.1.el7.x86_64", "auditd.log.node": "localhost.localdomain", @@ -32,6 +33,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.707Z", "auditd.log.audit_backlog_limit": "8192", "auditd.log.node": "localhost.localdomain", "auditd.log.old": "64", @@ -61,6 +63,7 @@ "user.audit.id": "4294967295" }, { + "@timestamp": "2020-07-06T16:38:34.707Z", "auditd.log.audit_failure": "1", "auditd.log.node": "localhost.localdomain", "auditd.log.old": "1", @@ -90,6 +93,7 @@ "user.audit.id": "4294967295" }, { + "@timestamp": "2020-07-06T16:38:34.709Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 6, @@ -121,6 +125,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.725Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SYSTEM_BOOT", "auditd.log.sequence": 7, @@ -147,6 +152,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.739Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 8, @@ -178,6 +184,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.807Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 9, @@ -209,6 +216,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.843Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 10, @@ -240,6 +248,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.850Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 11, @@ -271,6 +280,7 @@ "user.id": "0" }, { + "@timestamp": "2020-07-06T16:38:34.857Z", "auditd.log.node": "localhost.localdomain", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 12, diff --git a/filebeat/module/auditd/log/test/audit-rhel6.log-expected.json b/filebeat/module/auditd/log/test/audit-rhel6.log-expected.json index 889da77f9e01..13db1f882c47 100644 --- a/filebeat/module/auditd/log/test/audit-rhel6.log-expected.json +++ b/filebeat/module/auditd/log/test/audit-rhel6.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-03-14T19:20:30.178Z", "auditd.log.op": "PAM:session_close", "auditd.log.record_type": "USER_END", "auditd.log.sequence": 19600327, @@ -31,6 +32,7 @@ "user.name": "root" }, { + "@timestamp": "2017-03-14T19:20:30.178Z", "auditd.log.op": "PAM:setcred", "auditd.log.record_type": "CRED_DISP", "auditd.log.sequence": 19600328, @@ -62,6 +64,7 @@ "user.name": "root" }, { + "@timestamp": "2017-03-14T19:20:56.192Z", "auditd.log.record_type": "USER_CMD", "auditd.log.sequence": 19600329, "auditd.log.ses": "11988", @@ -95,6 +98,7 @@ "user.id": "497" }, { + "@timestamp": "2017-03-14T19:20:56.193Z", "auditd.log.op": "PAM:setcred", "auditd.log.record_type": "CRED_ACQ", "auditd.log.sequence": 19600330, @@ -126,6 +130,7 @@ "user.name": "root" }, { + "@timestamp": "2017-03-14T19:20:56.193Z", "auditd.log.op": "PAM:session_open", "auditd.log.record_type": "USER_START", "auditd.log.sequence": 19600331, @@ -157,6 +162,7 @@ "user.name": "root" }, { + "@timestamp": "2017-03-14T19:23:02.529Z", "auditd.log.dst_prefixlen": 22, "auditd.log.op": "SPD-add", "auditd.log.sequence": 19600354, @@ -178,6 +184,7 @@ "user.audit.id": "4294967295" }, { + "@timestamp": "2017-03-14T19:23:02.529Z", "auditd.log.a0": "9", "auditd.log.a1": "7f564ee6d2a0", "auditd.log.a2": "b8", @@ -221,6 +228,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2017-03-16T04:02:40.072Z", "auditd.log.new_auid": "700", "auditd.log.new_ses": "12286", "auditd.log.old_auid": "700", @@ -250,6 +258,7 @@ "user.id": "700" }, { + "@timestamp": "2017-03-16T04:02:40.070Z", "auditd.log.direction": "both", "auditd.log.kind": "session", "auditd.log.laddr": "107.170.139.210", @@ -296,6 +305,7 @@ "user.saved.id": "74" }, { + "@timestamp": "2017-03-16T04:02:40.072Z", "auditd.log.op": "success", "auditd.log.record_type": "USER_AUTH", "auditd.log.sequence": 19623789, @@ -339,6 +349,7 @@ "user.terminal": "ssh" }, { + "@timestamp": "2017-03-16T04:02:57.804Z", "auditd.log.op": "PAM:authentication", "auditd.log.record_type": "USER_AUTH", "auditd.log.sequence": 19623807, @@ -371,6 +382,7 @@ "user.terminal": "pts/0" }, { + "@timestamp": "2017-03-16T04:02:57.805Z", "auditd.log.op": "PAM:accounting", "auditd.log.record_type": "USER_ACCT", "auditd.log.sequence": 19623808, diff --git a/filebeat/module/auditd/log/test/audit-rhel7.log-expected.json b/filebeat/module/auditd/log/test/audit-rhel7.log-expected.json index 50ede81ba095..a18b67e2e221 100644 --- a/filebeat/module/auditd/log/test/audit-rhel7.log-expected.json +++ b/filebeat/module/auditd/log/test/audit-rhel7.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2016-12-07T02:16:23.819Z", "auditd.log.format": "raw", "auditd.log.kernel": "3.10.0-327.36.3.el7.x86_64", "auditd.log.record_type": "DAEMON_START", @@ -28,6 +29,7 @@ "user.audit.id": "4294967295" }, { + "@timestamp": "2016-12-07T02:16:23.864Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 6, "auditd.log.ses": "4294967295", @@ -58,6 +60,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:23.876Z", "auditd.log.record_type": "SYSTEM_BOOT", "auditd.log.sequence": 7, "auditd.log.ses": "4294967295", @@ -83,6 +86,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:23.879Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 8, "auditd.log.ses": "4294967295", @@ -113,6 +117,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.075Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 9, "auditd.log.ses": "4294967295", @@ -143,6 +148,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.088Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 10, "auditd.log.ses": "4294967295", @@ -173,6 +179,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.163Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 11, "auditd.log.ses": "4294967295", @@ -203,6 +210,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.212Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 12, "auditd.log.ses": "4294967295", @@ -233,6 +241,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.521Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 13, "auditd.log.ses": "4294967295", @@ -263,6 +272,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.521Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 14, "auditd.log.ses": "4294967295", @@ -293,6 +303,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.526Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 15, "auditd.log.ses": "4294967295", @@ -323,6 +334,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.534Z", "auditd.log.record_type": "SERVICE_STOP", "auditd.log.sequence": 16, "auditd.log.ses": "4294967295", @@ -353,6 +365,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.827Z", "auditd.log.entries": 0, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -377,6 +390,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.827Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -420,6 +434,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.858Z", "auditd.log.entries": 0, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -444,6 +459,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.858Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -487,6 +503,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.870Z", "auditd.log.entries": 0, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -511,6 +528,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.870Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -554,6 +572,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.877Z", "auditd.log.entries": 0, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -578,6 +597,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.877Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -621,6 +641,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.931Z", "auditd.log.entries": 0, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -645,6 +666,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.931Z", "auditd.log.a0": "3", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -688,6 +710,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.939Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 22, "auditd.log.ses": "4294967295", @@ -718,6 +741,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.945Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 23, "auditd.log.ses": "4294967295", @@ -748,6 +772,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.953Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 24, "auditd.log.ses": "4294967295", @@ -778,6 +803,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.954Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 25, "auditd.log.ses": "4294967295", @@ -808,6 +834,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.960Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 26, "auditd.log.ses": "4294967295", @@ -838,6 +865,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:24.982Z", "auditd.log.entries": 0, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -862,6 +890,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:24.982Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -905,6 +934,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.012Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 28, "auditd.log.ses": "4294967295", @@ -935,6 +965,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.031Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 29, "auditd.log.ses": "4294967295", @@ -965,6 +996,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.043Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 30, "auditd.log.ses": "4294967295", @@ -995,6 +1027,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.044Z", "auditd.log.record_type": "SERVICE_STOP", "auditd.log.sequence": 31, "auditd.log.ses": "4294967295", @@ -1025,6 +1058,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.069Z", "auditd.log.entries": 0, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -1049,6 +1083,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.069Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -1092,6 +1127,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.104Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 33, "auditd.log.ses": "4294967295", @@ -1122,6 +1158,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.099Z", "auditd.log.entries": 0, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -1146,6 +1183,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.099Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -1189,6 +1227,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.128Z", "auditd.log.entries": 0, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -1213,6 +1252,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.128Z", "auditd.log.a0": "0", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -1256,6 +1296,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.164Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 36, "auditd.log.ses": "4294967295", @@ -1286,6 +1327,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.166Z", "auditd.log.record_type": "SERVICE_STOP", "auditd.log.sequence": 37, "auditd.log.ses": "4294967295", @@ -1316,6 +1358,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.167Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 38, "auditd.log.ses": "4294967295", @@ -1346,6 +1389,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.168Z", "auditd.log.record_type": "SERVICE_STOP", "auditd.log.sequence": 39, "auditd.log.ses": "4294967295", @@ -1376,6 +1420,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.170Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 40, "auditd.log.ses": "4294967295", @@ -1406,6 +1451,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.170Z", "auditd.log.record_type": "SERVICE_STOP", "auditd.log.sequence": 41, "auditd.log.ses": "4294967295", @@ -1436,6 +1482,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.180Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 42, "auditd.log.ses": "4294967295", @@ -1466,6 +1513,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.187Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 43, "auditd.log.ses": "4294967295", @@ -1496,6 +1544,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.191Z", "auditd.log.entries": 0, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -1520,6 +1569,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.191Z", "auditd.log.a0": "1", "auditd.log.a1": "41a15c", "auditd.log.a2": "0", @@ -1563,6 +1613,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.511Z", "auditd.log.record_type": "SERVICE_START", "auditd.log.sequence": 45, "auditd.log.ses": "4294967295", @@ -1593,6 +1644,7 @@ "user.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.528Z", "auditd.log.entries": 5, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1617,6 +1669,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.528Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1660,6 +1713,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.532Z", "auditd.log.entries": 5, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1684,6 +1738,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.532Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1727,6 +1782,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.534Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1751,6 +1807,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.534Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1794,6 +1851,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.537Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1818,6 +1876,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.537Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1861,6 +1920,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.538Z", "auditd.log.entries": 4, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1885,6 +1945,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.538Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1928,6 +1989,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.542Z", "auditd.log.entries": 4, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -1952,6 +2014,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.542Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -1995,6 +2058,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.543Z", "auditd.log.entries": 3, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -2019,6 +2083,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.543Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -2062,6 +2127,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.546Z", "auditd.log.entries": 3, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -2086,6 +2152,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.546Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -2129,6 +2196,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.548Z", "auditd.log.entries": 4, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -2153,6 +2221,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.548Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -2196,6 +2265,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.552Z", "auditd.log.entries": 4, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -2220,6 +2290,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.552Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -2263,6 +2334,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.553Z", "auditd.log.entries": 5, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2287,6 +2359,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.553Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2330,6 +2403,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.556Z", "auditd.log.entries": 5, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2354,6 +2428,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.556Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2397,6 +2472,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.557Z", "auditd.log.entries": 6, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2421,6 +2497,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.557Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2464,6 +2541,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.560Z", "auditd.log.entries": 6, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2488,6 +2566,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.560Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2531,6 +2610,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.562Z", "auditd.log.entries": 4, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2555,6 +2635,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.562Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2598,6 +2679,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.566Z", "auditd.log.entries": 4, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2622,6 +2704,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.566Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2665,6 +2748,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.569Z", "auditd.log.entries": 3, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2689,6 +2773,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.569Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2732,6 +2817,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.573Z", "auditd.log.entries": 3, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2756,6 +2842,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.573Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2799,6 +2886,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.575Z", "auditd.log.entries": 4, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2823,6 +2911,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.575Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2866,6 +2955,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.578Z", "auditd.log.entries": 4, "auditd.log.family": "10", "auditd.log.record_type": "NETFILTER_CFG", @@ -2890,6 +2980,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.578Z", "auditd.log.a0": "4", "auditd.log.a1": "29", "auditd.log.a2": "40", @@ -2933,6 +3024,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.580Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -2957,6 +3049,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.580Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -3000,6 +3093,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.582Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -3024,6 +3118,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.582Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -3067,6 +3162,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.583Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -3091,6 +3187,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.583Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -3134,6 +3231,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.585Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", @@ -3158,6 +3256,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:16:25.585Z", "auditd.log.a0": "4", "auditd.log.a1": "0", "auditd.log.a2": "40", @@ -3201,6 +3300,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2016-12-07T02:16:25.587Z", "auditd.log.entries": 6, "auditd.log.family": "2", "auditd.log.record_type": "NETFILTER_CFG", diff --git a/filebeat/module/auditd/log/test/audit-ubuntu1604.log-expected.json b/filebeat/module/auditd/log/test/audit-ubuntu1604.log-expected.json index d4660c1e4195..3c749e10d58d 100644 --- a/filebeat/module/auditd/log/test/audit-ubuntu1604.log-expected.json +++ b/filebeat/module/auditd/log/test/audit-ubuntu1604.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-04-21T05:28:40.441Z", "auditd.log.a0": "3", "auditd.log.a1": "7ffd0dc80040", "auditd.log.a2": "7ffd0dc7ffd0", @@ -44,6 +45,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2017-04-21T05:28:40.441Z", "auditd.log.saddr": "0200E31C4853E6640000000000000000", "auditd.log.sequence": 8832, "event.action": "sockaddr", @@ -57,6 +59,7 @@ "service.type": "auditd" }, { + "@timestamp": "2017-04-21T05:28:40.441Z", "auditd.log.proctitle": "(sshd)", "auditd.log.sequence": 8832, "event.action": "proctitle", @@ -70,6 +73,7 @@ "service.type": "auditd" }, { + "@timestamp": "2017-04-21T05:38:27.096Z", "auditd.log.a0": "5", "auditd.log.a1": "7ffc12ac3ab0", "auditd.log.a2": "10", @@ -114,6 +118,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2017-04-21T05:38:27.096Z", "auditd.log.saddr": "02000050A9FEA9FE0000000000000000", "auditd.log.sequence": 9004, "event.action": "sockaddr", @@ -127,6 +132,7 @@ "service.type": "auditd" }, { + "@timestamp": "2017-04-21T05:38:27.096Z", "auditd.log.proctitle": "(g_daemon)", "auditd.log.sequence": 9004, "event.action": "proctitle", diff --git a/filebeat/module/auditd/log/test/avc.log-expected.json b/filebeat/module/auditd/log/test/avc.log-expected.json index bf893021e231..3179d7f8b092 100644 --- a/filebeat/module/auditd/log/test/avc.log-expected.json +++ b/filebeat/module/auditd/log/test/avc.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2008-11-16T22:21:13.147Z", "auditd.log.dev": "dm-0", "auditd.log.ino": "284133", "auditd.log.path": "/var/www/html/file1", @@ -20,6 +21,7 @@ "service.type": "auditd" }, { + "@timestamp": "2018-04-25T13:28:53.080Z", "auditd.log.apparmor": "DENIED", "auditd.log.denied_mask": "trace", "auditd.log.operation": "ptrace", @@ -43,6 +45,7 @@ "service.type": "auditd" }, { + "@timestamp": "2018-04-25T13:28:53.080Z", "auditd.log.record_type": "AVC", "auditd.log.sequence": 61207, "auditd.log.seresult": "1", diff --git a/filebeat/module/auditd/log/test/execve.log-expected.json b/filebeat/module/auditd/log/test/execve.log-expected.json index 0dfcb755fcdd..777e188a62c7 100644 --- a/filebeat/module/auditd/log/test/execve.log-expected.json +++ b/filebeat/module/auditd/log/test/execve.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2016-12-07T02:20:31.371Z", "auditd.log.sequence": 479, "event.action": "execve", "event.dataset": "auditd.log", @@ -23,6 +24,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:31.372Z", "auditd.log.sequence": 481, "event.action": "execve", "event.dataset": "auditd.log", @@ -42,6 +44,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:32.471Z", "auditd.log.sequence": 485, "event.action": "execve", "event.dataset": "auditd.log", @@ -71,6 +74,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:53.941Z", "auditd.log.sequence": 486, "event.action": "execve", "event.dataset": "auditd.log", @@ -90,6 +94,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.135Z", "auditd.log.sequence": 493, "event.action": "execve", "event.dataset": "auditd.log", @@ -109,6 +114,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.258Z", "auditd.log.sequence": 507, "event.action": "execve", "event.dataset": "auditd.log", @@ -126,6 +132,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.261Z", "auditd.log.sequence": 508, "event.action": "execve", "event.dataset": "auditd.log", @@ -144,6 +151,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.264Z", "auditd.log.sequence": 509, "event.action": "execve", "event.dataset": "auditd.log", @@ -161,6 +169,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.265Z", "auditd.log.sequence": 510, "event.action": "execve", "event.dataset": "auditd.log", @@ -179,6 +188,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.266Z", "auditd.log.sequence": 511, "event.action": "execve", "event.dataset": "auditd.log", @@ -197,6 +207,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.268Z", "auditd.log.sequence": 512, "event.action": "execve", "event.dataset": "auditd.log", @@ -216,6 +227,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.269Z", "auditd.log.sequence": 513, "event.action": "execve", "event.dataset": "auditd.log", @@ -236,6 +248,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.270Z", "auditd.log.sequence": 514, "event.action": "execve", "event.dataset": "auditd.log", @@ -254,6 +267,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.271Z", "auditd.log.sequence": 515, "event.action": "execve", "event.dataset": "auditd.log", @@ -272,6 +286,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.273Z", "auditd.log.sequence": 516, "event.action": "execve", "event.dataset": "auditd.log", @@ -291,6 +306,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.274Z", "auditd.log.sequence": 517, "event.action": "execve", "event.dataset": "auditd.log", @@ -311,6 +327,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:20:54.276Z", "auditd.log.sequence": 518, "event.action": "execve", "event.dataset": "auditd.log", @@ -329,6 +346,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:07.546Z", "auditd.log.sequence": 519, "event.action": "execve", "event.dataset": "auditd.log", @@ -347,6 +365,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:07.553Z", "auditd.log.sequence": 520, "event.action": "execve", "event.dataset": "auditd.log", @@ -365,6 +384,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:07.557Z", "auditd.log.sequence": 521, "event.action": "execve", "event.dataset": "auditd.log", @@ -383,6 +403,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:07.561Z", "auditd.log.sequence": 522, "event.action": "execve", "event.dataset": "auditd.log", @@ -401,6 +422,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:18.176Z", "auditd.log.sequence": 525, "event.action": "execve", "event.dataset": "auditd.log", @@ -419,6 +441,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:32.487Z", "auditd.log.sequence": 528, "event.action": "execve", "event.dataset": "auditd.log", @@ -448,6 +471,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:48.360Z", "auditd.log.sequence": 529, "event.action": "execve", "event.dataset": "auditd.log", @@ -468,6 +492,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:48.371Z", "auditd.log.sequence": 533, "event.action": "execve", "event.dataset": "auditd.log", @@ -487,6 +512,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:48.376Z", "auditd.log.sequence": 534, "event.action": "execve", "event.dataset": "auditd.log", @@ -505,6 +531,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:48.378Z", "auditd.log.sequence": 538, "event.action": "execve", "event.dataset": "auditd.log", @@ -528,6 +555,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:48.379Z", "auditd.log.sequence": 540, "event.action": "execve", "event.dataset": "auditd.log", @@ -547,6 +575,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:21:57.921Z", "auditd.log.sequence": 542, "event.action": "execve", "event.dataset": "auditd.log", @@ -565,6 +594,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.297Z", "auditd.log.sequence": 543, "event.action": "execve", "event.dataset": "auditd.log", @@ -583,6 +613,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.304Z", "auditd.log.sequence": 547, "event.action": "execve", "event.dataset": "auditd.log", @@ -600,6 +631,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.330Z", "auditd.log.sequence": 552, "event.action": "execve", "event.dataset": "auditd.log", @@ -617,6 +649,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.334Z", "auditd.log.sequence": 553, "event.action": "execve", "event.dataset": "auditd.log", @@ -636,6 +669,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.335Z", "auditd.log.sequence": 554, "event.action": "execve", "event.dataset": "auditd.log", @@ -656,6 +690,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.336Z", "auditd.log.sequence": 555, "event.action": "execve", "event.dataset": "auditd.log", @@ -674,6 +709,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.337Z", "auditd.log.sequence": 556, "event.action": "execve", "event.dataset": "auditd.log", @@ -692,6 +728,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.338Z", "auditd.log.sequence": 557, "event.action": "execve", "event.dataset": "auditd.log", @@ -711,6 +748,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.339Z", "auditd.log.sequence": 558, "event.action": "execve", "event.dataset": "auditd.log", @@ -731,6 +769,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:14.341Z", "auditd.log.sequence": 559, "event.action": "execve", "event.dataset": "auditd.log", @@ -749,6 +788,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:16.705Z", "auditd.log.sequence": 560, "event.action": "execve", "event.dataset": "auditd.log", @@ -767,6 +807,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:32.504Z", "auditd.log.sequence": 563, "event.action": "execve", "event.dataset": "auditd.log", @@ -796,6 +837,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:36.580Z", "auditd.log.sequence": 564, "event.action": "execve", "event.dataset": "auditd.log", @@ -814,6 +856,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:36.585Z", "auditd.log.sequence": 565, "event.action": "execve", "event.dataset": "auditd.log", @@ -832,6 +875,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:36.590Z", "auditd.log.sequence": 566, "event.action": "execve", "event.dataset": "auditd.log", @@ -850,6 +894,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:22:36.593Z", "auditd.log.sequence": 567, "event.action": "execve", "event.dataset": "auditd.log", @@ -868,6 +913,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:23:32.521Z", "auditd.log.sequence": 570, "event.action": "execve", "event.dataset": "auditd.log", @@ -897,6 +943,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:24:05.611Z", "auditd.log.sequence": 571, "event.action": "execve", "event.dataset": "auditd.log", @@ -915,6 +962,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:24:05.615Z", "auditd.log.sequence": 572, "event.action": "execve", "event.dataset": "auditd.log", @@ -933,6 +981,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:24:05.619Z", "auditd.log.sequence": 573, "event.action": "execve", "event.dataset": "auditd.log", @@ -951,6 +1000,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:24:05.622Z", "auditd.log.sequence": 574, "event.action": "execve", "event.dataset": "auditd.log", @@ -969,6 +1019,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:24:32.536Z", "auditd.log.sequence": 577, "event.action": "execve", "event.dataset": "auditd.log", @@ -998,6 +1049,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:25:32.552Z", "auditd.log.sequence": 580, "event.action": "execve", "event.dataset": "auditd.log", @@ -1027,6 +1079,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:25:34.641Z", "auditd.log.sequence": 581, "event.action": "execve", "event.dataset": "auditd.log", @@ -1045,6 +1098,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:25:34.645Z", "auditd.log.sequence": 582, "event.action": "execve", "event.dataset": "auditd.log", @@ -1063,6 +1117,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:25:34.648Z", "auditd.log.sequence": 583, "event.action": "execve", "event.dataset": "auditd.log", @@ -1081,6 +1136,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:25:34.652Z", "auditd.log.sequence": 584, "event.action": "execve", "event.dataset": "auditd.log", @@ -1099,6 +1155,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:26:32.568Z", "auditd.log.sequence": 587, "event.action": "execve", "event.dataset": "auditd.log", @@ -1128,6 +1185,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:27:03.670Z", "auditd.log.sequence": 588, "event.action": "execve", "event.dataset": "auditd.log", @@ -1146,6 +1204,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:27:03.674Z", "auditd.log.sequence": 589, "event.action": "execve", "event.dataset": "auditd.log", @@ -1164,6 +1223,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:27:03.678Z", "auditd.log.sequence": 590, "event.action": "execve", "event.dataset": "auditd.log", @@ -1182,6 +1242,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:27:03.681Z", "auditd.log.sequence": 591, "event.action": "execve", "event.dataset": "auditd.log", @@ -1200,6 +1261,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:27:32.585Z", "auditd.log.sequence": 594, "event.action": "execve", "event.dataset": "auditd.log", @@ -1229,6 +1291,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:28.279Z", "auditd.log.sequence": 597, "event.action": "execve", "event.dataset": "auditd.log", @@ -1247,6 +1310,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:32.602Z", "auditd.log.sequence": 600, "event.action": "execve", "event.dataset": "auditd.log", @@ -1276,6 +1340,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:32.699Z", "auditd.log.sequence": 601, "event.action": "execve", "event.dataset": "auditd.log", @@ -1294,6 +1359,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:32.703Z", "auditd.log.sequence": 602, "event.action": "execve", "event.dataset": "auditd.log", @@ -1312,6 +1378,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:32.707Z", "auditd.log.sequence": 603, "event.action": "execve", "event.dataset": "auditd.log", @@ -1330,6 +1397,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:28:32.710Z", "auditd.log.sequence": 604, "event.action": "execve", "event.dataset": "auditd.log", @@ -1348,6 +1416,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:29:32.619Z", "auditd.log.sequence": 607, "event.action": "execve", "event.dataset": "auditd.log", @@ -1377,6 +1446,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:30:01.729Z", "auditd.log.sequence": 608, "event.action": "execve", "event.dataset": "auditd.log", @@ -1395,6 +1465,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:30:01.733Z", "auditd.log.sequence": 609, "event.action": "execve", "event.dataset": "auditd.log", @@ -1413,6 +1484,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:30:01.737Z", "auditd.log.sequence": 610, "event.action": "execve", "event.dataset": "auditd.log", @@ -1431,6 +1503,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:30:01.740Z", "auditd.log.sequence": 611, "event.action": "execve", "event.dataset": "auditd.log", @@ -1449,6 +1522,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:30:32.635Z", "auditd.log.sequence": 614, "event.action": "execve", "event.dataset": "auditd.log", @@ -1478,6 +1552,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:29.545Z", "auditd.log.sequence": 615, "event.action": "execve", "event.dataset": "auditd.log", @@ -1496,6 +1571,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:30.759Z", "auditd.log.sequence": 618, "event.action": "execve", "event.dataset": "auditd.log", @@ -1514,6 +1590,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:30.765Z", "auditd.log.sequence": 619, "event.action": "execve", "event.dataset": "auditd.log", @@ -1532,6 +1609,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:30.769Z", "auditd.log.sequence": 620, "event.action": "execve", "event.dataset": "auditd.log", @@ -1550,6 +1628,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:30.772Z", "auditd.log.sequence": 621, "event.action": "execve", "event.dataset": "auditd.log", @@ -1568,6 +1647,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:31:32.652Z", "auditd.log.sequence": 624, "event.action": "execve", "event.dataset": "auditd.log", @@ -1597,6 +1677,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:32:32.668Z", "auditd.log.sequence": 627, "event.action": "execve", "event.dataset": "auditd.log", @@ -1626,6 +1707,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:32:59.791Z", "auditd.log.sequence": 628, "event.action": "execve", "event.dataset": "auditd.log", @@ -1644,6 +1726,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:32:59.795Z", "auditd.log.sequence": 629, "event.action": "execve", "event.dataset": "auditd.log", @@ -1662,6 +1745,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:32:59.799Z", "auditd.log.sequence": 630, "event.action": "execve", "event.dataset": "auditd.log", @@ -1680,6 +1764,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:32:59.802Z", "auditd.log.sequence": 631, "event.action": "execve", "event.dataset": "auditd.log", @@ -1698,6 +1783,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:33:32.684Z", "auditd.log.sequence": 634, "event.action": "execve", "event.dataset": "auditd.log", @@ -1727,6 +1813,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:34:28.821Z", "auditd.log.sequence": 635, "event.action": "execve", "event.dataset": "auditd.log", @@ -1745,6 +1832,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:34:28.825Z", "auditd.log.sequence": 636, "event.action": "execve", "event.dataset": "auditd.log", @@ -1763,6 +1851,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:34:28.829Z", "auditd.log.sequence": 637, "event.action": "execve", "event.dataset": "auditd.log", @@ -1781,6 +1870,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:34:28.832Z", "auditd.log.sequence": 638, "event.action": "execve", "event.dataset": "auditd.log", @@ -1799,6 +1889,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-12-07T02:34:29.999Z", "auditd.log.sequence": 639, "event.action": "execve", "event.dataset": "auditd.log", diff --git a/filebeat/module/auditd/log/test/test.log-expected.json b/filebeat/module/auditd/log/test/test.log-expected.json index af1e33ca542d..0e6104f0e46d 100644 --- a/filebeat/module/auditd/log/test/test.log-expected.json +++ b/filebeat/module/auditd/log/test/test.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-01-31T20:17:14.891Z", "auditd.log.dst_prefixlen": 16, "auditd.log.op": "SPD-delete", "auditd.log.sequence": 18877201, @@ -21,6 +22,7 @@ "user.audit.id": "4294967295" }, { + "@timestamp": "2017-01-31T20:17:14.891Z", "auditd.log.a0": "9", "auditd.log.a1": "7f564b2672a0", "auditd.log.a2": "b8", @@ -64,6 +66,7 @@ "user.saved.id": "0" }, { + "@timestamp": "2017-03-14T19:20:56.192Z", "auditd.log.record_type": "USER_CMD", "auditd.log.sequence": 19600329, "auditd.log.ses": "11988", @@ -97,6 +100,7 @@ "user.id": "497" }, { + "@timestamp": "2016-12-07T02:17:21.515Z", "auditd.log.cipher": "chacha20-poly1305@openssh.com", "auditd.log.direction": "from-server", "auditd.log.ksize": 512, @@ -146,6 +150,7 @@ "user.saved.id": "74" }, { + "@timestamp": "2017-04-11T15:21:03.550Z", "auditd.log.data": "eh^?^?echo test^Mvim /etc/pam.d/password-auth-ac^Mman pam_tty_audit^Mman pam.d^Mvim /etc^Asudo ^E/pamd.sy^?^?^?^?^?.^?m.d/sy^I-a^Ia^?-a^I^Mman pam^Mt^?grep sys^?^?^?/var/lo^Ig/me^Is^I | grep pam_tty^Mgrep pam_tty /var/log/mes^I^M^[[A^Asudo ^Msudo su^M", "auditd.log.major": "136", "auditd.log.minor": "0", @@ -169,6 +174,7 @@ "user.id": "1000" }, { + "@timestamp": "2016-01-03T00:37:51.394Z", "auditd.log.proctitle": "bash", "auditd.log.sequence": 194438, "event.action": "proctitle", @@ -182,6 +188,7 @@ "service.type": "auditd" }, { + "@timestamp": "2016-01-03T00:37:51.394Z", "auditd.log.proctitle": "sshd: burn [priv]", "auditd.log.sequence": 194440, "event.action": "proctitle", @@ -195,6 +202,7 @@ "service.type": "auditd" }, { + "@timestamp": "2019-11-15T19:01:24.309Z", "auditd.log.gpg_res": "1", "auditd.log.key_enforce": "0", "auditd.log.record_type": "SOFTWARE_UPDATE", @@ -229,6 +237,7 @@ "user.id": "0" }, { + "@timestamp": "2019-11-15T19:00:56.144Z", "auditd.log.record_type": "SYSTEM_BOOT", "auditd.log.sequence": 5, "auditd.log.ses": "4294967295", @@ -254,6 +263,7 @@ "user.id": "0" }, { + "@timestamp": "2019-11-15T19:01:57.054Z", "auditd.log.record_type": "SYSTEM_SHUTDOWN", "auditd.log.sequence": 1163, "auditd.log.ses": "4294967295", @@ -279,6 +289,7 @@ "user.id": "0" }, { + "@timestamp": "2020-02-10T21:59:44.206Z", "auditd.log.sequence": 579393, "event.action": "execve", "event.dataset": "auditd.log", @@ -296,6 +307,7 @@ "service.type": "auditd" }, { + "@timestamp": "2020-02-10T21:59:44.206Z", "auditd.log.a0": "0x1fd05c0", "auditd.log.a1": "0x1fd2730", "auditd.log.a2": "0x1fd4640", @@ -338,6 +350,7 @@ "user.saved.id": "vagrant" }, { + "@timestamp": "2020-02-10T21:59:44.206Z", "auditd.log.name": "mymodule", "auditd.log.record_type": "KERN_MODULE", "auditd.log.sequence": 579397, @@ -360,6 +373,7 @@ "service.type": "auditd" }, { + "@timestamp": "2017-12-17T10:44:41.075Z", "auditd.log.op": "create", "auditd.log.reason": "api", "auditd.log.record_type": "VIRT_CONTROL", @@ -387,6 +401,7 @@ "user.name": "root" }, { + "@timestamp": "2016-12-16T15:45:43.572Z", "auditd.log.img-ctx": "system_u:object_r:svirt_image_t:s0:c444,c977", "auditd.log.model": "selinux", "auditd.log.record_type": "VIRT_MACHINE_ID", diff --git a/filebeat/module/auditd/log/test/useradd.log-expected.json b/filebeat/module/auditd/log/test/useradd.log-expected.json index 30d1ad5138c0..d76ad1288ad5 100644 --- a/filebeat/module/auditd/log/test/useradd.log-expected.json +++ b/filebeat/module/auditd/log/test/useradd.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2021-01-17T17:12:33.686Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.id": "1004", "auditd.log.op": "adding group to /etc/group", @@ -37,6 +38,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:33.710Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.id": "1004", "auditd.log.op": "adding group to /etc/gshadow", @@ -74,6 +76,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:33.710Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.id": "1004", "auditd.log.record_type": "ADD_GROUP", @@ -110,6 +113,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:33.730Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.id": "1004", "auditd.log.op": "adding user", @@ -147,6 +151,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:33.814Z", "auditd.log.hostname": "localhost", "auditd.log.record_type": "USER_ACCT", "auditd.log.reset": "0", @@ -183,6 +188,7 @@ "user.terminal": "/dev/pts/2" }, { + "@timestamp": "2021-01-17T17:12:38.174Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.op": "PAM:chauthtok", "auditd.log.record_type": "USER_CHAUTHTOK", @@ -220,6 +226,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:38.178Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.op": "PAM:authentication", "auditd.log.record_type": "USER_AUTH", @@ -255,6 +262,7 @@ "user.terminal": "pts/2" }, { + "@timestamp": "2021-01-17T17:12:38.178Z", "auditd.log.hostname": "ubuntu-bionic", "auditd.log.op": "PAM:accounting", "auditd.log.record_type": "USER_ACCT", diff --git a/filebeat/tests/system/test_modules.py b/filebeat/tests/system/test_modules.py index 83769d83d1dc..aa6bc02048d7 100644 --- a/filebeat/tests/system/test_modules.py +++ b/filebeat/tests/system/test_modules.py @@ -25,6 +25,7 @@ "f5.bigipafm", "fortinet.clientendpoint", "haproxy.log", + "ibmmq.errorlog", "icinga.startup", "imperva.securesphere", "infoblox.nios", @@ -299,7 +300,7 @@ def clean_keys(obj): host_keys.append("host.name") # The create timestamps area always new - time_keys = ["event.created", "event.ingested", "@timestamp"] + time_keys = ["event.created", "event.ingested"] # source path and agent.version can be different for each run other_keys = ["log.file.path", "agent.version"] # ECS versions change for any ECS release, large or small diff --git a/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json index ebd653dfbc07..81c80ebf991e 100644 --- a/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/asa.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -54,6 +55,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11757", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -114,6 +116,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11749", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -175,6 +178,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11748", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -236,6 +240,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11745", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -297,6 +302,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11744", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -358,6 +364,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11742", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -419,6 +426,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11738", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -480,6 +488,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11739", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -541,6 +550,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11731", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -602,6 +612,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11723", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -663,6 +674,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11715", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -724,6 +736,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11711", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -785,6 +798,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11712", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -846,6 +860,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11708", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -907,6 +922,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11746", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -968,6 +984,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11706", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1029,6 +1046,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11702", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1090,6 +1108,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11753", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -1151,6 +1170,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1205,6 +1225,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11758", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1265,6 +1286,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11758", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1325,6 +1347,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11759", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1385,6 +1408,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11759", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1445,6 +1469,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1499,6 +1524,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11760", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1559,6 +1585,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1613,6 +1640,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11761", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1673,6 +1701,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11762", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1733,6 +1762,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11763", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -1793,6 +1823,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11762", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1853,6 +1884,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11763", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -1913,6 +1945,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -1967,6 +2000,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11764", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2027,6 +2061,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2081,6 +2116,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11772", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2141,6 +2177,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11773", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2201,6 +2238,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11772", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2261,6 +2299,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11773", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2321,6 +2360,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2375,6 +2415,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11774", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2435,6 +2476,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11775", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2495,6 +2537,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11776", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2555,6 +2598,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11775", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2615,6 +2659,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11776", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2675,6 +2720,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -2729,6 +2775,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11777", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2789,6 +2836,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11777", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -2850,6 +2898,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11779", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -2910,6 +2959,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11778", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2970,6 +3020,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11779", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -3030,6 +3081,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3084,6 +3136,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11780", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3144,6 +3197,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3198,6 +3252,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11781", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3258,6 +3313,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3312,6 +3368,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11782", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3372,6 +3429,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11783", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3432,6 +3490,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11783", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -3492,6 +3551,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3546,6 +3606,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11784", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3606,6 +3667,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3660,6 +3722,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11785", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3720,6 +3783,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11786", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3780,6 +3844,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11784", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -3841,6 +3906,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -3895,6 +3961,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11787", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -3955,6 +4022,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11786", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -4015,6 +4083,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4069,6 +4138,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11788", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -4129,6 +4199,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4187,6 +4258,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4241,6 +4313,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11797", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.156.80", @@ -4301,6 +4374,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4359,6 +4433,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4417,6 +4492,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4475,6 +4551,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4533,6 +4610,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4591,6 +4669,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "inside", @@ -4649,6 +4728,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11564", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -4710,6 +4790,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11797", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302014", @@ -4771,6 +4852,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -4825,6 +4907,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11798", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.156.80", @@ -4885,6 +4968,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -4942,6 +5026,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -4999,6 +5084,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5056,6 +5142,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5113,6 +5200,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5170,6 +5258,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5227,6 +5316,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5284,6 +5374,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5341,6 +5432,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5398,6 +5490,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5455,6 +5548,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5512,6 +5606,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5569,6 +5664,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "inbound", @@ -5626,6 +5722,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -5680,6 +5777,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11799", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", @@ -5740,6 +5838,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -5794,6 +5893,7 @@ ] }, { + "@timestamp": "2018-10-10T12:34:56.000-02:00", "cisco.asa.connection_id": "11800", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "172.31.98.44", diff --git a/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json index 598cd963c84b..e959ed691457 100644 --- a/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/hostnames.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2019-10-10T10:21:36.000-02:00", "cisco.asa.mapped_source_ip": "10.0.55.66", "cisco.asa.message_id": "302021", "destination.domain": "target.destination.hostname.local", @@ -47,6 +48,7 @@ ] }, { + "@timestamp": "2011-06-04T21:59:52.000-02:00", "cisco.asa.icmp_code": 0, "cisco.asa.icmp_type": 8, "cisco.asa.mapped_source_ip": "192.0.2.134", diff --git a/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json index 2301c80480a8..09357b0121bf 100644 --- a/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/not-ip.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2019-10-04T15:27:55.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "AL-DMZ-LB-IN", @@ -52,6 +53,7 @@ ] }, { + "@timestamp": "2020-01-01T10:42:53.000-02:00", "cisco.asa.mapped_source_host": "mydomain.example.net", "cisco.asa.message_id": "302021", "destination.address": "172.24.177.29", @@ -100,6 +102,7 @@ ] }, { + "@timestamp": "2020-01-02T11:33:20.000-02:00", "cisco.asa.destination_interface": "wan", "cisco.asa.mapped_destination_host": "www.example.org", "cisco.asa.mapped_destination_port": 80, diff --git a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json index 70dc3befff2f..65608c192ee3 100644 --- a/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json +++ b/x-pack/filebeat/module/cisco/asa/test/sample.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2013-04-15T09:36:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_dmz", @@ -50,6 +51,7 @@ ] }, { + "@timestamp": "2013-04-15T09:36:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_dmz", @@ -100,6 +102,7 @@ ] }, { + "@timestamp": "2014-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -151,6 +154,7 @@ ] }, { + "@timestamp": "2013-04-24T16:00:28.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "inside", @@ -206,6 +210,7 @@ ] }, { + "@timestamp": "2013-04-24T16:00:27.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "inside", @@ -261,6 +266,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -308,6 +314,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743274", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.3.42", @@ -362,6 +369,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -409,6 +417,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743275", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.1.35", @@ -465,6 +474,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "outside", @@ -512,6 +522,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743276", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "10.123.3.130", @@ -568,6 +579,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743275", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -621,6 +633,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "666", "cisco.asa.destination_interface": "inside", "cisco.asa.destination_username": "user2", @@ -683,6 +696,7 @@ "user.name": "user2" }, { + "@timestamp": "2011-06-04T21:59:52.000-02:00", "cisco.asa.mapped_source_ip": "192.168.132.46", "cisco.asa.message_id": "302021", "destination.address": "172.24.177.29", @@ -731,6 +745,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "305011", "cisco.asa.source_interface": "inside", @@ -778,6 +793,7 @@ ] }, { + "@timestamp": "2013-04-29T12:59:50.000-02:00", "cisco.asa.connection_id": "89743277", "cisco.asa.destination_interface": "inside", "cisco.asa.mapped_destination_ip": "10.0.0.130", @@ -834,6 +850,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:33.000-02:00", "cisco.asa.message_id": "106007", "destination.address": "10.1.2.60", "destination.ip": "10.1.2.60", @@ -881,6 +898,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:38.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -931,6 +949,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:38.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -981,6 +1000,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1031,6 +1051,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1081,6 +1102,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1131,6 +1153,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:40.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1181,6 +1204,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:41.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1231,6 +1255,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:47.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1281,6 +1306,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:48.000-02:00", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1331,6 +1357,7 @@ ] }, { + "@timestamp": "2013-04-30T09:22:56.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1381,6 +1408,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:02.000-02:00", "cisco.asa.message_id": "106006", "cisco.asa.source_interface": "inside", "destination.address": "10.1.2.42", @@ -1429,6 +1457,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:03.000-02:00", "cisco.asa.message_id": "106007", "destination.address": "10.1.5.60", "destination.ip": "10.1.5.60", @@ -1476,6 +1505,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:06.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1526,6 +1556,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:08.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1576,6 +1607,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:15.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1626,6 +1658,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1676,6 +1709,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1726,6 +1760,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:40.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_out", @@ -1776,6 +1811,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:41.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "acl_out", @@ -1826,6 +1862,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:43.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1876,6 +1913,7 @@ ] }, { + "@timestamp": "2013-04-30T09:23:43.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1926,6 +1964,7 @@ ] }, { + "@timestamp": "2018-04-15T11:34:34.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106100", "cisco.asa.rule_name": "acl_in", @@ -1977,6 +2016,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.connection_id": "447235", "cisco.asa.destination_interface": "identity", "cisco.asa.mapped_destination_ip": "10.0.13.13", @@ -2031,6 +2071,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2082,6 +2123,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:24.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2133,6 +2175,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_host": "OCSP_Server", @@ -2188,6 +2231,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_host": "OCSP_Server", @@ -2243,6 +2287,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:31.000-02:00", "cisco.asa.connection_id": "447236", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2298,6 +2343,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.connection_id": "447234", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2353,6 +2399,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.connection_id": "447234", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2408,6 +2455,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.message_id": "106015", "cisco.asa.source_interface": "outside", "destination.address": "192.168.1.34", @@ -2456,6 +2504,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:38.000-02:00", "cisco.asa.message_id": "106015", "cisco.asa.source_interface": "outside", "destination.address": "192.168.1.34", @@ -2504,6 +2553,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:39.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "dmz", @@ -2555,6 +2605,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_ip": "192.168.1.34", @@ -2609,6 +2660,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.mapped_destination_ip": "192.168.1.34", @@ -2663,6 +2715,7 @@ ] }, { + "@timestamp": "2018-12-11T08:01:53.000-02:00", "cisco.asa.connection_id": "447237", "cisco.asa.destination_interface": "dmz", "cisco.asa.message_id": "302014", @@ -2718,6 +2771,7 @@ ] }, { + "@timestamp": "2012-08-15T23:30:09.000-02:00", "cisco.asa.connection_id": "40", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "302016", @@ -2771,6 +2825,7 @@ ] }, { + "@timestamp": "2014-09-12T06:50:53.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -2818,6 +2873,7 @@ ] }, { + "@timestamp": "2014-09-12T06:51:01.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -2865,6 +2921,7 @@ ] }, { + "@timestamp": "2014-09-12T06:51:05.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -2912,6 +2969,7 @@ ] }, { + "@timestamp": "2014-09-12T06:51:05.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.47", @@ -2959,6 +3017,7 @@ ] }, { + "@timestamp": "2014-09-12T06:51:06.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -3006,6 +3065,7 @@ ] }, { + "@timestamp": "2014-09-12T06:51:17.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.88.99.57", @@ -3053,6 +3113,7 @@ ] }, { + "@timestamp": "2014-09-12T06:52:48.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.168.1.255", @@ -3100,6 +3161,7 @@ ] }, { + "@timestamp": "2014-09-12T06:53:00.000-02:00", "cisco.asa.message_id": "106016", "cisco.asa.source_interface": "Mobile_Traffic", "destination.address": "192.168.1.255", @@ -3147,6 +3209,7 @@ ] }, { + "@timestamp": "2014-09-12T06:53:01.000-02:00", "cisco.asa.destination_interface": "inside", "cisco.asa.message_id": "106023", "cisco.asa.rule_name": "PERMIT_IN", @@ -3202,6 +3265,7 @@ ] }, { + "@timestamp": "2014-09-12T06:53:02.000-02:00", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, "cisco.asa.message_id": "313001", @@ -3250,6 +3314,7 @@ ] }, { + "@timestamp": "2015-01-14T13:16:13.000-02:00", "cisco.asa.icmp_type": 0, "cisco.asa.message_id": "313004", "cisco.asa.source_interface": "inside", @@ -3296,6 +3361,7 @@ ] }, { + "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outside", "cisco.asa.mapped_destination_ip": "192.88.99.129", "cisco.asa.mapped_destination_port": 80, @@ -3358,6 +3424,7 @@ ] }, { + "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outsidet", "cisco.asa.mapped_destination_ip": "192.0.2.223", "cisco.asa.mapped_destination_port": 80, @@ -3415,6 +3482,7 @@ ] }, { + "@timestamp": "2015-01-14T13:16:14.000-02:00", "cisco.asa.destination_interface": "outsidet", "cisco.asa.mapped_destination_ip": "192.0.2.223", "cisco.asa.mapped_destination_port": 80, @@ -3473,6 +3541,7 @@ ] }, { + "@timestamp": "2009-11-16T14:12:35.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "192.0.2.1", "destination.ip": "192.0.2.1", @@ -3515,6 +3584,7 @@ "url.path": "/app" }, { + "@timestamp": "2009-11-16T14:12:36.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "192.0.2.32", "destination.ip": "192.0.2.32", @@ -3559,6 +3629,7 @@ "url.scheme": "http" }, { + "@timestamp": "2009-11-16T14:12:37.000-02:00", "cisco.asa.message_id": "304002", "cisco.asa.source_interface": "inside", "destination.address": "192.0.0.19", @@ -3606,6 +3677,7 @@ "url.scheme": "http" }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "27215708", "cisco.asa.destination_interface": "vlan-42", "cisco.asa.mapped_destination_ip": "81.2.69.143", @@ -3674,6 +3746,7 @@ ] }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.message_id": "304001", "destination.address": "172.17.6.211", "destination.ip": "172.17.6.211", @@ -3723,6 +3796,7 @@ "url.scheme": "http" }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "195207391", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "89.160.20.156", @@ -3797,6 +3871,7 @@ ] }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.connection_id": "195207391", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "89.160.20.156", @@ -3875,6 +3950,7 @@ ] }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "LOCAL\\USER001", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -3939,6 +4015,7 @@ "user.name": "USER001" }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "LOCAL\\user@domain.tld", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -4008,6 +4085,7 @@ "user.name": "user@domain.tld" }, { + "@timestamp": "2021-01-13T19:12:37.000-02:00", "cisco.asa.destination_username": "AD\\USER002", "cisco.asa.icmp_code": 3, "cisco.asa.icmp_type": 3, @@ -4076,6 +4154,7 @@ "user.name": "USER002" }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "OUTSIDE", @@ -4134,6 +4213,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.icmp_code": 0, "cisco.asa.icmp_type": 134, "cisco.asa.mapped_source_ip": "fe80::2205:baff:fe9d:f637", @@ -4179,6 +4259,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "251933191", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "2a03:2880:f253:cb:face:b00c:0:43fe", @@ -4233,6 +4314,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "305012", "cisco.asa.source_interface": "OUTSIDE", @@ -4303,6 +4385,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261246338", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.message_id": "302014", @@ -4378,6 +4461,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261311655", "cisco.asa.destination_interface": "INSIDE", "cisco.asa.mapped_destination_ip": "192.168.0.1", @@ -4453,6 +4537,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261311655", "cisco.asa.destination_interface": "INSIDE", "cisco.asa.message_id": "302016", @@ -4526,6 +4611,7 @@ ] }, { + "@timestamp": "2021-01-15T19:12:37.000-02:00", "cisco.asa.connection_id": "261246338", "cisco.asa.destination_interface": "OUTSIDE", "cisco.asa.mapped_destination_ip": "40.0.0.1", @@ -4601,6 +4687,7 @@ ] }, { + "@timestamp": "2021-07-29T08:35:29.000-02:00", "cisco.asa.message_id": "602304", "cisco.asa.tunnel_type": "LAN-to-LAN", "destination.address": "81.2.69.1452", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/288_auto_clear_users_history_start.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/288_auto_clear_users_history_start.log-expected.json index 0ed48dfb9c0c..9cae2c6ba1ea 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/288_auto_clear_users_history_start.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/288_auto_clear_users_history_start.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T03:00:20.000-02:00", + "@timestamp": "2022-03-08T03:00:20.000-02:00", "cyberarkpas.audit.action": "Auto Clear Users History start", "cyberarkpas.audit.desc": "Auto Clear Users History start", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/289_auto_clear_users_history_end.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/289_auto_clear_users_history_end.log-expected.json index 4476ba0f803d..072d75b33f80 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/289_auto_clear_users_history_end.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/289_auto_clear_users_history_end.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T03:00:20.000-02:00", + "@timestamp": "2022-03-08T03:00:20.000-02:00", "cyberarkpas.audit.action": "Auto Clear Users History end", "cyberarkpas.audit.desc": "Auto Clear Users History end", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/310_monitor_dr_replication_start.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/310_monitor_dr_replication_start.log-expected.json index 5b958288c536..d5a9961da301 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/310_monitor_dr_replication_start.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/310_monitor_dr_replication_start.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T02:48:07.000-02:00", + "@timestamp": "2022-03-08T02:48:07.000-02:00", "cyberarkpas.audit.action": "Monitor DR Replication start", "cyberarkpas.audit.desc": "Monitor DR Replication start", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/311_monitor_dr_replication_end.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/311_monitor_dr_replication_end.log-expected.json index e4999439beab..696e2ea23020 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/311_monitor_dr_replication_end.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/311_monitor_dr_replication_end.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T02:48:07.000-02:00", + "@timestamp": "2022-03-08T02:48:07.000-02:00", "cyberarkpas.audit.action": "Monitor DR Replication end", "cyberarkpas.audit.desc": "Monitor DR Replication end", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/357_monitor_fw_rules_start.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/357_monitor_fw_rules_start.log-expected.json index a3b04bd34cfa..e04dc95c4b5c 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/357_monitor_fw_rules_start.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/357_monitor_fw_rules_start.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T02:32:56.000-02:00", + "@timestamp": "2022-03-08T02:32:56.000-02:00", "cyberarkpas.audit.action": "Monitor FW rules start", "cyberarkpas.audit.desc": "Monitor FW rules start", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/358_monitor_fw_rules_end.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/358_monitor_fw_rules_end.log-expected.json index a5af60dcea03..97fcd7a22e83 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/358_monitor_fw_rules_end.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/358_monitor_fw_rules_end.log-expected.json @@ -38,7 +38,7 @@ ] }, { - "@timestamp": "2021-03-08T02:32:56.000-02:00", + "@timestamp": "2022-03-08T02:32:56.000-02:00", "cyberarkpas.audit.action": "Monitor FW Rules end", "cyberarkpas.audit.desc": "Monitor FW Rules end", "cyberarkpas.audit.issuer": "Batch", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/479_security_warning_the_signature_hash_algorithm_of_the_vault_certificate_is_sha1.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/479_security_warning_the_signature_hash_algorithm_of_the_vault_certificate_is_sha1.log-expected.json index e127969e7f2a..78fd1127daf7 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/479_security_warning_the_signature_hash_algorithm_of_the_vault_certificate_is_sha1.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/479_security_warning_the_signature_hash_algorithm_of_the_vault_certificate_is_sha1.log-expected.json @@ -39,7 +39,7 @@ ] }, { - "@timestamp": "2021-03-08T07:46:54.000-02:00", + "@timestamp": "2022-03-08T07:46:54.000-02:00", "cyberarkpas.audit.action": "Security warning - The Signature Hash Algorithm of the Vault certificate is SHA1.", "cyberarkpas.audit.desc": "Security warning - The Signature Hash Algorithm of the Vault certificate is SHA1.", "cyberarkpas.audit.issuer": "Builtin", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/59_clear_safe_history.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/59_clear_safe_history.log-expected.json index 21d71f71183a..65619e9c9d1e 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/59_clear_safe_history.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/59_clear_safe_history.log-expected.json @@ -39,7 +39,7 @@ ] }, { - "@timestamp": "2021-03-08T03:10:31.000-02:00", + "@timestamp": "2022-03-08T03:10:31.000-02:00", "cyberarkpas.audit.action": "Clear Safe History", "cyberarkpas.audit.desc": "Clear Safe History", "cyberarkpas.audit.issuer": "PasswordManager", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/88_set_password.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/88_set_password.log-expected.json index bbc572cd230a..60c6a59eca33 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/88_set_password.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/88_set_password.log-expected.json @@ -76,7 +76,7 @@ ] }, { - "@timestamp": "2021-03-08T02:54:46.000-02:00", + "@timestamp": "2022-03-08T02:54:46.000-02:00", "cyberarkpas.audit.action": "Set Password", "cyberarkpas.audit.desc": "Set Password", "cyberarkpas.audit.issuer": "PVWAGWUser", diff --git a/x-pack/filebeat/module/cyberarkpas/audit/test/legacysyslog.log-expected.json b/x-pack/filebeat/module/cyberarkpas/audit/test/legacysyslog.log-expected.json index 14b87c8867c4..b71d3ab351e8 100644 --- a/x-pack/filebeat/module/cyberarkpas/audit/test/legacysyslog.log-expected.json +++ b/x-pack/filebeat/module/cyberarkpas/audit/test/legacysyslog.log-expected.json @@ -1,6 +1,6 @@ [ { - "@timestamp": "2021-03-08T03:41:01.000-02:00", + "@timestamp": "2022-03-08T03:41:01.000-02:00", "cyberarkpas.audit.action": "Retrieve File", "cyberarkpas.audit.desc": "Retrieve File", "cyberarkpas.audit.file": "Root\\Policies\\Policy-BusinessWebsite.ini", diff --git a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json index 78b92a4d5fdc..3f14245d2a33 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json +++ b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json @@ -1,6 +1,6 @@ [ { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -33,7 +33,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -66,7 +66,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -99,7 +99,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -132,7 +132,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -165,7 +165,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -198,7 +198,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -231,7 +231,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -264,7 +264,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -297,7 +297,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -330,7 +330,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -363,7 +363,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -396,7 +396,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.788Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -429,7 +429,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -462,7 +462,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -495,7 +495,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -528,7 +528,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -561,7 +561,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.013Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -594,7 +594,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.014Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -627,7 +627,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.014Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -660,7 +660,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.014Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -693,7 +693,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.014Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -726,7 +726,7 @@ "user.name": "felix" }, { - "@timestamp": "2021-12-03T15:44:37.789Z", + "@timestamp": "2022-01-10T10:25:59.014Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json index 3a12b85cdc75..d01fd9f6f6a6 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/anti-spam.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:48.000-02:00", "client.bytes": 0, "client.port": 0, "destination.bytes": 0, @@ -62,6 +63,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:49.000-02:00", "client.bytes": 0, "client.ip": "89.160.20.156", "client.port": 52742, @@ -140,6 +142,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:50.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.port": 51789, @@ -216,6 +219,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:51.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.14", "client.port": 55002, @@ -292,6 +296,7 @@ ] }, { + "@timestamp": "2017-01-31T18:34:41.000-02:00", "client.bytes": 0, "client.ip": "10.198.47.71", "client.port": 22420, @@ -362,6 +367,7 @@ ] }, { + "@timestamp": "2018-06-06T11:10:11.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 58043, @@ -432,6 +438,7 @@ ] }, { + "@timestamp": "2018-06-06T12:50:07.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60134, @@ -502,6 +509,7 @@ ] }, { + "@timestamp": "2018-06-06T12:51:34.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60298, @@ -570,6 +578,7 @@ ] }, { + "@timestamp": "2018-06-06T12:53:39.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60392, @@ -635,6 +644,7 @@ ] }, { + "@timestamp": "2018-06-06T12:56:53.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 60608, @@ -704,6 +714,7 @@ ] }, { + "@timestamp": "2017-01-31T18:31:11.000-02:00", "client.bytes": 0, "client.ip": "10.198.47.71", "client.port": 22333, diff --git a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json index e21ac56d23d1..ffbbcf87eb7a 100644 --- a/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/anti-virus.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:33.000-02:00", "client.bytes": 550, "client.ip": "172.16.34.24", "client.port": 57695, @@ -73,6 +74,7 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" }, { + "@timestamp": "2020-05-18T14:38:34.000-02:00", "client.bytes": 541, "client.ip": "172.16.34.24", "client.port": 57835, @@ -146,6 +148,7 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" }, { + "@timestamp": "2020-05-18T14:38:35.000-02:00", "client.bytes": 0, "client.ip": "1.128.3.4", "client.port": 56336, @@ -221,6 +224,7 @@ "url.domain": "farasamed.com" }, { + "@timestamp": "2020-05-18T14:38:36.000-02:00", "client.bytes": 0, "client.ip": "216.160.83.61", "client.port": 54693, @@ -303,6 +307,7 @@ "url.domain": "divella.it" }, { + "@timestamp": "2018-06-06T10:51:29.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 56653, @@ -376,6 +381,7 @@ "url.domain": "postman.local" }, { + "@timestamp": "2018-06-06T10:58:29.000-02:00", "client.bytes": 0, "client.ip": "10.198.16.121", "client.port": 56632, @@ -449,6 +455,7 @@ "url.domain": "postman.local" }, { + "@timestamp": "2018-06-21T19:50:23.000-02:00", "client.bytes": 0, "client.ip": "10.146.13.49", "client.port": 39910, @@ -520,6 +527,7 @@ ] }, { + "@timestamp": "2018-06-21T19:50:48.000-02:00", "client.bytes": 0, "client.ip": "10.146.13.49", "client.port": 39936, diff --git a/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json index 61f202c8826b..16b796d1d507 100644 --- a/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/atp.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-01-31T18:44:31.000-02:00", "client.ip": "10.198.47.71", "client.port": 22623, "destination.ip": "46.161.30.47", @@ -64,6 +65,7 @@ "url.original": "46.161.30.47" }, { + "@timestamp": "2020-05-18T14:38:34.000-02:00", "client.ip": "172.16.34.24", "client.port": 57579, "destination.ip": "13.226.155.22", @@ -128,6 +130,7 @@ "url.scheme": "http" }, { + "@timestamp": "2020-05-18T14:38:35.000-02:00", "client.ip": "172.16.34.24", "client.port": 57540, "destination.ip": "13.226.155.22", @@ -192,6 +195,7 @@ "url.scheme": "http" }, { + "@timestamp": "2018-06-05T08:49:00.000-02:00", "client.ip": "10.198.32.89", "client.port": 0, "destination.ip": "82.211.30.202", diff --git a/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json index aa00ab04538c..9bc411835c77 100644 --- a/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/cfilter.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-01-31T14:03:33.000-02:00", "client.ip": "10.198.47.71", "client.port": 9444, "destination.ip": "182.79.221.19", @@ -69,6 +70,7 @@ "url.scheme": "https" }, { + "@timestamp": "2017-02-01T18:20:21.000-02:00", "client.ip": "216.160.83.57", "client.port": 46719, "destination.ip": "216.58.197.44", @@ -144,6 +146,7 @@ "url.scheme": "http" }, { + "@timestamp": "2017-02-01T18:13:29.000-02:00", "client.ip": "216.160.83.57", "client.port": 49128, "destination.ip": "74.125.130.188", @@ -220,6 +223,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:51.000-02:00", "client.ip": "172.17.34.10", "client.port": 62851, "destination.ip": "13.79.168.201", @@ -287,6 +291,7 @@ "url.scheme": "https" }, { + "@timestamp": "2020-05-18T14:38:52.000-02:00", "client.ip": "172.16.34.15", "client.port": 60471, "destination.ip": "40.90.137.127", @@ -356,6 +361,7 @@ "url.scheme": "https" }, { + "@timestamp": "2020-05-18T14:38:53.000-02:00", "client.ip": "1.128.3.4", "client.port": 65391, "destination.ip": "91.228.167.133", @@ -428,6 +434,7 @@ "user_agent.original": "EFSW Update (Windows; U; 64bit; BPC 7.1.12010.0; OS: 10.0.17763 SP 0.0 NT; TDB 45511; CL 1.1.1; x64s; APP efsw; PX 1; PUA 1; CD 1; RA 1; PEV 0; UNS 1; UBR 1158; HVCI 0; SHA256 1; WU 3; HWF: 01009DAA-757A-D666-EFD2-92DD0D501284; PLOC de_de; PCODE 211.0.0; " }, { + "@timestamp": "2016-12-02T18:50:20.000-02:00", "client.ip": "10.108.108.49", "event.action": "alert", "event.category": [ @@ -481,6 +488,7 @@ ] }, { + "@timestamp": "2016-12-02T18:50:20.000-02:00", "client.ip": "192.168.73.220", "client.port": 37832, "destination.ip": "64.233.189.147", @@ -551,6 +559,7 @@ "url.scheme": "http" }, { + "@timestamp": "2016-12-02T18:50:22.000-02:00", "client.ip": "192.168.73.220", "client.port": 46322, "destination.ip": "64.233.188.94", diff --git a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json index 27e381dabcec..26d15e9a785c 100644 --- a/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/event.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:57.000-02:00", "client.ip": "172.17.35.116", "event.category": [ "authentication" @@ -56,6 +57,7 @@ "user.name": "elastic.user@elastic.test.com" }, { + "@timestamp": "2020-05-18T14:38:58.000-02:00", "client.ip": "89.160.20.112", "destination.as.number": 721, "destination.as.organization.name": "DoD Network Information Center", @@ -119,6 +121,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:59.000-02:00", "event.code": "062511318057", "event.dataset": "sophos.xg", "event.kind": "event", @@ -155,6 +158,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:00.000-02:00", "client.ip": "67.43.156.13", "event.category": [ "authentication" @@ -215,6 +219,7 @@ "user.name": "elastic.user@elastic.test.com" }, { + "@timestamp": "2020-05-18T14:39:01.000-02:00", "event.category": [ "host", "malware" @@ -259,6 +264,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:02.000-02:00", "event.code": "063411660022", "event.dataset": "sophos.xg", "event.kind": "event", @@ -296,6 +302,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:03.000-02:00", "client.ip": "81.2.69.145", "event.category": [ "authentication" @@ -358,6 +365,7 @@ "user.name": "elastic.user@elastic.test.com" }, { + "@timestamp": "2020-05-20T05:47:46.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "062811617824", @@ -406,6 +414,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:05.000-02:00", "client.ip": "1.128.3.4", "event.category": [ "authentication" @@ -459,6 +468,7 @@ "user.name": "hendrikl" }, { + "@timestamp": "2020-05-18T14:39:06.000-02:00", "event.code": "066911518017", "event.dataset": "sophos.xg", "event.kind": "event", @@ -496,6 +506,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:07.000-02:00", "client.ip": "10.83.234.5", "event.code": "062009617502", "event.dataset": "sophos.xg", @@ -541,6 +552,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:08.000-02:00", "client.ip": "175.16.199.1", "event.code": "062109517507", "event.dataset": "sophos.xg", @@ -594,6 +606,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:09.000-02:00", "event.code": "063911517818", "event.dataset": "sophos.xg", "event.kind": "event", @@ -631,6 +644,7 @@ ] }, { + "@timestamp": "2020-05-18T14:39:10.000-02:00", "event.code": "063311617923", "event.dataset": "sophos.xg", "event.kind": "event", @@ -666,6 +680,7 @@ ] }, { + "@timestamp": "2020-06-02T06:29:36.000-02:00", "client.bytes": 0, "client.ip": "10.84.234.38", "destination.bytes": 0, @@ -729,6 +744,7 @@ "user.name": "elastic.user@elastic.test.com" }, { + "@timestamp": "2017-03-16T12:56:01.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "066811618014", @@ -774,6 +790,7 @@ ] }, { + "@timestamp": "2017-03-16T12:53:27.000-02:00", "client.bytes": 22368, "destination.bytes": 31488, "event.code": "066811618015", @@ -819,6 +836,7 @@ ] }, { + "@timestamp": "2017-03-16T12:46:26.000-02:00", "client.bytes": 0, "destination.bytes": 0, "event.code": "066811618016", @@ -864,6 +882,7 @@ ] }, { + "@timestamp": "2018-06-06T11:12:10.000-02:00", "event.code": "063711517815", "event.dataset": "sophos.xg", "event.kind": "event", diff --git a/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json index 4f2f390525c1..d6bb070314e0 100644 --- a/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/firewall.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:37.000-02:00", "client.bytes": 459, "client.ip": "1.128.3.4", "client.mac": "00:00:00:00:00:00", @@ -101,6 +102,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:38.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.mac": "00:00:00:00:00:00", @@ -206,6 +208,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:39.000-02:00", "client.bytes": 0, "client.ip": "172.17.35.113", "client.mac": "24:01:c7:07:2b:a2", @@ -292,6 +295,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:40.000-02:00", "client.bytes": 0, "client.ip": "10.82.234.6", "client.nat.port": 0, @@ -381,6 +385,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:41.000-02:00", "client.bytes": 0, "client.ip": "67.43.156.12", "client.mac": "c4:f7:d5:b5:47:f4", @@ -472,6 +477,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:42.000-02:00", "client.bytes": 0, "client.ip": "172.17.35.101", "client.mac": "24:01:c7:07:2b:a2", @@ -563,6 +569,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:43.000-02:00", "client.bytes": 0, "client.ip": "172.16.36.105", "client.mac": "34:db:fd:83:d8:09", @@ -649,6 +656,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:44.000-02:00", "client.bytes": 0, "client.ip": "10.82.234.9", "client.nat.port": 0, @@ -732,6 +740,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:45.000-02:00", "client.bytes": 0, "client.ip": "10.84.234.7", "client.mac": "00:00:00:00:00:00", @@ -831,6 +840,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:45.000-02:00", "client.bytes": 0, "client.ip": "192.168.1.254", "client.mac": "34:db:fd:83:d8:09", @@ -917,6 +927,7 @@ ] }, { + "@timestamp": "2020-06-05T12:38:53.000-02:00", "client.bytes": 1802, "client.ip": "172.17.35.119", "client.mac": "00:00:00:00:00:00", @@ -1007,6 +1018,7 @@ ] }, { + "@timestamp": "2018-05-30T13:26:37.000-02:00", "client.bytes": 0, "client.ip": "10.198.32.19", "client.nat.port": 0, @@ -1097,6 +1109,7 @@ ] }, { + "@timestamp": "2018-06-04T17:20:24.000-02:00", "client.bytes": 0, "client.ip": "0.0.0.0", "client.nat.port": 0, @@ -1177,6 +1190,7 @@ ] }, { + "@timestamp": "2018-05-30T14:01:32.000-02:00", "client.bytes": 0, "client.ip": "10.198.38.184", "client.mac": "c8:5b:76:ab:72:d3", @@ -1261,6 +1275,7 @@ ] }, { + "@timestamp": "2018-05-30T14:17:17.000-02:00", "client.bytes": 0, "client.ip": "10.198.32.19", "client.mac": "b8:97:5a:5b:0f:fd", @@ -1346,6 +1361,7 @@ ] }, { + "@timestamp": "2018-06-05T14:30:31.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.23", "client.nat.port": 0, @@ -1425,6 +1441,7 @@ ] }, { + "@timestamp": "2018-05-31T17:05:14.000-02:00", "client.bytes": 0, "client.ip": "10.198.12.19", "client.nat.port": 0, @@ -1515,6 +1532,7 @@ ] }, { + "@timestamp": "2018-05-30T15:09:51.000-02:00", "client.bytes": 0, "client.ip": "fe80::59f5:3ce8:c98e:5062", "client.mac": "1e:3a:5a:5b:23:ab", @@ -1599,6 +1617,7 @@ ] }, { + "@timestamp": "2018-06-01T10:57:55.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.57", "client.mac": "08:00:27:4c:49:e3", @@ -1682,6 +1701,7 @@ ] }, { + "@timestamp": "2018-06-01T10:55:41.000-02:00", "client.bytes": 0, "client.ip": "10.198.37.57", "client.mac": "08:00:27:4c:49:e3", @@ -1766,6 +1786,7 @@ ] }, { + "@timestamp": "2021-02-11T13:12:45.000-02:00", "client.bytes": 0, "client.ip": "1.2.3.4", "client.mac": "11:22:33:44:55:66", @@ -1867,6 +1888,7 @@ ] }, { + "@timestamp": "2020-06-05T03:45:23.000-02:00", "client.bytes": 0, "client.ip": "10.146.13.30", "client.mac": "00:50:56:99:51:94", diff --git a/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json index 37b56704bb41..2bfe7cdce631 100644 --- a/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/idp.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:54.000-02:00", "client.ip": "67.43.156.12", "client.port": 41528, "destination.ip": "172.16.68.20", @@ -73,6 +74,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:55.000-02:00", "client.ip": "89.160.20.156", "client.port": 58914, "destination.as.number": 35908, @@ -156,6 +158,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:56.000-02:00", "client.ip": "67.43.156.12", "client.port": 59476, "destination.ip": "172.16.68.20", @@ -229,6 +232,7 @@ ] }, { + "@timestamp": "2018-05-23T16:20:34.000-02:00", "client.ip": "10.0.0.168", "client.port": 28938, "destination.ip": "10.1.1.234", @@ -296,6 +300,7 @@ ] }, { + "@timestamp": "2018-05-23T16:16:43.000-02:00", "client.ip": "10.0.1.31", "client.port": 40140, "destination.ip": "10.1.0.115", diff --git a/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json index 15343c1e3e27..21f888b93271 100644 --- a/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/sandbox.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-01-31T14:52:11.000-02:00", "event.action": "Allowed", "event.category": [ "network" @@ -45,6 +46,7 @@ ] }, { + "@timestamp": "2017-01-31T14:52:11.000-02:00", "client.ip": "10.198.47.112", "event.action": "Denied", "event.category": [ @@ -106,6 +108,7 @@ ] }, { + "@timestamp": "2017-01-31T15:28:25.000-02:00", "event.action": "Allowed", "event.category": [ "network" @@ -151,6 +154,7 @@ ] }, { + "@timestamp": "2017-01-31T15:28:25.000-02:00", "client.ip": "10.198.47.112", "event.action": "Pending", "event.category": [ @@ -211,6 +215,7 @@ ] }, { + "@timestamp": "2017-01-31T15:28:25.000-02:00", "client.ip": "10.198.47.112", "event.action": "Denied", "event.category": [ @@ -272,6 +277,7 @@ ] }, { + "@timestamp": "2020-05-18T14:38:36.000-02:00", "client.ip": "172.16.34.24", "event.action": "Denied", "event.category": [ diff --git a/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json index 9af985b4a368..f3f6f6a45978 100644 --- a/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/system-health.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127626618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -36,6 +37,7 @@ ] }, { + "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127726618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -73,6 +75,7 @@ ] }, { + "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "123526618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -114,6 +117,7 @@ ] }, { + "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127826618031", "event.dataset": "sophos.xg", "event.kind": "event", @@ -151,6 +155,7 @@ ] }, { + "@timestamp": "2018-06-05T15:10:00.000-02:00", "event.code": "127926618031", "event.dataset": "sophos.xg", "event.kind": "event", diff --git a/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json index e944e04898d3..0408fb4ab4ea 100644 --- a/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/waf.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2020-05-18T14:38:46.000-02:00", "client.bytes": 1419, "client.ip": "216.160.83.61", "destination.bytes": 401, @@ -74,6 +75,7 @@ "user_agent.original": "Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.4954; Pro)" }, { + "@timestamp": "2020-05-18T14:38:47.000-02:00", "client.bytes": 1774, "client.ip": "216.160.83.61", "destination.bytes": 200, @@ -149,6 +151,7 @@ "user_agent.original": "Microsoft Office/16.0 (Windows NT 6.2; Microsoft Outlook 16.0.4954; Pro)" }, { + "@timestamp": "2020-05-19T17:20:29.000-02:00", "client.bytes": 510, "client.ip": "10.198.235.254", "destination.bytes": 403, @@ -220,6 +223,7 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" }, { + "@timestamp": "2020-05-19T18:03:30.000-02:00", "client.bytes": 715, "client.ip": "10.198.235.254", "destination.bytes": 403, @@ -295,6 +299,7 @@ "user_agent.original": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0" }, { + "@timestamp": "2020-05-20T18:03:31.000-02:00", "client.bytes": 295, "client.ip": "89.160.20.112", "destination.bytes": 403, diff --git a/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json b/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json index d23e1273de3c..d934c831d2ab 100644 --- a/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json +++ b/x-pack/filebeat/module/sophos/xg/test/wifi.log-expected.json @@ -1,5 +1,6 @@ [ { + "@timestamp": "2017-02-01T14:17:35.000-02:00", "event.code": "106025618011", "event.dataset": "sophos.xg", "event.kind": "event", @@ -37,6 +38,7 @@ ] }, { + "@timestamp": "2017-02-01T14:19:47.000-02:00", "event.code": "106025618011", "event.dataset": "sophos.xg", "event.kind": "event", From 6aec024e0ab8239791be20885d6d3c58697d18cd Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Mon, 10 Jan 2022 16:48:18 +0000 Subject: [PATCH 158/172] ci: uses aliases for the branches (#29706) --- .ci/schedule-daily.groovy | 44 +++++++++++++++++++++++++++++--------- .ci/schedule-weekly.groovy | 44 +++++++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/.ci/schedule-daily.groovy b/.ci/schedule-daily.groovy index 5c1cc904f5ca..a326d9759cf4 100644 --- a/.ci/schedule-daily.groovy +++ b/.ci/schedule-daily.groovy @@ -20,13 +20,7 @@ pipeline { stages { stage('Nighly beats builds') { steps { - runBuild(quietPeriod: 0, job: 'Beats/beats/master') - // This should be `current_8` bump.getCurrentMinorReleaseFor8 - runBuild(quietPeriod: 2000, job: 'Beats/beats/8.0') - // This should be `current_7` bump.getCurrentMinorReleaseFor7 or - // `next_minor_7` bump.getNextMinorReleaseFor7 - runBuild(quietPeriod: 4000, job: 'Beats/beats/7.17') - runBuild(quietPeriod: 6000, job: 'Beats/beats/7.16') + runBuilds(quietPeriodFactor: 2000, branches: ['master', '8.', '7.', '7.']) } } } @@ -37,7 +31,37 @@ pipeline { } } -def runBuild(Map args = [:]) { - def jobName = args.job - build(quietPeriod: args.quietPeriod, job: jobName, parameters: [booleanParam(name: 'macosTest', value: true)], wait: false, propagate: false) +def runBuilds(Map args = [:]) { + def branches = [] + // Expand macros and filter duplicated matches. + args.branches.each { branch -> + def branchName = getBranchName(branch) + if (!branches.contains(branchName)) { + branches << branchName + } + } + + def quietPeriod = 0 + branches.each { branch -> + build(quietPeriod: quietPeriod, job: "Beats/beats/${branch}", parameters: [booleanParam(name: 'macosTest', value: true)], wait: false, propagate: false) + // Increate the quiet period for the next iteration + quietPeriod += args.quietPeriodFactor + } +} + +def getBranchName(branch) { + // special macro to look for the latest minor version + if (branch.contains('8.')) { + return bumpUtils.getMajorMinor(bumpUtils.getCurrentMinorReleaseFor8()) + } + if (branch.contains('8.')) { + return bumpUtils.getMajorMinor(bumpUtils.getNextMinorReleaseFor8()) + } + if (branch.contains('7.')) { + return bumpUtils.getMajorMinor(bumpUtils.getCurrentMinorReleaseFor7()) + } + if (branch.contains('7.')) { + return bumpUtils.getMajorMinor(bumpUtils.getNextMinorReleaseFor7()) + } + return branch } diff --git a/.ci/schedule-weekly.groovy b/.ci/schedule-weekly.groovy index 6d5c1a7f0072..a42ae7934fd0 100644 --- a/.ci/schedule-weekly.groovy +++ b/.ci/schedule-weekly.groovy @@ -20,13 +20,7 @@ pipeline { stages { stage('Weekly beats builds') { steps { - runBuild(quietPeriod: 0, job: 'Beats/beats/master') - // This should be `current_8` bump.getCurrentMinorReleaseFor8 - runBuild(quietPeriod: 1000, job: 'Beats/beats/8.0') - // This should be `current_7` bump.getCurrentMinorReleaseFor7 or - // `next_minor_7` bump.getNextMinorReleaseFor7 - runBuild(quietPeriod: 2000, job: 'Beats/beats/7.17') - runBuild(quietPeriod: 3000, job: 'Beats/beats/7.16') + runBuilds(quietPeriodFactor: 1000, branches: ['master', '8.', '7.', '7.']) } } } @@ -37,7 +31,37 @@ pipeline { } } -def runBuild(Map args = [:]) { - def jobName = args.job - build(quietPeriod: args.quietPeriod, job: jobName, parameters: [booleanParam(name: 'awsCloudTests', value: true)], wait: false, propagate: false) +def runBuilds(Map args = [:]) { + def branches = [] + // Expand macros and filter duplicated matches. + args.branches.each { branch -> + def branchName = getBranchName(branch) + if (!branches.contains(branchName)) { + branches << branchName + } + } + + def quietPeriod = 0 + branches.each { branch -> + build(quietPeriod: quietPeriod, job: "Beats/beats/${branch}", parameters: [booleanParam(name: 'awsCloudTests', value: true)], wait: false, propagate: false) + // Increate the quiet period for the next iteration + quietPeriod += args.quietPeriodFactor + } +} + +def getBranchName(branch) { + // special macro to look for the latest minor version + if (branch.contains('8.')) { + return bumpUtils.getMajorMinor(bumpUtils.getCurrentMinorReleaseFor8()) + } + if (branch.contains('8.')) { + return bumpUtils.getMajorMinor(bumpUtils.getNextMinorReleaseFor8()) + } + if (branch.contains('7.')) { + return bumpUtils.getMajorMinor(bumpUtils.getCurrentMinorReleaseFor7()) + } + if (branch.contains('7.')) { + return bumpUtils.getMajorMinor(bumpUtils.getNextMinorReleaseFor7()) + } + return branch } From ed62d2e1dba871edc24af9945bc76b39dcfd7c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 11 Jan 2022 09:13:33 +0100 Subject: [PATCH 159/172] Do not add date to index if `@meta.index` is set (#29775) --- libbeat/beat/events/util.go | 5 ++--- libbeat/idxmgmt/std.go | 19 +------------------ libbeat/idxmgmt/std_test.go | 14 +++----------- 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/libbeat/beat/events/util.go b/libbeat/beat/events/util.go index 46967c82d71b..2c2b9c201874 100644 --- a/libbeat/beat/events/util.go +++ b/libbeat/beat/events/util.go @@ -27,9 +27,8 @@ const ( // precedence over values defined using FieldMetaIndex or FieldMetaRawIndex. FieldMetaAlias = "alias" - // FieldMetaIndex defines the base index name to use for the event. The value is suffixed - // with a Y-m-d value based on the event's timestamp. If set, it takes precedence over the - // value defined using FieldMetaRawIndex. + // FieldMetaIndex defines the data stream name to use for the event. + // If set, it takes precedence over the value defined using FieldMetaRawIndex. FieldMetaIndex = "index" // FieldMetaRawIndex defines the raw index name to use for the event. It is used as-is, without diff --git a/libbeat/idxmgmt/std.go b/libbeat/idxmgmt/std.go index e32fdfd647ca..c9c86444358e 100644 --- a/libbeat/idxmgmt/std.go +++ b/libbeat/idxmgmt/std.go @@ -61,12 +61,6 @@ type indexSelector struct { beatInfo beat.Info } -type ilmIndexSelector struct { - index outil.Selector - st *indexState - beatInfo beat.Info -} - type componentType uint8 //go:generate stringer -linecomment -type componentType @@ -292,15 +286,6 @@ func (m *indexManager) setupWithILM() (bool, error) { return withILM, nil } -func (s *ilmIndexSelector) Select(evt *beat.Event) (string, error) { - if idx := getEventCustomIndex(evt, s.beatInfo); idx != "" { - return idx, nil - } - - idx, err := s.index.Select(evt) - return idx, err -} - func (s indexSelector) Select(evt *beat.Event) (string, error) { if idx := getEventCustomIndex(evt, s.beatInfo); idx != "" { return idx, nil @@ -314,9 +299,7 @@ func getEventCustomIndex(evt *beat.Event, beatInfo beat.Info) string { } if idx, err := events.GetMetaStringValue(*evt, events.FieldMetaIndex); err == nil { - ts := evt.Timestamp.UTC() - return fmt.Sprintf("%s-%d.%02d.%02d", - strings.ToLower(idx), ts.Year(), ts.Month(), ts.Day()) + return strings.ToLower(idx) } // This is functionally identical to Meta["alias"], returning the overriding diff --git a/libbeat/idxmgmt/std_test.go b/libbeat/idxmgmt/std_test.go index 4a7a4c848cbe..8859204be914 100644 --- a/libbeat/idxmgmt/std_test.go +++ b/libbeat/idxmgmt/std_test.go @@ -18,7 +18,6 @@ package idxmgmt import ( - "fmt" "testing" "time" @@ -108,13 +107,6 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { stable := func(s string) nameFunc { return func(_ time.Time) string { return s } } - dateIdx := func(base string) nameFunc { - return func(ts time.Time) string { - ts = ts.UTC() - ext := fmt.Sprintf("%d.%02d.%02d", ts.Year(), ts.Month(), ts.Day()) - return fmt.Sprintf("%v-%v", base, ext) - } - } cases := map[string]struct { ilmCalls []onCall @@ -136,7 +128,7 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { "event index without ilm": { ilmCalls: noILM, cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: dateIdx("test"), + want: stable("test"), meta: common.MapStr{ "index": "test", }, @@ -144,7 +136,7 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { "event index without ilm must be lowercase": { ilmCalls: noILM, cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: dateIdx("test"), + want: stable("test"), meta: common.MapStr{ "index": "Test", }, @@ -162,7 +154,7 @@ func TestDefaultSupport_BuildSelector(t *testing.T) { "event index with ilm": { ilmCalls: ilmTemplateSettings("test-9.9.9"), cfg: map[string]interface{}{"index": "test-%{[agent.version]}"}, - want: dateIdx("event-index"), + want: stable("event-index"), meta: common.MapStr{ "index": "event-index", }, From fbc33ab293f70d41c993eaed187a3b592632152c Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Tue, 11 Jan 2022 10:30:48 +0100 Subject: [PATCH 160/172] ibmmq: Fix timestamp parsing (#29773) This fixes the timestamp parsing in ibmmq logs: - Date processor format definition was broken for ES 8.0 (extra `a` character). - The header date format in some logs was unsupported. - The Time() field, with correct TZ and higher precission was ignored. --- filebeat/tests/system/test_modules.py | 1 - .../module/ibmmq/errorlog/ingest/pipeline.yml | 6 +- .../errorlog/test/AMQERR01.log-expected.json | 30 ++-- .../test/AMQERR01_QM1.log-expected.json | 46 +++--- .../test/AMQERR01_QM2.log-expected.json | 154 +++++++++--------- 5 files changed, 119 insertions(+), 118 deletions(-) diff --git a/filebeat/tests/system/test_modules.py b/filebeat/tests/system/test_modules.py index aa6bc02048d7..96aed80cf15f 100644 --- a/filebeat/tests/system/test_modules.py +++ b/filebeat/tests/system/test_modules.py @@ -25,7 +25,6 @@ "f5.bigipafm", "fortinet.clientendpoint", "haproxy.log", - "ibmmq.errorlog", "icinga.startup", "imperva.securesphere", "infoblox.nios", diff --git a/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml b/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml index 7b30ee7d38a0..6eadaa6b30a7 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml +++ b/x-pack/filebeat/module/ibmmq/errorlog/ingest/pipeline.yml @@ -30,7 +30,7 @@ processors: patterns: - 'Process\(%{DATA:process.pid}\) User\(%{WORD:user.name}\) Program\(%{DATA:process.title}\) Host\(%{DATA:host.hostname}\) Installation\(%{WORD:ibmmq.errorlog.installation}\) - VRMF\(%{DATA:service.version}\)( QMgr\(%{DATA:ibmmq.errorlog.qmgr}\))?( Time\(%{TIMESTAMP_ISO8601:@timestamp}\))?( + VRMF\(%{DATA:service.version}\)( QMgr\(%{DATA:ibmmq.errorlog.qmgr}\))?( Time\(%{TIMESTAMP_ISO8601:log_timestamp}\))?( RemoteHost\(%{DATA:destination.address}\))?( ArithInsert1\(%{DATA:ibmmq.errorlog.arithinsert1}\))?( ArithInsert2\(%{DATA:ibmmq.errorlog.arithinsert2}\))?( CommentInsert1\(%{DATA:ibmmq.errorlog.commentinsert1}\))?( CommentInsert2\(%{DATA:ibmmq.errorlog.commentinsert2}\))?( CommentInsert3\(%{DATA:ibmmq.errorlog.commentinsert3}\))? @@ -41,8 +41,10 @@ processors: field: log_timestamp target_field: '@timestamp' formats: - - MM/dd/yyyy hh:mm:ss aa + - ISO8601 + - MM/dd/yyyy hh:mm:ss a - dd/MM/yyyy HH:mm:ss + - dd.MM.yyyy HH:mm:ss ignore_failure: true - append: field: ibmmq.errorlog.commentinsert diff --git a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01.log-expected.json b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01.log-expected.json index c29d64be9286..ccb30351cb00 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01.log-expected.json +++ b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01.log-expected.json @@ -66,7 +66,7 @@ "user.name": "felix" }, { - "@timestamp": "2018-10-11T10:46:25.000Z", + "@timestamp": "2018-10-11T08:46:25.924Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -99,7 +99,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-11T10:46:26.000Z", + "@timestamp": "2018-10-11T08:46:26.343Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -132,7 +132,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-11T10:46:26.000Z", + "@timestamp": "2018-10-11T08:46:26.346Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -264,7 +264,7 @@ "user.name": "felix" }, { - "@timestamp": "2018-10-28T15:12:07.000Z", + "@timestamp": "2018-10-28T14:12:07.685Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -297,7 +297,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-28T15:12:07.000Z", + "@timestamp": "2018-10-28T14:12:07.789Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -330,7 +330,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-28T15:12:08.000Z", + "@timestamp": "2018-10-28T14:12:08.663Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -363,7 +363,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-28T15:12:08.000Z", + "@timestamp": "2018-10-28T14:12:08.665Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -396,7 +396,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:48:52.000Z", + "@timestamp": "2018-10-29T15:48:52.594Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -429,7 +429,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:48:52.000Z", + "@timestamp": "2018-10-29T15:48:52.663Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -462,7 +462,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:48:53.000Z", + "@timestamp": "2018-10-29T15:48:53.368Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -495,7 +495,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:48:53.000Z", + "@timestamp": "2018-10-29T15:48:53.369Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -528,7 +528,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:49:35.000Z", + "@timestamp": "2018-10-29T15:49:35.477Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -561,7 +561,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:49:35.000Z", + "@timestamp": "2018-10-29T15:49:35.553Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -594,7 +594,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:49:36.000Z", + "@timestamp": "2018-10-29T15:49:36.447Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -627,7 +627,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-29T16:49:36.000Z", + "@timestamp": "2018-10-29T15:49:36.448Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", diff --git a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json index 3f14245d2a33..e472bca49fe6 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json +++ b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM1.log-expected.json @@ -1,6 +1,6 @@ [ { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:00.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -33,7 +33,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:00.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -66,7 +66,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:00.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -99,7 +99,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -132,7 +132,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -165,7 +165,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -198,7 +198,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.012Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -231,7 +231,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -264,7 +264,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -297,7 +297,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -330,7 +330,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -363,7 +363,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -396,7 +396,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -429,7 +429,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -462,7 +462,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:01.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -495,7 +495,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:02.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -528,7 +528,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -561,7 +561,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.013Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -594,7 +594,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.014Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -627,7 +627,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.014Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -660,7 +660,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.014Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -693,7 +693,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.014Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -726,7 +726,7 @@ "user.name": "felix" }, { - "@timestamp": "2022-01-10T10:25:59.014Z", + "@timestamp": "2018-07-13T07:06:03.000Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", diff --git a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM2.log-expected.json b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM2.log-expected.json index ddaa656e1534..fd44a2bbdbc4 100644 --- a/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM2.log-expected.json +++ b/x-pack/filebeat/module/ibmmq/errorlog/test/AMQERR01_QM2.log-expected.json @@ -782,7 +782,7 @@ "user.name": "felix" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.779Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -816,7 +816,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.803Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -850,7 +850,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.806Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -884,7 +884,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.815Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -918,7 +918,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.818Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -952,7 +952,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.828Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -986,7 +986,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.834Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1020,7 +1020,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.907Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1054,7 +1054,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.907Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1088,7 +1088,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.907Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1122,7 +1122,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.907Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1156,7 +1156,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:18.000Z", + "@timestamp": "2018-10-17T11:50:18.908Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1190,7 +1190,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.011Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1224,7 +1224,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.012Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1258,7 +1258,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.108Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1292,7 +1292,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.108Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1326,7 +1326,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.109Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1360,7 +1360,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.109Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1394,7 +1394,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.109Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1428,7 +1428,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.109Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1462,7 +1462,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.110Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1496,7 +1496,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.123Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1530,7 +1530,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.124Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1564,7 +1564,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.124Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1598,7 +1598,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.124Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1632,7 +1632,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.125Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1666,7 +1666,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.124Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1700,7 +1700,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.125Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1734,7 +1734,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.124Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1768,7 +1768,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.125Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1802,7 +1802,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.125Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1836,7 +1836,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.126Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1870,7 +1870,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.131Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1904,7 +1904,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.131Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1938,7 +1938,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.132Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -1972,7 +1972,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.238Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2006,7 +2006,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.269Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2040,7 +2040,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.349Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2074,7 +2074,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.401Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2108,7 +2108,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-17T13:50:19.000Z", + "@timestamp": "2018-10-17T11:50:19.638Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2142,7 +2142,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T15:18:48.000Z", + "@timestamp": "2018-10-18T13:18:48.524Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2176,7 +2176,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T15:19:11.000Z", + "@timestamp": "2018-10-18T13:19:11.833Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2210,7 +2210,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:06.000Z", + "@timestamp": "2018-10-18T14:10:06.407Z", "destination.address": "127.0.0.1", "event.dataset": "ibmmq.errorlog", "event.kind": "event", @@ -2245,7 +2245,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:06.000Z", + "@timestamp": "2018-10-18T14:10:06.407Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2279,7 +2279,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:12.000Z", + "@timestamp": "2018-10-18T14:10:12.046Z", "destination.address": "127.0.0.1", "event.dataset": "ibmmq.errorlog", "event.kind": "event", @@ -2314,7 +2314,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:12.000Z", + "@timestamp": "2018-10-18T14:10:12.046Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2348,7 +2348,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:28.000Z", + "@timestamp": "2018-10-18T14:10:28.071Z", "destination.address": "127.0.0.1", "event.dataset": "ibmmq.errorlog", "event.kind": "event", @@ -2383,7 +2383,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:10:28.000Z", + "@timestamp": "2018-10-18T14:10:28.071Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2417,7 +2417,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:20.000Z", + "@timestamp": "2018-10-18T14:13:20.545Z", "destination.address": "127.0.0.1", "event.dataset": "ibmmq.errorlog", "event.kind": "event", @@ -2452,7 +2452,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:20.000Z", + "@timestamp": "2018-10-18T14:13:20.546Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2486,7 +2486,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.803Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2520,7 +2520,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.821Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2554,7 +2554,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.821Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2588,7 +2588,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.822Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2622,7 +2622,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2656,7 +2656,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2690,7 +2690,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2724,7 +2724,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2758,7 +2758,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2792,7 +2792,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2826,7 +2826,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2860,7 +2860,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2894,7 +2894,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.824Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2928,7 +2928,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.823Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2962,7 +2962,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -2996,7 +2996,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3030,7 +3030,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3064,7 +3064,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3098,7 +3098,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3132,7 +3132,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3166,7 +3166,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3200,7 +3200,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3234,7 +3234,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.825Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3268,7 +3268,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.827Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3301,7 +3301,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.828Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3334,7 +3334,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.829Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", @@ -3367,7 +3367,7 @@ "user.name": "MUSR_MQADMIN" }, { - "@timestamp": "2018-10-18T16:13:46.000Z", + "@timestamp": "2018-10-18T14:13:46.830Z", "event.dataset": "ibmmq.errorlog", "event.kind": "event", "event.module": "ibmmq", From 2f79c7769915cd3fd1f1379511bd32555c358c96 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 11 Jan 2022 09:39:54 +0000 Subject: [PATCH 161/172] Add k8s metadata in state_cronjob metricset (#29572) --- CHANGELOG.next.asciidoc | 1 + .../elastic-agent-managed-kubernetes.yaml | 2 + .../elastic-agent-managed-role.yaml | 2 + .../elastic-agent-standalone-kubernetes.yaml | 2 + .../elastic-agent-standalone-role.yaml | 2 + deploy/kubernetes/metricbeat-kubernetes.yaml | 2 + .../metricbeat/metricbeat-role.yaml | 2 + libbeat/common/kubernetes/informer.go | 12 ++++ libbeat/common/kubernetes/metadata/pod.go | 1 + .../common/kubernetes/metadata/resource.go | 3 +- libbeat/common/kubernetes/types.go | 3 + .../state_cronjob/_meta/docs.asciidoc | 5 ++ .../kubernetes/state_cronjob/state_cronjob.go | 66 +++++++++++------ .../state_cronjob_integration_test.go | 2 +- .../module/kubernetes/test/integration.go | 12 ++++ .../module/kubernetes/util/kubernetes.go | 70 +++++++++++-------- 16 files changed, 133 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9dff67877304..432285920ae3 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -166,6 +166,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] - Add `container.id` and `container.runtime` ECS fields in container metricset. {pull}29560[29560] - Add `memory.workingset.limit.pct` field in Kubernetes container/pod metricset. {pull}29547[29547] +- Add k8s metadata in state_cronjob metricset. {pull}29572[29572] - Add `elasticsearch.cluster.id` field to Beat and Kibana modules. {pull}29577[29577] - Add `elasticsearch.cluster.id` field to Logstash module. {pull}29625[29625] diff --git a/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml b/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml index 12cc5badc696..9389489eed5a 100644 --- a/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml +++ b/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml @@ -165,6 +165,8 @@ rules: - apiGroups: [ "batch" ] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: [ "get", "list", "watch" ] # required for apiserver - nonResourceURLs: diff --git a/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-role.yaml b/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-role.yaml index 37d159333cde..49d4bd129994 100644 --- a/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-role.yaml +++ b/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-role.yaml @@ -38,6 +38,8 @@ rules: - apiGroups: [ "batch" ] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: [ "get", "list", "watch" ] # required for apiserver - nonResourceURLs: diff --git a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml index 9f58ec9c4f33..a46d8e3f4f63 100644 --- a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml +++ b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml @@ -671,6 +671,8 @@ rules: - apiGroups: ["batch"] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: ["get", "list", "watch"] - apiGroups: - "" diff --git a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-role.yaml b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-role.yaml index 16ee4759acc9..f0f6c2ca9134 100644 --- a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-role.yaml +++ b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-role.yaml @@ -32,6 +32,8 @@ rules: - apiGroups: ["batch"] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: ["get", "list", "watch"] - apiGroups: - "" diff --git a/deploy/kubernetes/metricbeat-kubernetes.yaml b/deploy/kubernetes/metricbeat-kubernetes.yaml index ae81804a606f..166c195d2f6c 100644 --- a/deploy/kubernetes/metricbeat-kubernetes.yaml +++ b/deploy/kubernetes/metricbeat-kubernetes.yaml @@ -295,6 +295,8 @@ rules: - apiGroups: ["batch"] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: ["get", "list", "watch"] - apiGroups: - "" diff --git a/deploy/kubernetes/metricbeat/metricbeat-role.yaml b/deploy/kubernetes/metricbeat/metricbeat-role.yaml index 065c32c789cf..26ed85ba619e 100644 --- a/deploy/kubernetes/metricbeat/metricbeat-role.yaml +++ b/deploy/kubernetes/metricbeat/metricbeat-role.yaml @@ -31,6 +31,8 @@ rules: - apiGroups: ["batch"] resources: - jobs + # Uncomment if need metadata for cronjob objects in versions >= v1.21 + #- cronjobs verbs: ["get", "list", "watch"] - apiGroups: - "" diff --git a/libbeat/common/kubernetes/informer.go b/libbeat/common/kubernetes/informer.go index cd7fb513cf6f..48d98e3e0039 100644 --- a/libbeat/common/kubernetes/informer.go +++ b/libbeat/common/kubernetes/informer.go @@ -149,6 +149,18 @@ func NewInformer(client kubernetes.Interface, resource Resource, opts WatchOptio } objType = "service" + case *CronJob: + cronjob := client.BatchV1().CronJobs(opts.Namespace) + listwatch = &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + return cronjob.List(ctx, options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + return cronjob.Watch(ctx, options) + }, + } + + objType = "cronjob" case *Job: job := client.BatchV1().Jobs(opts.Namespace) listwatch = &cache.ListWatch{ diff --git a/libbeat/common/kubernetes/metadata/pod.go b/libbeat/common/kubernetes/metadata/pod.go index 174b3667419e..6debd974260d 100644 --- a/libbeat/common/kubernetes/metadata/pod.go +++ b/libbeat/common/kubernetes/metadata/pod.go @@ -88,6 +88,7 @@ func (p *pod) GenerateK8s(obj kubernetes.Resource, opts ...FieldOptions) common. out := p.resource.GenerateK8s("pod", obj, opts...) // check if Pod is handled by a ReplicaSet which is controlled by a Deployment + // TODO: same happens with CronJob vs Job. The hierarcy there is CronJob->Job->Pod if p.addResourceMetadata.Deployment { rsName, _ := out.GetValue("replicaset.name") if rsName, ok := rsName.(string); ok { diff --git a/libbeat/common/kubernetes/metadata/resource.go b/libbeat/common/kubernetes/metadata/resource.go index 95f6ff8f909c..7bff84e9e407 100644 --- a/libbeat/common/kubernetes/metadata/resource.go +++ b/libbeat/common/kubernetes/metadata/resource.go @@ -119,7 +119,8 @@ func (r *Resource) GenerateK8s(kind string, obj kubernetes.Resource, options ... "ReplicaSet", "StatefulSet", "DaemonSet", - "Job": + "Job", + "CronJob": safemapstr.Put(meta, strings.ToLower(ref.Kind)+".name", ref.Name) } } diff --git a/libbeat/common/kubernetes/types.go b/libbeat/common/kubernetes/types.go index c3d1fefb01ed..a1800671abf1 100644 --- a/libbeat/common/kubernetes/types.go +++ b/libbeat/common/kubernetes/types.go @@ -76,6 +76,9 @@ type Service = v1.Service // Job data type Job = batchv1.Job +// CronJob data +type CronJob = batchv1.CronJob + const ( // PodPending phase PodPending = v1.PodPending diff --git a/metricbeat/module/kubernetes/state_cronjob/_meta/docs.asciidoc b/metricbeat/module/kubernetes/state_cronjob/_meta/docs.asciidoc index 1558a5f00e55..d994fe5dced0 100644 --- a/metricbeat/module/kubernetes/state_cronjob/_meta/docs.asciidoc +++ b/metricbeat/module/kubernetes/state_cronjob/_meta/docs.asciidoc @@ -1 +1,6 @@ This is the `state_cronjob` metricset of the Kubernetes module. + +This metricset does not add metadata by default and hence in order to +add metadata for this one need to configure the metricset with `add_metadata: true` +and uncomment the proper `apiGroup` in the `ClusterRole`. Metadata are only available +for versions of k8s >= v1.21. diff --git a/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go b/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go index 272dc58aca6a..013f2afe9651 100644 --- a/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go +++ b/metricbeat/module/kubernetes/state_cronjob/state_cronjob.go @@ -20,9 +20,9 @@ package state_cronjob import ( "fmt" - "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/common/kubernetes" + "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" - "github.com/elastic/beats/v7/libbeat/common" p "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" k8smod "github.com/elastic/beats/v7/metricbeat/module/kubernetes" @@ -44,6 +44,7 @@ type CronJobMetricSet struct { prometheus p.Prometheus mapping *p.MetricsMapping mod k8smod.Module + enricher util.Enricher } // NewCronJobMetricSet returns a prometheus based metricset for CronJobs @@ -58,7 +59,12 @@ func NewCronJobMetricSet(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, fmt.Errorf("must be child of kubernetes module") } - return &CronJobMetricSet{ + config := util.GetDefaultDisabledMetaConfig() + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, fmt.Errorf("error loading config of kubernetes module") + } + + ms := CronJobMetricSet{ BaseMetricSet: base, prometheus: prometheus, mod: mod, @@ -79,42 +85,58 @@ func NewCronJobMetricSet(base mb.BaseMetricSet) (mb.MetricSet, error) { "concurrency_policy": p.KeyLabel("concurrency"), }, }, - }, nil + } + if config.AddMetadata { + ms.enricher = util.NewResourceMetadataEnricher( + base, &kubernetes.CronJob{}, false) + } + return &ms, nil } // Fetch prometheus metrics and treats those prefixed by mb.ModuleDataKey as // module rooted fields at the event that gets reported // // Copied from other kube state metrics. -func (m *CronJobMetricSet) Fetch(reporter mb.ReporterV2) error { +func (m *CronJobMetricSet) Fetch(reporter mb.ReporterV2) { + if m.enricher != nil { + m.enricher.Start() + } + families, err := m.mod.GetStateMetricsFamilies(m.prometheus) if err != nil { - return errors.Wrap(err, "error getting family metrics") + m.Logger().Error(err) + reporter.Error(err) + return } events, err := m.prometheus.ProcessMetrics(families, m.mapping) if err != nil { - return errors.Wrap(err, "error getting metrics") + m.Logger().Error(err) + reporter.Error(err) + return } + if m.enricher != nil { + m.enricher.Enrich(events) + } for _, event := range events { - var moduleFieldsMapStr common.MapStr - moduleFields, ok := event[mb.ModuleDataKey] - if ok { - moduleFieldsMapStr, ok = moduleFields.(common.MapStr) - if !ok { - m.Logger().Errorf("error trying to convert '%s' from event to common.MapStr", mb.ModuleDataKey) - } + e, err := util.CreateEvent(event, "kubernetes.cronjob") + if err != nil { + m.Logger().Error(err) } - delete(event, mb.ModuleDataKey) - - if reported := reporter.Event(mb.Event{ - MetricSetFields: event, - ModuleFields: moduleFieldsMapStr, - Namespace: "kubernetes.cronjob", - }); !reported { - return nil + + if reported := reporter.Event(e); !reported { + m.Logger().Debug("error trying to emit event") + return } } + return +} + +// Close stops this metricset +func (m *CronJobMetricSet) Close() error { + if m.enricher != nil { + m.enricher.Stop() + } return nil } diff --git a/metricbeat/module/kubernetes/state_cronjob/state_cronjob_integration_test.go b/metricbeat/module/kubernetes/state_cronjob/state_cronjob_integration_test.go index 68e567b8bea4..aa3b003f06a5 100644 --- a/metricbeat/module/kubernetes/state_cronjob/state_cronjob_integration_test.go +++ b/metricbeat/module/kubernetes/state_cronjob/state_cronjob_integration_test.go @@ -30,7 +30,7 @@ import ( ) func TestFetchMetricset(t *testing.T) { - config := test.GetKubeStateMetricsConfig(t, "state_cronjob") + config := test.GetKubeStateMetricsConfigWithMetaDisabled(t, "state_cronjob") metricSet := mbtest.NewFetcher(t, config) events, errs := metricSet.FetchEvents() if len(errs) > 0 { diff --git a/metricbeat/module/kubernetes/test/integration.go b/metricbeat/module/kubernetes/test/integration.go index f2675b339bf9..ba7a7c0256bb 100644 --- a/metricbeat/module/kubernetes/test/integration.go +++ b/metricbeat/module/kubernetes/test/integration.go @@ -49,6 +49,18 @@ func GetKubeStateMetricsConfig(t *testing.T, metricSetName string) map[string]in } } +// GetKubeStateMetricsConfigWithMetaDisabled function returns configuration for talking to kube-state-metrics. +func GetKubeStateMetricsConfigWithMetaDisabled(t *testing.T, metricSetName string) map[string]interface{} { + t.Helper() + return map[string]interface{}{ + "module": "kubernetes", + "metricsets": []string{metricSetName}, + "host": "${NODE_NAME}", + "hosts": []string{"kube-state-metrics:8080"}, + "add_metadata": false, + } +} + // GetKubeletConfig function returns configuration for talking to Kubelet API. func GetKubeletConfig(t *testing.T, metricSetName string) map[string]interface{} { t.Helper() diff --git a/metricbeat/module/kubernetes/util/kubernetes.go b/metricbeat/module/kubernetes/util/kubernetes.go index 56e9684eee3a..6518a258e261 100644 --- a/metricbeat/module/kubernetes/util/kubernetes.go +++ b/metricbeat/module/kubernetes/util/kubernetes.go @@ -61,14 +61,14 @@ type kubernetesConfig struct { type enricher struct { sync.RWMutex - metadata map[string]common.MapStr - index func(common.MapStr) string - watcher kubernetes.Watcher - watcherStarted bool - watcherStartedLock sync.Mutex - namespaceWatcher kubernetes.Watcher - nodeWatcher kubernetes.Watcher - isPod bool + metadata map[string]common.MapStr + index func(common.MapStr) string + watcher kubernetes.Watcher + watchersStarted bool + watchersStartedLock sync.Mutex + namespaceWatcher kubernetes.Watcher + nodeWatcher kubernetes.Watcher + isPod bool } const selector = "kubernetes" @@ -134,6 +134,8 @@ func NewResourceMetadataEnricher( m[id] = metaGen.Generate("deployment", r) case *kubernetes.Job: m[id] = metaGen.Generate("job", r) + case *kubernetes.CronJob: + m[id] = metaGen.Generate("cronjob", r) case *kubernetes.Service: m[id] = serviceMetaGen.Generate(r) case *kubernetes.StatefulSet: @@ -304,6 +306,12 @@ func getResourceMetadataWatchers(config *kubernetesConfig, resource kubernetes.R return watcher, nodeWatcher, namespaceWatcher } +func GetDefaultDisabledMetaConfig() *kubernetesConfig { + return &kubernetesConfig{ + AddMetadata: false, + } +} + func validatedConfig(base mb.BaseMetricSet) *kubernetesConfig { config := kubernetesConfig{ AddMetadata: true, @@ -373,42 +381,44 @@ func buildMetadataEnricher( } func (m *enricher) Start() { - m.watcherStartedLock.Lock() - defer m.watcherStartedLock.Unlock() - if m.nodeWatcher != nil { - if err := m.nodeWatcher.Start(); err != nil { - logp.Warn("Error starting node watcher: %s", err) + m.watchersStartedLock.Lock() + defer m.watchersStartedLock.Unlock() + if !m.watchersStarted { + if m.nodeWatcher != nil { + if err := m.nodeWatcher.Start(); err != nil { + logp.Warn("Error starting node watcher: %s", err) + } } - } - if m.namespaceWatcher != nil { - if err := m.namespaceWatcher.Start(); err != nil { - logp.Warn("Error starting namespace watcher: %s", err) + if m.namespaceWatcher != nil { + if err := m.namespaceWatcher.Start(); err != nil { + logp.Warn("Error starting namespace watcher: %s", err) + } } - } - if !m.watcherStarted { err := m.watcher.Start() if err != nil { logp.Warn("Error starting Kubernetes watcher: %s", err) } - m.watcherStarted = true + m.watchersStarted = true } } func (m *enricher) Stop() { - m.watcherStartedLock.Lock() - defer m.watcherStartedLock.Unlock() - if m.watcherStarted { + m.watchersStartedLock.Lock() + defer m.watchersStartedLock.Unlock() + if m.watchersStarted { m.watcher.Stop() - m.watcherStarted = false - } - if m.namespaceWatcher != nil { - m.namespaceWatcher.Stop() - } - if m.nodeWatcher != nil { - m.nodeWatcher.Stop() + if m.namespaceWatcher != nil { + m.namespaceWatcher.Stop() + } + + if m.nodeWatcher != nil { + m.nodeWatcher.Stop() + } + + m.watchersStarted = false } } From eef391b64814efc379405653a751b76d4b3a7ea5 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 11 Jan 2022 10:15:20 +0000 Subject: [PATCH 162/172] jjbb: remove obsoleted branches (<7.16) (#29707) --- .ci/jobs/apm-beats-update.yml | 7 ++----- .ci/jobs/beats-tester.yml | 4 ++-- .ci/jobs/beats.yml | 5 +---- .ci/jobs/packaging.yml | 7 ++----- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.ci/jobs/apm-beats-update.yml b/.ci/jobs/apm-beats-update.yml index 678a9fbcd676..a1fe03b0df2c 100644 --- a/.ci/jobs/apm-beats-update.yml +++ b/.ci/jobs/apm-beats-update.yml @@ -18,7 +18,7 @@ discover-pr-forks-trust: 'permission' discover-pr-origin: 'merge-current' discover-tags: true - head-filter-regex: '(master|7\.[x789]|7\.1\d|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' + head-filter-regex: '(master|7\.1[6789]|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' disable-pr-notifications: true notification-context: 'apm-beats-update' repo: 'beats' @@ -36,10 +36,7 @@ name: 'master' case-sensitive: true - regex-name: - regex: '7\.[x789]' - case-sensitive: true - - regex-name: - regex: '7\.1\d' + regex: '7\.1[6789]' case-sensitive: true - regex-name: regex: '8\.\d+' diff --git a/.ci/jobs/beats-tester.yml b/.ci/jobs/beats-tester.yml index 14cc1007c56d..dc268c0eefa5 100644 --- a/.ci/jobs/beats-tester.yml +++ b/.ci/jobs/beats-tester.yml @@ -14,7 +14,7 @@ discover-pr-forks-trust: 'permission' discover-pr-origin: 'merge-current' discover-tags: true - head-filter-regex: '(master|7\.([x9]|1\d+)|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' + head-filter-regex: '(master|7\.1[6789]|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' disable-pr-notifications: true notification-context: 'beats-tester' repo: 'beats' @@ -32,7 +32,7 @@ name: 'master' case-sensitive: true - regex-name: - regex: '7\.([x9]|1\d+)' + regex: '7\.1[6789]' case-sensitive: true - regex-name: regex: '8\.\d+' diff --git a/.ci/jobs/beats.yml b/.ci/jobs/beats.yml index 0500b2ba8f28..638051d8a2e6 100644 --- a/.ci/jobs/beats.yml +++ b/.ci/jobs/beats.yml @@ -39,10 +39,7 @@ regex: '6\.[89]' case-sensitive: true - regex-name: - regex: '7\.[x789]' - case-sensitive: true - - regex-name: - regex: '7\.1\d' + regex: '7\.1[6789]' case-sensitive: true - regex-name: regex: '8\.\d+' diff --git a/.ci/jobs/packaging.yml b/.ci/jobs/packaging.yml index baa3ce45035f..97f9462d8f6b 100644 --- a/.ci/jobs/packaging.yml +++ b/.ci/jobs/packaging.yml @@ -14,7 +14,7 @@ discover-pr-forks-trust: 'permission' discover-pr-origin: 'merge-current' discover-tags: true - head-filter-regex: '(master|7\.[x789]|7\.1\d|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' + head-filter-regex: '(master|7\.1[6789]|8\.\d+|PR-.*|v\d+\.\d+\.\d+)' disable-pr-notifications: true notification-context: 'beats-packaging' repo: 'beats' @@ -32,10 +32,7 @@ name: 'master' case-sensitive: true - regex-name: - regex: '7\.[x789]' - case-sensitive: true - - regex-name: - regex: '7\.1\d' + regex: '7\.1[6789]' case-sensitive: true - regex-name: regex: '8\.\d+' From 896b7e481c0e8046d20b02f253a4f7bcf9c73494 Mon Sep 17 00:00:00 2001 From: Tetiana Kravchenko Date: Tue, 11 Jan 2022 15:08:04 +0100 Subject: [PATCH 163/172] Remove overriding of index pattern on the Kubernetes overview dashboard (#29676) * Remove overriding of index pattern on the Kubernetes overview dashboard; align visualisations with changes in https://github.com/elastic/integrations/pull/2151 Signed-off-by: Tetiana Kravchenko * add PR number in changelog Signed-off-by: Tetiana Kravchenko --- CHANGELOG.next.asciidoc | 1 + .../174a6ad0-30e0-11e7-8df8-6d3604a72912-ecs.json | 3 +-- .../da1ff7c0-30ed-11e7-b9e5-2b5b07213ab3-ecs.json | 5 +---- .../e1018b90-2bfb-11e7-859b-f78b612cde28-ecs.json | 4 +--- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 432285920ae3..914d76a8989a 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -57,6 +57,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove deprecated config option perfmon.counters from windows/perfmon metricset. {pull}28282[28282] - Remove deprecated fields in Redis module. {issue}11835[11835] {pull}28246[28246] - system/process metricset: Replace usage of deprecated `process.ppid` field with `process.parent.pid`. {pull}28620[28620] +- Remove overriding of index pattern on the Kubernetes overview dashboard. {pull}29676[29676] *Packetbeat* diff --git a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/174a6ad0-30e0-11e7-8df8-6d3604a72912-ecs.json b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/174a6ad0-30e0-11e7-8df8-6d3604a72912-ecs.json index 12a7a5a03b62..530eda35e084 100644 --- a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/174a6ad0-30e0-11e7-8df8-6d3604a72912-ecs.json +++ b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/174a6ad0-30e0-11e7-8df8-6d3604a72912-ecs.json @@ -57,7 +57,6 @@ "type": "sum" } ], - "override_index_pattern": 1, "point_size": 1, "seperate_axis": 0, "series_interval": "10s", @@ -84,4 +83,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:31:37.319Z", "version": "WzQwMjMsMV0=" -} \ No newline at end of file +} diff --git a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/da1ff7c0-30ed-11e7-b9e5-2b5b07213ab3-ecs.json b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/da1ff7c0-30ed-11e7-b9e5-2b5b07213ab3-ecs.json index a72257a06867..5d3875f54da1 100644 --- a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/da1ff7c0-30ed-11e7-b9e5-2b5b07213ab3-ecs.json +++ b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/da1ff7c0-30ed-11e7-b9e5-2b5b07213ab3-ecs.json @@ -57,12 +57,9 @@ "type": "sum" } ], - "override_index_pattern": 1, "point_size": 1, "seperate_axis": 0, - "series_index_pattern": "*", "series_interval": "10s", - "series_time_field": "@timestamp", "split_color_mode": "gradient", "split_mode": "everything", "stacked": "none" @@ -86,4 +83,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:31:37.319Z", "version": "WzQwMjUsMV0=" -} \ No newline at end of file +} diff --git a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/e1018b90-2bfb-11e7-859b-f78b612cde28-ecs.json b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/e1018b90-2bfb-11e7-859b-f78b612cde28-ecs.json index 3c3492288fb1..c352ee06e799 100644 --- a/metricbeat/module/kubernetes/_meta/kibana/7/visualization/e1018b90-2bfb-11e7-859b-f78b612cde28-ecs.json +++ b/metricbeat/module/kubernetes/_meta/kibana/7/visualization/e1018b90-2bfb-11e7-859b-f78b612cde28-ecs.json @@ -57,11 +57,9 @@ "type": "sum" } ], - "override_index_pattern": 1, "point_size": 1, "seperate_axis": 0, "series_interval": "10s", - "series_time_field": "@timestamp", "split_color_mode": "gradient", "split_mode": "everything", "stacked": "none" @@ -85,4 +83,4 @@ "type": "visualization", "updated_at": "2021-08-04T16:31:37.319Z", "version": "WzQwMTYsMV0=" -} \ No newline at end of file +} From cf3abb44688d421b7c61c0946f68cfe6263e0209 Mon Sep 17 00:00:00 2001 From: Michael Katsoulis Date: Tue, 11 Jan 2022 16:20:08 +0200 Subject: [PATCH 164/172] Add a readme for k8s autodiscover provider (#28213) * Add a readme for k8s autodiscover provider --- libbeat/autodiscover/README.md | 191 ++++++++++++++++++ .../composable/providers/kubernetes/README.md | 70 +++++++ 2 files changed, 261 insertions(+) create mode 100644 libbeat/autodiscover/README.md create mode 100644 x-pack/elastic-agent/pkg/composable/providers/kubernetes/README.md diff --git a/libbeat/autodiscover/README.md b/libbeat/autodiscover/README.md new file mode 100644 index 000000000000..912d254b6f5a --- /dev/null +++ b/libbeat/autodiscover/README.md @@ -0,0 +1,191 @@ +# Kubernetes autodiscover provider in Beats and Agent + +https://www.elastic.co/guide/en/beats/metricbeat/master/configuration-autodiscover.html +https://www.elastic.co/guide/en/beats/filebeat/current/configuration-autodiscover.html +https://www.elastic.co/guide/en/fleet/7.x/dynamic-input-configuration.html#providers + +When you run applications on containers, they become moving targets to the monitoring system. Autodiscover allows you to track them and adapt settings as changes happen. By defining configuration templates, the autodiscover subsystem can monitor services as they start running. + +You define autodiscover settings in the autodiscover section of the metricbeat.yml/filebeat.yml config file. To enable autodiscover, you specify a list of providers. +For Elastic Agent we will discuss later. + +**Providers** +Autodiscover providers work by watching for events on the system and translating those events into internal autodiscover events with a common format. When you configure the provider, you can optionally use fields from the autodiscover event to set conditions that, when met, launch specific configurations. + +On start Metricbeat/Filebeat/Agent will scan existing containers and launch the proper configs for them. Then it will watch for new start/stop events. This ensures you don’t need to worry about state, but only define your desired configs. + +The Kubernetes autodiscover provider watches for Kubernetes nodes, pods, services and namespaces when they start, update, and stop. + +We will describe the internals of three ways of Kubernetes autodiscover process. +1. Templates Based Autodiscover +2. Hints Based Autodiscover +3. Autodiscover provider in Elastic Agent + +## Templates Based Autodiscover + +As the name suggests, user needs to set a template to indicate to autodiscover provider what to do. +There is one configuration variable that differentiates in a way how the autosicover process is performed. +This variable is `unique` + +### Autodiscover with LeaderElection +When setting `unique: true` the Leader Election mechanism is activated. That way **only** the Beat instance that will gain the leader lease/lock will enable the provided template. +The best appliance of this feature is when collecting cluster wide metrics from `kube-state-metrics` or `apiserver`. +In that case having all instances of metricbeat collecting the same metrics is not desirable. + +Example: +``` +metricbeat.autodiscover: + providers: + - type: kubernetes + scope: cluster + node: ${NODE_NAME} + unique: true + identifier: leader-election-metricbeat + templates: + - config: + - module: kubernetes + hosts: ["kube-state-metrics:8080"] + period: 10s + add_metadata: true + metricsets: + - state_node +``` + +##### How it works + +We will deep dive in the internals of [libbeat kubernetes autodiscover provider](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes). + +We will use metricbeat as an example. + +Step-by-step walkthrough +1. Kubernetes provider `init` function [adds](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L46) the provider in the autodiscover providers registry at startup. For Kubernetes provider an `AutodiscoverBuilder` func is passed as an argument. +2. Metricbeat calls `NewAutodiscover` [function](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/metricbeat/beater/metricbeat.go#L183) which checks in the config for enabled providers and [builds](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/provider.go#L90) them one by one, calling the `AutodiscoverBuilder` func. +3. Kubernetes `AutodiscoverBuilder` creates and returns a [Kubernetes Provider struct](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L131) which is then added to an Autodiscover manager struct. +4. When unique is set to true [NewLeaderElectionManager](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L141) is set as the eventManager of Kubernetes Provider. +5. Metricbeat [starts](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/metricbeat/beater/metricbeat.go#L249) the Autodiscover manager which starts for Kubernets provider the [leaderElectionManager](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L326). Before starting the providers it also starts a worker for listening of events that will be published by the eventers of each provider. +6. `OnStartedLeading` is executed when the specific metricbeat instance gains the leader election lock. [StartLeading](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L205) creates a bus event with `"start": true,` and publishes it. The template configurations is also added in this event. +7. [Listener](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/autodiscover.go#L140) of events get the published event and generates [configs](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/autodiscover.go#L185) for it. Configs include the variables and settings from the template set by the user. +8. For each config the worker checks if it already [exists](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/autodiscover.go#L221) (It was already handled). If at least one of the events config does not exist, then the config is marked as `updated`. +9. The runners list get [reloaded](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/cfgfile/list.go#L54). It is checked from the list of current runners if each config is handled by one of them. + If no runner is handling that config a new runner will [start](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/cfgfile/list.go#L107). If some runners are no longer needed will be removed. +10. Starting of a runner starts under the hood the metricbeat [module](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/metricbeat/mb/module/runner.go#L76) with the specific metricsets as they are set in the template. Same also applies for filebeat and heartbeat cases. + +### Autodiscover without LeaderElection + +When setting `unique: false` or not setting it at all the Leader Election mechanism is disabled. That way all Beat instances will enable the provided template. Or at least the ones that match a condition. +A good appliance of this is when user wants to enable a specific module(for example redis) each time a pod with a specific label appears in each kubernetes node. + +Example: +``` +metricbeat.autodiscover: + providers: + - type: kubernetes + templates: + - condition: + contains: + kubernetes.labels.app: "redis" + config: + - module: redis + metricsets: ["info", "keyspace"] + hosts: "${data.host}:6379" + password: "${REDIS_PASSWORD}" +``` + +##### How it works + +We will use metricbeat and redis module as example. +Step-by-step walkthrough + +Steps 1-3 are exactly the same as with Leader Election. +4. In the [Kubernetes Provider struct](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L131) created by the Kubernetes AutodiscoverBuilder in case there is a [condition](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L116) a `NewConfigMapper` is created. It contains the condition [map](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/template/config.go#L64) with all the conditions of a given config. +4. When unique is set to false, the resource is [checked](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L239) from the configuration template(default is pod) and a new PodEventer/NodeEventer/ServiceEventer is set as the eventManager of Kubernetes Provider. +5. The kubernetes node that the metricbeat instance is running on is [discovered](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L72). +6. A dedicated watcher to watch [pods](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L82), nodes and namespaces get started. Also a [metadata generator](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L113) is started to enrich the events with kubernetes metadata. +7. Each time a new event is about to be published by the watchers(we will have a dedicated section of how events are published), it is checked whether the condition set by the user [matches](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L182) the event. +8. If it matches, then a config is created with the configuration set by user and it is added in the event. After that the event gets published. +9. The worker listening for events receives the start event and checks if there is any update in the configs of the event. (same process with leader election steps 6-9) +10. If there is an update it starts or stops the runners needed. In our example it starts a new runner that starts the redis module. + +##### How pod eventer works + +The [watcher](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/common/kubernetes/watcher.go#L124) struct has a kubernetes informer field which depending on the resource type [watches](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/common/kubernetes/informer.go#L52) and lists the changes in the kubernetes cluster for that specific resource. +When a new pod for example is discovered it is added in the work [queue](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/common/kubernetes/watcher.go#L137) for processing. +The watcher processes that [queue](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/common/kubernetes/watcher.go#L218) and depending if there was an addition,deletion or update of a resource it calls the +related [method](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/common/kubernetes/watcher.go#L250). +* [OnAdd](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L137) is called when there is a pod addition and it executes [emit](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L314) with `start` flag. Emit adds the pod to a new event together will all metadata, sets `start: true` and [publishes](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L343) it. Step 7 follows. +* [OnDelete](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L160) is called when there is a pod deletion and it ecexutes emit with `stop` flag. Emit adds the pod to a new event with ``stop: true`` and publishes it. Step 7 follows. +* [OnUpdate](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/pod.go#L146) is called when there is update in the an existing resource and it ecexutes at first emit with `stop` flag to generate a stop event and then with `start` flag to generate a start event. + + +## Hints Based Autodiscover + +https://www.elastic.co/guide/en/beats/metricbeat/master/configuration-autodiscover-hints.html + +Metricbeat, Filebeat and Heartbeat support autodiscover based on hints from the provider. The hints system looks for hints in Kubernetes Pod annotations which have the prefix co.elastic.metrics. As soon as the container starts, Metricbeat/Filebeat will check if it contains any hints and launch the proper config for it. Hints tell Metricbeat/Filebeat how to get metrics for the given container. + +Example metricbeat configuration: +``` +metricbeat.autodiscover: + providers: + - type: kubernetes + node: ${NODE_NAME} + hints.enabled: true +``` + +Example redis pod with right annotations: +``` +apiVersion: v1 +kind: Pod +metadata: + name: redis + annotations: + co.elastic.metrics/module: redis + co.elastic.metrics/metricsets: info + co.elastic.metrics/hosts: '${data.host}:6379' +spec: + containers: + - name: redis + image: redis:5.0.4 + command: + - redis-server + - "/redis-master/redis.conf" + env: + - name: MASTER + value: "true" + ports: + - containerPort: 6379 + resources: + limits: + cpu: "0.1" + volumeMounts: + - mountPath: /redis-master-data + name: data + - mountPath: /redis-master + name: config + volumes: + - name: data + emptyDir: {} + - name: config + configMap: + name: example-redis-config + items: + - key: redis-config + path: redis.conf +``` + +##### How hints work + +Everything works the same as Autodiscover without LeaderElection until step 8. + +8. If there is no conditions in the template set by the user, the configs will be generated from [hints](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L186). +9. Wether hints are enabled or not is part of the [Kubernetes Provider struct](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L121) builders field. +10. [GenerateHints](https://github.com/elastic/beats/blob/eff92354db783001880f4bade9f59942fca747ba/libbeat/autodiscover/builder/helper.go#L213) function looks into the event's annotations. A [hints map](https://github.com/elastic/beats/blob/eff92354db783001880f4bade9f59942fca747ba/libbeat/autodiscover/builder/helper.go#L226) is created with all hints and returned. +11. From those hints, configs are [created](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/builder.go#L97) in the same form as in `Autodiscover without LeaderElection` step 8. + They contain the same information as if they where set explicitly in the metricbeat configureation but actually derive from the pod annotations. +12. Those configs are then [added](https://github.com/elastic/beats/blob/4b1f69923b3f2abbbf1860295fe5dbff7db3d63c/libbeat/autodiscover/providers/kubernetes/kubernetes.go#L197) in the event and gets published. +13. The process after that is same as in `Autodiscover without LeaderElection` step 9 and onward. + + + +## Autodiscover provider in Elastic Agent +Follow the link [here](https://github.com/elastic/beats/blob/aa264bdf008a9bf309e61744e9ec8c5586593f12/x-pack/elastic-agent/pkg/composable/providers/kubernetes/README.md). diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/README.md b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/README.md new file mode 100644 index 000000000000..8fe7492c87a5 --- /dev/null +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/README.md @@ -0,0 +1,70 @@ +## Autodiscover provider in Elastic Agent + +https://www.elastic.co/guide/en/fleet/8.0/dynamic-input-configuration.html#dynamic-providers + +Currently Kubernetes dynamic provider can only be configured in [standalone](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml#L24) agent. +In fleet managed agent it is enabled by default with default values. + +Template based autodiscover of Kubernetes resources is only supported in standalone mode as of now. +It is not part of the Kubernetes Integration yet. + +Hints based autodiscover is not supported yet. + +### Template based autodiscover + +Example: +As an example we will use again redis module. +In agent.yml(configmap) an extra input block needs to be added. +``` +# Add extra input blocks here, based on conditions +# so as to automatically identify targeted Pods and start monitoring them +# using a predefined integration. For instance: +- name: redis + type: redis/metrics + use_output: default + meta: + package: + name: redis + version: 0.3.6 + data_stream: + namespace: default + streams: + - data_stream: + dataset: redis.info + type: metrics + metricsets: + - info + hosts: + - '${kubernetes.pod.ip}:6379' + idle_timeout: 20s + maxconn: 10 + network: tcp + period: 10s + condition: ${kubernetes.pod.labels.app} == 'redis' +``` + +What makes this input block dynamic are the variables hosts and condition. +`${kubernetes.pod.ip}` and `${kubernetes.pod.labels.app}` + +#### High level description +The Kubernetes dynamic provider watches for Kubernetes resources and generates mappings from them (similar to events in beats provider). The mappings include those variables([list of variables](https://www.elastic.co/guide/en/fleet/03bf16907bea9768427f8305a5c345368b55d834/dynamic-input-configuration.html#kubernetes-provider)) for each k8s resource with unique value for each one of them. +Agent composable controller which controls all the providers receives these mappings and tries to match them with the input blogs of the configurations. +This means that for every mapping that the condition matches (kubernetes.pod.labels.app equals to redis), a +new input will be created in which the condition will be removed(not needed anymore) and the `kubernetes.pod.ip` variable will be substituted from the value in the same mapping. +The updated complete inputs blog will be then forwarded to agent to spawn/update metricbeat and filebeat instances. + +##### Internals + +Step-by-step walkthrough +1. Elastic agent running in local mode initiates a new [composable controller](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/agent/application/local_mode.go#L112). +2. The controller consists of all contextProviders and [dynamicProviders](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/composable/controller.go#L73). +3. Agent initiates a new [emitter](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/agent/application/local_mode.go#L118) which [starts](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/emitter.go#L27) all the dynamicProviders of the [controller](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/composable/controller.go#L122). +4. Kubernetes Dynamic provider depending on the [resource type](https://github.com/elastic/beats/blob/03bf16907bea9768427f8305a5c345368b55d834/x-pack/elastic-agent/pkg/composable/providers/kubernetes/kubernetes.go#L56) (default is pod) initiates a [watcher](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go#L69) for + the specific resource the same way as in metrcbeat/filebeat kubernetes provider. +5. Under the hood a dedicated watcher starts for pods, nodes and namespaces as well as a metadata generator. +6. The difference is that the watchers instead of publishing events, they create [data](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go#L134) from the objects read from the queue. These [data](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go#L244) consist of mappings, processors and a priority . +7. A [mapping](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go#L217) includes all those variables retrieved from the kubernetes resource metadata while the [processors](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go#L236) indicate the addition of extra fields. +8. Composable controller [collects](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/controller.go#L244) the created data and [compares](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/controller.go#L263) their mappings and processors against the existing ones. If there is a change, it updates the dynamicProviderState and notifies a worker thread through a [signal](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/controller.go#L272). +9. When the worker gets [notified](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/controller.go#L141) for a change it creates new [variables](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/composable/controller.go#L170) from the mappings and processors. +10. It then updates the [emitter](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go#L111) with them. +11. The emitter controller will update the ast that is then used by the agent to generate the final inputs and spawn new programs to deploy the changes([code](https://github.com/elastic/beats/blob/3c77c9a92a2e90b85f525293cb4c2cfc5bc996b1/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go#L151)). From 7a0eb7c909b557acd1e704e392c9a591c1409e59 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Tue, 11 Jan 2022 15:53:33 +0100 Subject: [PATCH 165/172] Missing changelog entry for #29773 (#29791) Relates #29773 --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 914d76a8989a..0b170a7fbff2 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -100,6 +100,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix handling of IPv6 addresses in netflow flow events. {issue}19210[19210] {pull}29383[29383] - Fix `sophos` KV splitting and syslog header handling {issue}24237[24237] {pull}29331[29331] - Undo deletion of endpoint config from cloudtrail fileset in {pull}29415[29415]. {pull}29450[29450] +- ibmmq: Fixed `@timestamp` not being populated with correct values. {pull}29773[29773] *Heartbeat* From 72048b57e7438cad537b70edb70e22961758a83e Mon Sep 17 00:00:00 2001 From: apmmachine <58790750+apmmachine@users.noreply.github.com> Date: Tue, 11 Jan 2022 12:46:27 -0500 Subject: [PATCH 166/172] [Automation] Update elastic stack version to 8.1.0-7004acda for testing (#29783) Co-authored-by: apmmachine Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- testing/environments/snapshot-oss.yml | 6 +++--- testing/environments/snapshot.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/environments/snapshot-oss.yml b/testing/environments/snapshot-oss.yml index b3c6eaa2976c..8a398f7b4c8a 100644 --- a/testing/environments/snapshot-oss.yml +++ b/testing/environments/snapshot-oss.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-5e490954-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-7004acda-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -21,7 +21,7 @@ services: - "script.context.template.cache_max_size=2000" logstash: - image: docker.elastic.co/logstash/logstash-oss:8.1.0-5e490954-SNAPSHOT + image: docker.elastic.co/logstash/logstash-oss:8.1.0-7004acda-SNAPSHOT healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 @@ -31,7 +31,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-5e490954-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-7004acda-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 204cc33baced..c8552faf0c0b 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -3,7 +3,7 @@ version: '2.3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-5e490954-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-7004acda-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cat/health?h=status | grep -q green"] retries: 300 @@ -37,7 +37,7 @@ services: - ./docker/logstash/pki:/etc/pki:ro kibana: - image: docker.elastic.co/kibana/kibana:8.1.0-5e490954-SNAPSHOT + image: docker.elastic.co/kibana/kibana:8.1.0-7004acda-SNAPSHOT healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status?v8format=true | grep -q '\"overall\":{\"level\":\"available\"'"] retries: 600 From 9bd989b2ddfbcafc641ad0086a6c3d55df277592 Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Wed, 12 Jan 2022 06:43:28 +1030 Subject: [PATCH 167/172] libbeat/processors/add_process_metadata: implement a process cache eviction policy (#29717) The eviction policy implemented here guarantees a hard limit to the number of entries in the cache and provides a downward force on the number of entries over time with an exponential decay on the fraction of entries that are older than the cache expiration duration. --- CHANGELOG.next.asciidoc | 1 + .../add_process_metadata.go | 12 +- .../processors/add_process_metadata/cache.go | 42 ++++++- .../add_process_metadata/cache_test.go | 113 ++++++++++++++++++ 4 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 libbeat/processors/add_process_metadata/cache_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 0b170a7fbff2..305b5a664276 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -93,6 +93,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - system/socket: Fix bugs leading to wrong process being attributed to flows. {pull}29166[29166] {issue}17165[17165] - system/socket: Fix process name and arg truncation for long names, paths and args lists. {issue}24667[24667] {pull}29410[29410] - system/socket: Fix startup errors on newer 5.x kernels due to missing _do_fork function. {issue}29607[29607] {pull}29744[29744] +- libbeat/processors/add_process_metadata: Fix memory leak in process cache. {issue}24890[24890] {pull}29717[29717] *Filebeat* diff --git a/libbeat/processors/add_process_metadata/add_process_metadata.go b/libbeat/processors/add_process_metadata/add_process_metadata.go index e405aa6940b1..31b9fa9a9db3 100644 --- a/libbeat/processors/add_process_metadata/add_process_metadata.go +++ b/libbeat/processors/add_process_metadata/add_process_metadata.go @@ -36,9 +36,11 @@ import ( ) const ( - processorName = "add_process_metadata" - cacheExpiration = time.Second * 30 - containerIDMapping = "container.id" + processorName = "add_process_metadata" + cacheExpiration = time.Second * 30 + cacheCapacity = 32 << 10 // maximum number of process cache entries. + cacheEvictionEffort = 10 // number of entries to sample for expiry eviction. + containerIDMapping = "container.id" ) var ( @@ -49,7 +51,7 @@ var ( // ErrNoProcess is returned when metadata for a process can't be collected. ErrNoProcess = errors.New("process not found") - procCache = newProcessCache(cacheExpiration, gosysinfoProvider{}) + procCache = newProcessCache(cacheExpiration, cacheCapacity, cacheEvictionEffort, gosysinfoProvider{}) processCgroupPaths = cgroup.ProcessCgroupPaths @@ -112,7 +114,6 @@ func newProcessMetadataProcessorWithProvider(cfg *common.Config, provider proces } mappings, err := config.getMappings() - if err != nil { return nil, errors.Wrapf(err, "error unpacking %v.target_fields", processorName) } @@ -139,7 +140,6 @@ func newProcessMetadataProcessorWithProvider(cfg *common.Config, provider proces } else { p.cidProvider = newCidProvider(resolve.NewTestResolver(config.HostPath), config.CgroupPrefixes, config.CgroupRegex, processCgroupPaths, nil) } - } if withCache { diff --git a/libbeat/processors/add_process_metadata/cache.go b/libbeat/processors/add_process_metadata/cache.go index 0a8234fe0caf..e3435aa92af8 100644 --- a/libbeat/processors/add_process_metadata/cache.go +++ b/libbeat/processors/add_process_metadata/cache.go @@ -29,16 +29,22 @@ type processCacheEntry struct { } type processCache struct { - cache map[int]processCacheEntry provider processMetadataProvider expiration time.Duration - rwMutex sync.RWMutex + + cap int // cap is the maximum number of elements the cache will hold. + effort int // effort is the number of entries to examine during expired element eviction. + + rwMutex sync.RWMutex // rwMutex protects the cache map. + cache map[int]processCacheEntry } -func newProcessCache(expiration time.Duration, provider processMetadataProvider) processCache { +func newProcessCache(expiration time.Duration, cap, effort int, provider processMetadataProvider) processCache { return processCache{ cache: make(map[int]processCacheEntry), expiration: expiration, + cap: cap, + effort: effort, provider: provider, } } @@ -58,6 +64,12 @@ func (pc *processCache) GetProcessMetadata(pid int) (*processMetadata, error) { if !valid { pc.rwMutex.Lock() defer pc.rwMutex.Unlock() + + pc.tryEvictExpired() + if len(pc.cache) >= pc.cap { + pc.evictRandomEntry() + } + // Make sure someone else didn't generate this entry while we were // waiting for the write lock if entry, valid = pc.getEntryUnlocked(pid); !valid { @@ -68,3 +80,27 @@ func (pc *processCache) GetProcessMetadata(pid int) (*processMetadata, error) { } return entry.metadata, entry.err } + +// tryEvictExpired implements a random sampling expired element cache +// eviction policy. +func (pc *processCache) tryEvictExpired() { + now := time.Now() + n := 0 + for pid, entry := range pc.cache { + if n >= pc.effort { + return + } + if now.After(entry.expiration) { + delete(pc.cache, pid) + } + n++ + } +} + +// evictRandomEntry implements a random cache eviction policy. +func (pc *processCache) evictRandomEntry() { + for pid := range pc.cache { + delete(pc.cache, pid) + return + } +} diff --git a/libbeat/processors/add_process_metadata/cache_test.go b/libbeat/processors/add_process_metadata/cache_test.go new file mode 100644 index 000000000000..9d9886d9932d --- /dev/null +++ b/libbeat/processors/add_process_metadata/cache_test.go @@ -0,0 +1,113 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package add_process_metadata + +import ( + "math/rand" + "testing" + "time" +) + +var cacheEvictionTests = []struct { + name string + + expire time.Duration + cap, effort int + + iters int + maxPID int + delay time.Duration +}{ + { + name: "small sparse", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 1000, + maxPID: 100000, + delay: 2 * time.Millisecond, + }, + { + name: "small dense", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 1000, + maxPID: 10, + delay: 2 * time.Millisecond, + }, + { + name: "large sparse", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 10000, + maxPID: 100000, + delay: time.Millisecond / 10, + }, + { + name: "large dense", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 10000, + maxPID: 10, + delay: time.Millisecond / 10, + }, + { + name: "huge sparse", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 1000, + maxPID: 100000, + delay: time.Millisecond / 100, + }, + { + name: "huge dense", + expire: time.Millisecond, + cap: 100, + effort: 5, + iters: 1000, + maxPID: 10, + delay: time.Millisecond / 100, + }, +} + +func TestCacheEviction(t *testing.T) { + for _, test := range cacheEvictionTests { + rnd := rand.New(rand.NewSource(1)) + c := newProcessCache(test.expire, test.cap, test.effort, emptyProvider{}) + + for i := 0; i < test.iters; i++ { + pid := rnd.Intn(test.maxPID) + c.GetProcessMetadata(pid) + if len(c.cache) > test.cap { + t.Errorf("cache overflow for %s after %d iterations", test.name, i) + break + } + time.Sleep(test.delay) + } + } +} + +type emptyProvider struct{} + +func (emptyProvider) GetProcessMetadata(pid int) (*processMetadata, error) { + return &processMetadata{pid: pid}, nil +} From febc7ddbfa4b8c7f39fb8a05b8d90864f0199e93 Mon Sep 17 00:00:00 2001 From: Blake Rouse Date: Tue, 11 Jan 2022 15:33:46 -0500 Subject: [PATCH 168/172] Change docker image from CentOS 7 to Ubuntu 20.04 (#29681) * Switch to Ubuntu 20.04. * Fix Dockerfile. * Change to amd64 in Dockerfile.tmpl. * Add missing curl and ca-certificate deps. Change back to x86_64. * Fix issues with setcap and xz extraction. * Add changelog, fix remaining issues. * Fix synthetics deps * Fix apt-get. Remove todo from packages.yml. Co-authored-by: Andrew Cholakian --- .ci/packer_cache.sh | 2 +- CHANGELOG.next.asciidoc | 1 + auditbeat/Dockerfile | 2 +- dev-tools/packaging/packages.yml | 18 ++--- .../docker/Dockerfile.elastic-agent.tmpl | 68 ++++++++++++------- .../templates/docker/Dockerfile.tmpl | 67 ++++++++++++------ filebeat/Dockerfile | 2 +- heartbeat/Dockerfile | 2 +- libbeat/Dockerfile | 2 +- metricbeat/Dockerfile | 2 +- packetbeat/Dockerfile | 2 +- x-pack/functionbeat/Dockerfile | 2 +- x-pack/libbeat/Dockerfile | 2 +- 13 files changed, 108 insertions(+), 64 deletions(-) diff --git a/.ci/packer_cache.sh b/.ci/packer_cache.sh index 1627343c6120..9b4443769245 100755 --- a/.ci/packer_cache.sh +++ b/.ci/packer_cache.sh @@ -21,7 +21,7 @@ function dockerPullCommonImages() { docker.elastic.co/observability-ci/database-enterprise:12.2.0.1 docker.elastic.co/beats-dev/fpm:1.11.0 golang:1.14.12-stretch - centos:7 + ubuntu:20.04 " for image in ${DOCKER_IMAGES} ; do (retry 2 docker pull ${image}) || echo "Error pulling ${image} Docker image. Continuing." diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 305b5a664276..5f3048eae328 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -29,6 +29,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131] - `include_matches` option of `journald` input no longer accepts a list of string. {pull}29294[29294] - Add job.name in pods controlled by Jobs {pull}28954[28954] +- Change Docker base image from CentOS 7 to Ubuntu 20.04 {pull}29681[29681] *Auditbeat* diff --git a/auditbeat/Dockerfile b/auditbeat/Dockerfile index 061539b6dcf3..08cff3f06a71 100644 --- a/auditbeat/Dockerfile +++ b/auditbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ python3 \ python3-pip \ python3-venv \ diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index 09efabf28260..9221f1ac0c08 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -475,8 +475,8 @@ shared: - &agent_docker_spec <<: *agent_binary_spec extra_vars: - from: 'centos:7' - buildFrom: 'centos:7' + from: 'ubuntu:20.04' + buildFrom: 'ubuntu:20.04' dockerfile: 'Dockerfile.elastic-agent.tmpl' docker_entrypoint: 'docker-entrypoint.elastic-agent.tmpl' user: '{{ .BeatName }}' @@ -495,8 +495,8 @@ shared: - &agent_docker_arm_spec <<: *agent_docker_spec extra_vars: - from: 'arm64v8/centos:7' - buildFrom: 'arm64v8/centos:7' + from: 'arm64v8/ubuntu:20.04' + buildFrom: 'arm64v8/ubuntu:20.04' - &agent_docker_cloud_spec <<: *agent_docker_spec @@ -653,8 +653,8 @@ shared: - &docker_spec <<: *binary_spec extra_vars: - from: 'centos:7' - buildFrom: 'centos:7' + from: 'ubuntu:20.04' + buildFrom: 'ubuntu:20.04' user: '{{ .BeatName }}' linux_capabilities: '' files: @@ -666,8 +666,8 @@ shared: - &docker_arm_spec <<: *docker_spec extra_vars: - from: 'arm64v8/centos:7' - buildFrom: 'arm64v8/centos:7' + from: 'arm64v8/ubuntu:20.04' + buildFrom: 'arm64v8/ubuntu:20.04' - &docker_ubi_spec extra_vars: @@ -1230,4 +1230,4 @@ specs: <<: *elastic_license_for_binaries files: '{{.BeatName}}{{.BinaryExt}}': - source: ./build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}} \ No newline at end of file + source: ./build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}} diff --git a/dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl index 38f7934a9d7d..644df5bd73a8 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl @@ -27,42 +27,51 @@ RUN mkdir -p {{ $beatHome }}/data {{ $beatHome }}/data/elastic-agent-{{ commit_s {{- end }} true -{{- if .linux_capabilities }} -# Since the beat is stored at the other end of a symlink we must follow the symlink first -# For security reasons setcap does not support symlinks. This is smart in the general case -# but in our specific case since we're building a trusted image from trusted binaries this is -# fine. Thus, we use readlink to follow the link and setcap on the actual binary -RUN readlink -f {{ $beatBinary }} | xargs setcap {{ .linux_capabilities }} -{{- end }} - FROM {{ .from }} ENV BEAT_SETUID_AS={{ .user }} {{- if contains .from "ubi-minimal" }} -RUN for iter in {1..10}; do microdnf update -y && microdnf install -y shadow-utils jq && microdnf clean all && exit_code=0 && break || exit_code=$? && echo "microdnf error: retry $iter in 10s" && sleep 10; done; (exit $exit_code) +RUN for iter in {1..10}; do microdnf update -y && microdnf install -y findutils shadow-utils && microdnf clean all && exit_code=0 && break || exit_code=$? && echo "microdnf error: retry $iter in 10s" && sleep 10; done; (exit $exit_code) {{- else }} -# Installing jq needs to be installed after epel-release and cannot be in the same yum install command. -RUN case $(arch) in aarch64) YUM_FLAGS="-x bind-license";; esac; \ - for iter in {1..10}; do \ - yum update -y $YUM_FLAGS && \ - yum install -y epel-release && \ - yum update -y $YUM_FLAGS && \ - yum install -y jq && \ - yum clean all && \ - exit_code=0 && break || exit_code=$? && echo "yum error: retry $iter in 10s" && sleep 10; \ + +RUN for iter in {1..10}; do \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --yes ca-certificates curl libcap2-bin xz-utils && \ + apt-get clean all && \ + exit_code=0 && break || exit_code=$? && echo "apt-get error: retry $iter in 10s" && sleep 10; \ done; \ (exit $exit_code) {{- end }} {{- if (and (contains .image_name "-complete") (not (contains .from "ubi-minimal"))) }} -RUN for iter in {1..10}; do \ - yum -y install atk gtk gdk xrandr pango libXcomposite libXcursor libXdamage \ - libXext libXi libXtst libXScrnSaver libXrandr GConf2 \ - alsa-lib atk gtk3 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils \ - xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc \ - yum clean all && \ - exit_code=0 && break || exit_code=$? && echo "yum error: retry $iter in 10s" && sleep 10; \ +RUN apt-get update -y && \ + for iter in {1..10}; do \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --yes \ + libglib2.0-0\ + libnss3\ + libnspr4\ + libatk1.0-0\ + libatk-bridge2.0-0\ + libcups2\ + libdrm2\ + libdbus-1-3\ + libxcb1\ + libxkbcommon0\ + libx11-6\ + libxcomposite1\ + libxdamage1\ + libxext6\ + libxfixes3\ + libxrandr2\ + libgbm1\ + libpango-1.0-0\ + libcairo2\ + libasound2\ + libatspi2.0-0\ + libxshmfence1 && \ + apt-get clean all && \ + exit_code=0 && break || exit_code=$? && echo "apt-get error: retry $iter in 10s" && sleep 10; \ done; \ (exit $exit_code) ENV NODE_PATH={{ $beatHome }}/.node @@ -145,6 +154,14 @@ COPY --from=home {{ $beatHome }}/NOTICE.txt /licenses COPY --from=home /opt /opt {{- end }} +{{- if .linux_capabilities }} +# Since the beat is stored at the other end of a symlink we must follow the symlink first +# For security reasons setcap does not support symlinks. This is smart in the general case +# but in our specific case since we're building a trusted image from trusted binaries this is +# fine. Thus, we use readlink to follow the link and setcap on the actual binary +RUN readlink -f {{ $beatBinary }} | xargs setcap {{ .linux_capabilities }} +{{- end }} + {{- if eq .user "root" }} {{- if contains .image_name "-cloud" }} # Generate folder for a stub command that will be overwritten at runtime @@ -213,3 +230,4 @@ RUN echo -e '#!/bin/sh\nexec /usr/local/bin/docker-entrypoint' > /app/apm.sh && {{- else }} ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/docker-entrypoint"] {{- end }} + diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 91a636f50b02..9309516bd80a 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -18,36 +18,52 @@ RUN mkdir -p {{ $beatHome }}/data {{ $beatHome }}/logs && \ {{- end }} chmod 0775 {{ $beatHome }}/data {{ $beatHome }}/logs -{{- if .linux_capabilities }} -# Since the beat is stored at the other end of a symlink we must follow the symlink first -# For security reasons setcap does not support symlinks. This is smart in the general case -# but in our specific case since we're building a trusted image from trusted binaries this is -# fine. Thus, we use readlink to follow the link and setcap on the actual binary -RUN readlink -f {{ $beatBinary }} | xargs setcap {{ .linux_capabilities }} -{{- end }} - FROM {{ .from }} {{- if contains .from "ubi-minimal" }} RUN microdnf -y update && \ - microdnf install shadow-utils && \ + microdnf install findutils shadow-utils && \ microdnf clean all {{- else }} -# FIXME: Package bind-license failed to update in arm -RUN case $(arch) in aarch64) YUM_FLAGS="-x bind-license";; esac; \ - yum -y update $YUM_FLAGS \ - {{- if (eq .BeatName "heartbeat") }} - && yum -y install epel-release \ - && yum -y install atk gtk gdk xrandr pango libXcomposite libXcursor libXdamage \ - libXext libXi libXtst libXScrnSaver libXrandr GConf2 \ - alsa-lib atk gtk3 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils \ - xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc \ - {{- end }} - && yum clean all && rm -rf /var/cache/yum - # See https://access.redhat.com/discussions/3195102 for why rm is needed +RUN for iter in {1..10}; do \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --yes ca-certificates curl libcap2-bin xz-utils && \ + apt-get clean all && \ + exit_code=0 && break || exit_code=$? && echo "apt-get error: retry $iter in 10s" && sleep 10; \ + done; \ + (exit $exit_code) {{- end }} {{- if (and (eq .BeatName "heartbeat") (not (contains .from "ubi-minimal"))) }} +RUN apt-get update -y && \ + for iter in {1..10}; do \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --yes \ + libglib2.0-0\ + libnss3\ + libnspr4\ + libatk1.0-0\ + libatk-bridge2.0-0\ + libcups2\ + libdrm2\ + libdbus-1-3\ + libxcb1\ + libxkbcommon0\ + libx11-6\ + libxcomposite1\ + libxdamage1\ + libxext6\ + libxfixes3\ + libxrandr2\ + libgbm1\ + libpango-1.0-0\ + libcairo2\ + libasound2\ + libatspi2.0-0\ + libxshmfence1 && \ + apt-get clean all && \ + exit_code=0 && break || exit_code=$? && echo "apt-get error: retry $iter in 10s" && sleep 10; \ + done; \ + (exit $exit_code) ENV NODE_PATH={{ $beatHome }}/.node RUN echo \ $NODE_PATH \ @@ -93,6 +109,7 @@ RUN set -e ; \ TINI_BIN=""; \ TINI_SHA256=""; \ TINI_VERSION="v0.19.0"; \ + echo "The arch value is $(arch)"; \ case "$(arch)" in \ x86_64) \ TINI_BIN="tini-amd64"; \ @@ -120,6 +137,14 @@ RUN mkdir /licenses COPY --from=home {{ $beatHome }}/LICENSE.txt /licenses COPY --from=home {{ $beatHome }}/NOTICE.txt /licenses +{{- if .linux_capabilities }} +# Since the beat is stored at the other end of a symlink we must follow the symlink first +# For security reasons setcap does not support symlinks. This is smart in the general case +# but in our specific case since we're building a trusted image from trusted binaries this is +# fine. Thus, we use readlink to follow the link and setcap on the actual binary +RUN readlink -f {{ $beatBinary }} | xargs setcap {{ .linux_capabilities }} +{{- end }} + {{- if ne .user "root" }} RUN groupadd --gid 1000 {{ .BeatName }} RUN useradd -M --uid 1000 --gid 1000 --groups 0 --home {{ $beatHome }} {{ .user }} diff --git a/filebeat/Dockerfile b/filebeat/Dockerfile index 763572e5a991..3b17f95e9980 100644 --- a/filebeat/Dockerfile +++ b/filebeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ libsystemd-dev \ netcat \ rsync \ diff --git a/heartbeat/Dockerfile b/heartbeat/Dockerfile index 355510ff31fa..f4a1faae3695 100644 --- a/heartbeat/Dockerfile +++ b/heartbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ netcat \ python3 \ python3-pip \ diff --git a/libbeat/Dockerfile b/libbeat/Dockerfile index 3ff2e7a8ce43..97a1b6343847 100644 --- a/libbeat/Dockerfile +++ b/libbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ netcat \ libpcap-dev \ python3 \ diff --git a/metricbeat/Dockerfile b/metricbeat/Dockerfile index d9166f054f13..e1c97b72d365 100644 --- a/metricbeat/Dockerfile +++ b/metricbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt update \ - && apt install -qq -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y --no-install-recommends \ netcat \ python3 \ python3-dev \ diff --git a/packetbeat/Dockerfile b/packetbeat/Dockerfile index 6223e3d70f0d..0a5a4a841282 100644 --- a/packetbeat/Dockerfile +++ b/packetbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ python3 \ python3-pip \ python3-venv \ diff --git a/x-pack/functionbeat/Dockerfile b/x-pack/functionbeat/Dockerfile index f07760a84870..5a75f945955b 100644 --- a/x-pack/functionbeat/Dockerfile +++ b/x-pack/functionbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ netcat \ rsync \ python3 \ diff --git a/x-pack/libbeat/Dockerfile b/x-pack/libbeat/Dockerfile index 12ce0e092039..78c387b04d9d 100644 --- a/x-pack/libbeat/Dockerfile +++ b/x-pack/libbeat/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17.5 RUN \ apt-get update \ - && apt-get install -y --no-install-recommends \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ netcat \ rsync \ python3 \ From 5c3cf5c310719581293c3fb04d0c712f283405b2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 08:38:54 +0100 Subject: [PATCH 169/172] Prepare 8.0.0-rc1 changelog (#29795) (#29806) (cherry picked from commit 9a5ee416b097a4dbae08bcef7876f37579bcd45c) Co-authored-by: Andres Rodriguez --- CHANGELOG.asciidoc | 5 +++++ libbeat/docs/release.asciidoc | 1 + 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index aa5c9f9a5ace..c61cdbccb99b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -3,6 +3,11 @@ :issue: https://github.com/elastic/beats/issues/ :pull: https://github.com/elastic/beats/pull/ +[[release-notes-8.0.0-rc1]] +=== Beats version 8.0.0-rc1 + +Changes will be described in a later RC / GA. + [[release-notes-8.0.0-beta1]] === Beats version 8.0.0-beta1 diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index fa53cf52e5b6..0255a23c6988 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -8,6 +8,7 @@ This section summarizes the changes in each release. Also read <> for more detail about changes that affect upgrade. +* <> * <> * <> * <> From 3270ae1ab631a156f8f7913ca3a794fe6bd80b2f Mon Sep 17 00:00:00 2001 From: "Lucas F. da Costa" Date: Wed, 12 Jan 2022 10:27:44 +0000 Subject: [PATCH 170/172] Add summary to journeys which don't emit journey:end (early node subprocess exits) (#29606) * update link to beats developer guide * fix: add summary to journeys which don't emit journey:end [fixes #28770] * fix: avoid cmd/status when journey has already finished --- CHANGELOG.next.asciidoc | 1 + libbeat/README.md | 2 +- .../monitors/browser/synthexec/enrich.go | 41 ++++--- .../monitors/browser/synthexec/enrich_test.go | 113 ++++++++++++++++-- .../browser/synthexec/execmultiplexer.go | 2 +- .../browser/synthexec/execmultiplexer_test.go | 23 ++-- .../monitors/browser/synthexec/synthexec.go | 7 +- 7 files changed, 150 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 5f3048eae328..681900086937 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -46,6 +46,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* - Only add monitor.status to browser events when summary. {pull}29460[29460] +- Also add summary to journeys for which the synthetics runner crashes. {pull}29606[29606] *Metricbeat* diff --git a/libbeat/README.md b/libbeat/README.md index cf99987c5a3b..06a22219dfe3 100644 --- a/libbeat/README.md +++ b/libbeat/README.md @@ -8,7 +8,7 @@ If you want to create a new project that reads some sort of operational data and ships it to Elasticsearch, we suggest you make use of this library. Please start by reading our [CONTRIBUTING](../CONTRIBUTING.md) file. We also have a [developer -guide](https://www.elastic.co/guide/en/beats/libbeat/current/new-beat.html) to +guide](https://www.elastic.co/guide/en/beats/devguide/master/index.html) to help you with the creation of new Beats. Please also open a topic on the [forums](https://discuss.elastic.co/c/beats/libbeat) and diff --git a/x-pack/heartbeat/monitors/browser/synthexec/enrich.go b/x-pack/heartbeat/monitors/browser/synthexec/enrich.go index c3ab6c76faab..bec551a7947e 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/enrich.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/enrich.go @@ -112,6 +112,14 @@ func (je *journeyEnricher) enrichSynthEvent(event *beat.Event, se *SynthEvent) e } switch se.Type { + case "cmd/status": + // If a command failed _after_ the journey was complete, as it happens + // when an `afterAll` hook fails, for example, we don't wan't to include + // a summary in the cmd/status event. + if !je.journeyComplete { + je.end = event.Timestamp + return je.createSummary(event) + } case "journey/end": je.journeyComplete = true return je.createSummary(event) @@ -155,23 +163,24 @@ func (je *journeyEnricher) createSummary(event *beat.Event) error { down = 0 } - if je.journeyComplete { - eventext.MergeEventFields(event, common.MapStr{ - "url": je.urlFields, - "synthetics": common.MapStr{ - "type": "heartbeat/summary", - "journey": je.journey, - }, - "monitor": common.MapStr{ - "duration": common.MapStr{ - "us": int64(je.end.Sub(je.start) / time.Microsecond), - }, - }, - "summary": common.MapStr{ - "up": up, - "down": down, + eventext.MergeEventFields(event, common.MapStr{ + "url": je.urlFields, + "synthetics": common.MapStr{ + "type": "heartbeat/summary", + "journey": je.journey, + }, + "monitor": common.MapStr{ + "duration": common.MapStr{ + "us": int64(je.end.Sub(je.start) / time.Microsecond), }, - }) + }, + "summary": common.MapStr{ + "up": up, + "down": down, + }, + }) + + if je.journeyComplete { return je.firstError } diff --git a/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go b/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go index 629454f34c0e..f2c8ba25dca9 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go @@ -21,6 +21,18 @@ import ( "github.com/elastic/go-lookslike/testslike" ) +func makeStepEvent(typ string, ts float64, name string, index int, status string, urlstr string, err *SynthError) *SynthEvent { + return &SynthEvent{ + Type: typ, + TimestampEpochMicros: 1000 + ts, + PackageVersion: "1.0.0", + Step: &Step{Name: name, Index: index, Status: status}, + Error: err, + Payload: common.MapStr{}, + URL: urlstr, + } +} + func TestJourneyEnricher(t *testing.T) { journey := &Journey{ Name: "A Journey Name", @@ -50,17 +62,6 @@ func TestJourneyEnricher(t *testing.T) { Journey: journey, Payload: common.MapStr{}, } - makeStepEvent := func(typ string, ts float64, name string, index int, status string, urlstr string, err *SynthError) *SynthEvent { - return &SynthEvent{ - Type: typ, - TimestampEpochMicros: 1000 + ts, - PackageVersion: "1.0.0", - Step: &Step{Name: name, Index: index, Status: status}, - Error: err, - Payload: common.MapStr{}, - URL: urlstr, - } - } url1 := "http://example.net/url1" url2 := "http://example.net/url2" url3 := "http://example.net/url3" @@ -121,6 +122,24 @@ func TestEnrichSynthEvent(t *testing.T) { wantErr bool check func(t *testing.T, e *beat.Event, je *journeyEnricher) }{ + { + "cmd/status", + &journeyEnricher{}, + &SynthEvent{ + Type: "cmd/status", + Error: &SynthError{Name: "cmdexit", Message: "cmd err msg"}, + }, + true, + func(t *testing.T, e *beat.Event, je *journeyEnricher) { + v := lookslike.MustCompile(map[string]interface{}{ + "summary": map[string]int{ + "up": 0, + "down": 1, + }, + }) + testslike.Test(t, v, e.Fields) + }, + }, { "journey/end", &journeyEnricher{}, @@ -195,3 +214,75 @@ func TestEnrichSynthEvent(t *testing.T) { }) } } + +func TestNoSummaryOnAfterHook(t *testing.T) { + journey := &Journey{ + Name: "A journey that fails after completing", + Id: "my-bad-after-all-hook", + } + journeyStart := &SynthEvent{ + Type: "journey/start", + TimestampEpochMicros: 1000, + PackageVersion: "1.0.0", + Journey: journey, + Payload: common.MapStr{}, + } + syntherr := &SynthError{ + Message: "my-errmsg", + Name: "my-errname", + Stack: "my\nerr\nstack", + } + journeyEnd := &SynthEvent{ + Type: "journey/end", + TimestampEpochMicros: 2000, + PackageVersion: "1.0.0", + Journey: journey, + Payload: common.MapStr{}, + } + cmdStatus := &SynthEvent{ + Type: "cmd/status", + Error: &SynthError{Name: "cmdexit", Message: "cmd err msg"}, + TimestampEpochMicros: 3000, + } + + badStepUrl := "https://example.com/bad-step" + synthEvents := []*SynthEvent{ + journeyStart, + makeStepEvent("step/start", 10, "Step1", 1, "", "", nil), + makeStepEvent("step/end", 20, "Step1", 1, "failed", badStepUrl, syntherr), + journeyEnd, + cmdStatus, + } + + je := &journeyEnricher{} + + for idx, se := range synthEvents { + e := &beat.Event{} + t.Run(fmt.Sprintf("event %d", idx), func(t *testing.T) { + enrichErr := je.enrich(e, se) + + if se != nil && se.Type == "cmd/status" { + t.Run("no summary in cmd/status", func(t *testing.T) { + require.NotContains(t, e.Fields, "summary") + }) + } + + // Only the journey/end event should get a summary when + // it's emitted before the cmd/status (when an afterX hook fails). + if se != nil && se.Type == "journey/end" { + require.Equal(t, stepError(syntherr), enrichErr) + + u, _ := url.Parse(badStepUrl) + t.Run("summary in journey/end", func(t *testing.T) { + v := lookslike.MustCompile(common.MapStr{ + "synthetics.type": "heartbeat/summary", + "url": wrappers.URLFields(u), + "monitor.duration.us": int64(journeyEnd.Timestamp().Sub(journeyStart.Timestamp()) / time.Microsecond), + }) + + testslike.Test(t, v, e.Fields) + }) + } + }) + } +} diff --git a/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer.go b/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer.go index 57b423626d15..07de0143c38b 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer.go @@ -29,7 +29,7 @@ func (e ExecMultiplexer) writeSynthEvent(se *SynthEvent) { e.eventCounter.Store(-1) } hasCurrentJourney := e.currentJourney.Load() - if se.Type == "journey/end" { + if se.Type == "journey/end" || se.Type == "cmd/status" { e.currentJourney.Store(false) } diff --git a/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer_test.go b/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer_test.go index 56af4c94d9d1..ec85a6b52229 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer_test.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/execmultiplexer_test.go @@ -18,7 +18,7 @@ func TestExecMultiplexer(t *testing.T) { var testJourneys []*Journey var testEvents []*SynthEvent time := float64(0) - for jIdx := 0; jIdx < 3; jIdx++ { + for jIdx := 0; jIdx < 4; jIdx++ { time++ // fake time to make events seem spaced out journey := &Journey{ Name: fmt.Sprintf("J%d", jIdx), @@ -45,11 +45,20 @@ func TestExecMultiplexer(t *testing.T) { }) } - testEvents = append(testEvents, &SynthEvent{ - Journey: journey, - Type: "journey/end", - TimestampEpochMicros: time, - }) + // We want one of the test journeys to end with a cmd/status indicating it failed + if jIdx != 4 { + testEvents = append(testEvents, &SynthEvent{ + Journey: journey, + Type: "journey/end", + TimestampEpochMicros: time, + }) + } else { + testEvents = append(testEvents, &SynthEvent{ + Journey: journey, + Type: "cmd/status", + TimestampEpochMicros: time, + }) + } } // Write the test events in another go routine since writes block @@ -77,7 +86,7 @@ Loop: i := 0 // counter for index, resets on journey change for _, se := range results { require.Equal(t, i, se.index) - if se.Type == "journey/end" { + if se.Type == "journey/end" || se.Type == "cmd/status" { i = 0 } else { i++ diff --git a/x-pack/heartbeat/monitors/browser/synthexec/synthexec.go b/x-pack/heartbeat/monitors/browser/synthexec/synthexec.go index e5bcd1332f5f..039a3480c800 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/synthexec.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/synthexec.go @@ -196,8 +196,9 @@ func runCmd( if err != nil { str := fmt.Sprintf("command exited with status %d: %s", cmd.ProcessState.ExitCode(), err) mpx.writeSynthEvent(&SynthEvent{ - Type: "cmd/status", - Error: &SynthError{Name: "cmdexit", Message: str}, + Type: "cmd/status", + Error: &SynthError{Name: "cmdexit", Message: str}, + TimestampEpochMicros: float64(time.Now().UnixMicro()), }) logp.Warn("Error executing command '%s' (%d): %s", loggableCmd.String(), cmd.ProcessState.ExitCode(), err) } @@ -243,7 +244,7 @@ func lineToSynthEventFactory(typ string) func(bytes []byte, text string) (res *S logp.Info("%s: %s", typ, text) return &SynthEvent{ Type: typ, - TimestampEpochMicros: float64(time.Now().UnixNano() / int64(time.Millisecond)), + TimestampEpochMicros: float64(time.Now().UnixMicro()), Payload: map[string]interface{}{ "message": text, }, From 56423a06169d0bf87769867dd1929518e248e65a Mon Sep 17 00:00:00 2001 From: Taylor Swanson <90622908+taylor-swanson@users.noreply.github.com> Date: Wed, 12 Jan 2022 09:06:43 -0600 Subject: [PATCH 171/172] [Winlogbeat] Add provider name to Security routing pipeline check (#29781) - Added the two provider names currently supported by the Security pipeline to the conditional check in the routing pipeline. These two providers are "Microsoft-Windows-Eventlog" and "Microsoft-Windows-Security-Auditing". - This will prevent unsupported providers such as "AD FS" from being enriched with incorrect information. --- CHANGELOG.next.asciidoc | 1 + x-pack/winlogbeat/module/routing/ingest/routing.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 681900086937..a2a9ba049ebb 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -125,6 +125,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Winlogbeat* +- Add provider names to Security pipeline conditional check in routing pipeline. {issue}27288[27288] {pull}29781[29781] *Functionbeat* diff --git a/x-pack/winlogbeat/module/routing/ingest/routing.yml b/x-pack/winlogbeat/module/routing/ingest/routing.yml index 7566be699437..52f8825f1ef6 100644 --- a/x-pack/winlogbeat/module/routing/ingest/routing.yml +++ b/x-pack/winlogbeat/module/routing/ingest/routing.yml @@ -3,7 +3,7 @@ description: Winlogbeat Routing Pipeline processors: - pipeline: name: '{< IngestPipeline "security" >}' - if: ctx?.winlog?.channel == 'Security' + if: ctx?.winlog?.channel == 'Security' && ['Microsoft-Windows-Eventlog', 'Microsoft-Windows-Security-Auditing'].contains(ctx?.winlog?.provider_name) - pipeline: name: '{< IngestPipeline "sysmon" >}' if: ctx?.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational' From cb5f2eb3eb43383121dafd82b03935a6eb2ab62f Mon Sep 17 00:00:00 2001 From: Blake Rouse Date: Wed, 12 Jan 2022 12:03:37 -0500 Subject: [PATCH 172/172] [Elastic Agent] Fix issue with ensureServiceToken. (#29800) * Fix issue with ensureServiceToken. * Move ensureServiceToken up to line 273. --- .../elastic-agent/pkg/agent/cmd/container.go | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index 33f46728b656..25ff4c15ddcd 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -199,11 +199,6 @@ func containerCmd(streams *cli.IOStreams, cmd *cobra.Command) error { } } - err = ensureServiceToken(streams, &cfg) - if err != nil { - return err - } - // start apm-server legacy process when in cloud mode var wg sync.WaitGroup var apmProc *process.Info @@ -274,6 +269,12 @@ func runContainerCmd(streams *cli.IOStreams, cmd *cobra.Command, cfg setupConfig return run(streams, logToStderr) } + if cfg.Kibana.Fleet.Setup || cfg.Fleet.Enroll { + err = ensureServiceToken(streams, &cfg) + if err != nil { + return err + } + } if cfg.Kibana.Fleet.Setup { client, err = kibanaClient(cfg.Kibana, cfg.Kibana.Headers) if err != nil { @@ -309,7 +310,10 @@ func runContainerCmd(streams *cli.IOStreams, cmd *cobra.Command, cfg setupConfig if policy != nil { policyID = policy.ID } - logInfo(streams, "Policy selected for enrollment: ", policyID) + if policyID != "" { + logInfo(streams, "Policy selected for enrollment: ", policyID) + } + cmdArgs, err := buildEnrollArgs(cfg, token, policyID) if err != nil { return err @@ -349,11 +353,13 @@ func ensureServiceToken(streams *cli.IOStreams, cfg *setupConfig) error { } logInfo(streams, "Requesting service_token from Kibana.") + + // Client is not passed in to this function because this function will use username/password and then + // all the following clients will use the created service token. client, err := kibanaClient(cfg.Kibana, cfg.Kibana.Headers) if err != nil { return err } - code, r, err := client.Connection.Request("POST", "/api/fleet/service-tokens", nil, nil, nil) if err != nil { return fmt.Errorf("request to get security token from Kibana failed: %w", err)