From 591fc3a7c9485b94a0631afe4ca6afaedc89f2f9 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Tue, 29 Jun 2021 00:55:17 -0700 Subject: [PATCH 01/25] [Heartbeat] configure permissions for synthetics config (#26393) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 880aac57ccd..dd8bd021a8c 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -47,7 +47,7 @@ ENV NODE_PATH={{ $beatHome }}/.node RUN echo \ $NODE_PATH \ {{ $beatHome }}/.config \ - {{ $beatHome }}/suites \ + {{ $beatHome }}/.synthetics \ {{ $beatHome }}/.npm \ {{ $beatHome }}/.cache \ | xargs -IDIR sh -c 'mkdir -p DIR && chmod 0770 DIR' From bba9cfd70e6c1c9ef6ab7ca215d01567f731fed2 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Tue, 29 Jun 2021 10:12:20 +0200 Subject: [PATCH 02/25] [Elastic Agent] Enable configuring monitoring namespace (#26439) [Elastic Agent] Enable configuring monitoring namespace (#26439) --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../emitter/modifiers/monitoring_decorator.go | 1 + .../pkg/agent/operation/monitoring.go | 33 +-- .../pkg/agent/operation/monitoring_test.go | 3 + .../pkg/agent/program/program_test.go | 4 + .../testdata/namespace-endpoint-security.yml | 114 ++++++++++ .../program/testdata/namespace-filebeat.yml | 68 ++++++ .../testdata/namespace-fleet-server.yml | 16 ++ .../program/testdata/namespace-heartbeat.yml | 30 +++ .../program/testdata/namespace-metricbeat.yml | 88 ++++++++ .../program/testdata/namespace-packetbeat.yml | 35 +++ .../pkg/agent/program/testdata/namespace.yml | 201 ++++++++++++++++++ .../core/monitoring/beats/beats_monitor.go | 9 + .../pkg/core/monitoring/config/config.go | 3 + .../pkg/core/monitoring/monitor.go | 1 + .../pkg/core/monitoring/noop/noop_monitor.go | 3 + 16 files changed, 594 insertions(+), 16 deletions(-) create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-endpoint-security.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-filebeat.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-fleet-server.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-heartbeat.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-metricbeat.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace-packetbeat.yml create mode 100644 x-pack/elastic-agent/pkg/agent/program/testdata/namespace.yml diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index d5eed75dc0f..7fe323a0b64 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -115,4 +115,5 @@ - Use `filestream` input for internal log collection. {pull}25660[25660] - Enable agent to send custom headers to kibana/ES {pull}26275[26275] - Set `agent.id` to the Fleet Agent ID in events published from inputs backed by Beats. {issue}21121[21121] {pull}26394[26394] +- Enable configuring monitoring namespace {issue}26439[26439] - Communicate with Fleet Server over HTTP2. {pull}26474[26474] diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/modifiers/monitoring_decorator.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/modifiers/monitoring_decorator.go index 8c3eb1c7d43..b31220f93de 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/modifiers/monitoring_decorator.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/modifiers/monitoring_decorator.go @@ -49,6 +49,7 @@ func InjectMonitoring(agentInfo *info.AgentInfo, outputGroup string, rootAst *tr transpiler.NewKey("logs", transpiler.NewBoolVal(true)), transpiler.NewKey("metrics", transpiler.NewBoolVal(true)), transpiler.NewKey("use_output", transpiler.NewStrVal("default")), + transpiler.NewKey("namespace", transpiler.NewStrVal("default")), }) transpiler.Insert(rootAst, transpiler.NewKey("monitoring", monitoringNode), "settings") diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go index 45b7263cf73..17188321b56 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go @@ -161,11 +161,12 @@ func (o *Operator) generateMonitoringSteps(version, outputType string, output in var steps []configrequest.Step watchLogs := o.monitor.WatchLogs() watchMetrics := o.monitor.WatchMetrics() + monitoringNamespace := o.monitor.MonitoringNamespace() // generate only when monitoring is running (for config refresh) or // state changes (turning on/off) if watchLogs != o.isMonitoringLogs() || watchLogs { - fbConfig, any := o.getMonitoringFilebeatConfig(outputType, output) + fbConfig, any := o.getMonitoringFilebeatConfig(outputType, output, monitoringNamespace) stepID := configrequest.StepRun if !watchLogs || !any { stepID = configrequest.StepRemove @@ -182,7 +183,7 @@ func (o *Operator) generateMonitoringSteps(version, outputType string, output in steps = append(steps, filebeatStep) } if watchMetrics != o.isMonitoringMetrics() || watchMetrics { - mbConfig, any := o.getMonitoringMetricbeatConfig(outputType, output) + mbConfig, any := o.getMonitoringMetricbeatConfig(outputType, output, monitoringNamespace) stepID := configrequest.StepRun if !watchMetrics || !any { stepID = configrequest.StepRemove @@ -215,12 +216,12 @@ func loadSpecFromSupported(processName string) program.Spec { } } -func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interface{}) (map[string]interface{}, bool) { +func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interface{}, monitoringNamespace string) (map[string]interface{}, bool) { inputs := []interface{}{ map[string]interface{}{ "type": "filestream", "parsers": []map[string]interface{}{ - map[string]interface{}{ + { "ndjson": map[string]interface{}{ "overwrite_keys": true, "message_key": "message", @@ -233,7 +234,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa filepath.Join(paths.Home(), "logs", "elastic-agent-watcher-json.log"), filepath.Join(paths.Home(), "logs", "elastic-agent-watcher-json.log*"), }, - "index": "logs-elastic_agent-default", + "index": fmt.Sprintf("logs-elastic_agent-%s", monitoringNamespace), "processors": []map[string]interface{}{ { "add_fields": map[string]interface{}{ @@ -241,7 +242,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa "fields": map[string]interface{}{ "type": "logs", "dataset": "elastic_agent", - "namespace": "default", + "namespace": monitoringNamespace, }, }, }, @@ -280,7 +281,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa inputs = append(inputs, map[string]interface{}{ "type": "filestream", "parsers": []map[string]interface{}{ - map[string]interface{}{ + { "ndjson": map[string]interface{}{ "overwrite_keys": true, "message_key": "message", @@ -288,7 +289,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa }, }, "paths": paths, - "index": fmt.Sprintf("logs-elastic_agent.%s-default", name), + "index": fmt.Sprintf("logs-elastic_agent.%s-%s", name, monitoringNamespace), "processors": []map[string]interface{}{ { "add_fields": map[string]interface{}{ @@ -296,7 +297,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa "fields": map[string]interface{}{ "type": "logs", "dataset": fmt.Sprintf("elastic_agent.%s", name), - "namespace": "default", + "namespace": monitoringNamespace, }, }, }, @@ -345,7 +346,7 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa return result, true } -func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output interface{}) (map[string]interface{}, bool) { +func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output interface{}, monitoringNamespace string) (map[string]interface{}, bool) { hosts := o.getMetricbeatEndpoints() if len(hosts) == 0 { return nil, false @@ -359,7 +360,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "metricsets": []string{"stats", "state"}, "period": "10s", "hosts": endpoints, - "index": fmt.Sprintf("metrics-elastic_agent.%s-default", name), + "index": fmt.Sprintf("metrics-elastic_agent.%s-%s", name, monitoringNamespace), "processors": []map[string]interface{}{ { "add_fields": map[string]interface{}{ @@ -367,7 +368,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "fields": map[string]interface{}{ "type": "metrics", "dataset": fmt.Sprintf("elastic_agent.%s", name), - "namespace": "default", + "namespace": monitoringNamespace, }, }, }, @@ -397,7 +398,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "period": "10s", "path": "/stats", "hosts": endpoints, - "index": fmt.Sprintf("metrics-elastic_agent.%s-default", fixedAgentName), + "index": fmt.Sprintf("metrics-elastic_agent.%s-%s", fixedAgentName, monitoringNamespace), "processors": []map[string]interface{}{ { "add_fields": map[string]interface{}{ @@ -405,7 +406,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "fields": map[string]interface{}{ "type": "metrics", "dataset": fmt.Sprintf("elastic_agent.%s", fixedAgentName), - "namespace": "default", + "namespace": monitoringNamespace, }, }, }, @@ -480,7 +481,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "period": "10s", "path": "/stats", "hosts": []string{beats.AgentPrefixedMonitoringEndpoint(o.config.DownloadConfig.OS(), o.config.MonitoringConfig.HTTP)}, - "index": fmt.Sprintf("metrics-elastic_agent.%s-default", fixedAgentName), + "index": fmt.Sprintf("metrics-elastic_agent.%s-%s", fixedAgentName, monitoringNamespace), "processors": []map[string]interface{}{ { "add_fields": map[string]interface{}{ @@ -488,7 +489,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "fields": map[string]interface{}{ "type": "metrics", "dataset": fmt.Sprintf("elastic_agent.%s", fixedAgentName), - "namespace": "default", + "namespace": monitoringNamespace, }, }, }, diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go index 136c9e485b1..c23248ff2d9 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go @@ -215,6 +215,9 @@ func (b *testMonitor) Reload(cfg *config.Config) error { return nil } // IsMonitoringEnabled returns true if monitoring is configured. func (b *testMonitor) IsMonitoringEnabled() bool { return b.monitorLogs || b.monitorMetrics } +// MonitoringNamespace returns monitoring namespace configured. +func (b *testMonitor) MonitoringNamespace() string { return "default" } + // WatchLogs return true if monitoring is configured and monitoring logs is enabled. func (b *testMonitor) WatchLogs() bool { return b.monitorLogs } 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 4498f7e5236..5ca35de0136 100644 --- a/x-pack/elastic-agent/pkg/agent/program/program_test.go +++ b/x-pack/elastic-agent/pkg/agent/program/program_test.go @@ -383,6 +383,10 @@ func TestConfiguration(t *testing.T) { empty bool err bool }{ + "namespace": { + programs: []string{"filebeat", "fleet-server", "heartbeat", "metricbeat", "endpoint", "packetbeat"}, + expected: 6, + }, "single_config": { programs: []string{"filebeat", "fleet-server", "heartbeat", "metricbeat", "endpoint", "packetbeat"}, expected: 6, diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-endpoint-security.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-endpoint-security.yml new file mode 100644 index 00000000000..7e9f04dc411 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-endpoint-security.yml @@ -0,0 +1,114 @@ +fleet: + enabled: true + access_api_key: VuaCfGcBCdbkQm-e5aOx:ui2lp2axTNmsyakw9tvNnw + protocol: https + hosts: [ localhost:5601 ] + timeout: 30s + agent: + id: fleet-agent-id + logging.level: error + host: + id: host-agent-id + +output: + elasticsearch: + hosts: + - "127.0.0.1:9200" + - "127.0.0.1:9300" + namespace: test_namespace + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= + +inputs: +- id: endpoint-id + type: endpoint + name: endpoint-1 + enabled: true + package: + name: endpoint + version: 0.3.0 + data_stream: + namespace: default + artifact_manifest: + schema_version: v22 + manifest_version: v21 + artifacts: + - endpoint-allowlist-windows: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-windows + - endpoint-allowlist-macos: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-macos + - endpoint-allowlist-linux: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-linux + policy: + linux: + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + process: logs-endpoint.events.process-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + process: true + file: true + network: true + windows: + malware: + mode: prevent + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + registry: logs-endpoint.events.registry-default + process: logs-endpoint.events.process-default + driver: logs-endpoint.events.driver-default + library: logs-endpoint.events.library-default + alerts: logs-endpoint.alerts-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + registry: true + process: true + security: true + file: true + dns: false + dll_and_driver_load: false + network: true + mac: + malware: + mode: prevent + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + process: logs-endpoint.events.process-default + alerts: logs-endpoint.alerts-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + process: true + file: true + network: true diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-filebeat.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-filebeat.yml new file mode 100644 index 00000000000..83df83e56e0 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-filebeat.yml @@ -0,0 +1,68 @@ +filebeat: + inputs: + - type: log + paths: + - /var/log/hello1.log + - /var/log/hello2.log + index: logs-generic-default + vars: + var: value + processors: + - add_fields: + target: "data_stream" + fields: + type: logs + dataset: generic + namespace: default + - add_fields: + target: "event" + fields: + dataset: generic + - add_fields: + target: "elastic_agent" + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: "agent" + fields: + id: agent-id + - type: log + paths: + - /var/log/hello3.log + - /var/log/hello4.log + index: testtype-generic-default + vars: + var: value + processors: + - add_fields: + target: "data_stream" + fields: + type: testtype + dataset: generic + namespace: default + - add_fields: + target: "event" + fields: + dataset: generic + - add_fields: + target: "elastic_agent" + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: "agent" + fields: + id: agent-id +output: + elasticsearch: + hosts: + - 127.0.0.1:9200 + - 127.0.0.1:9300 + namespace: test_namespace + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-fleet-server.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-fleet-server.yml new file mode 100644 index 00000000000..c03696aff1f --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-fleet-server.yml @@ -0,0 +1,16 @@ +fleet: + agent: + id: fleet-agent-id + logging.level: error + host: + id: host-agent-id + +output: + elasticsearch: + hosts: [ 127.0.0.1:9200, 127.0.0.1:9300 ] + username: fleet + password: fleetpassword + +inputs: + - id: fleet-server-id + type: fleet-server diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-heartbeat.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-heartbeat.yml new file mode 100644 index 00000000000..f34b204f5fa --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-heartbeat.yml @@ -0,0 +1,30 @@ +inputs: +- type: synthetics/http + id: unique-http-id + name: my-http + schedule: '*/5 * * * * * *' + host: "http://localhost:80/service/status" + timeout: 16s + wait: 1s + data_stream.namespace: default + processors: + - add_fields: + target: 'elastic_agent' + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: 'agent' + fields: + id: agent-id +output: + elasticsearch: + hosts: + - 127.0.0.1:9200 + - 127.0.0.1:9300 + namespace: test_namespace + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-metricbeat.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-metricbeat.yml new file mode 100644 index 00000000000..3f16a9d9e21 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-metricbeat.yml @@ -0,0 +1,88 @@ +metricbeat: + modules: + - module: docker + metricsets: [status] + index: metrics-docker.status-default + hosts: ["http://127.0.0.1:8080"] + processors: + - add_fields: + target: "data_stream" + fields: + type: metrics + dataset: docker.status + namespace: default + - add_fields: + target: "event" + fields: + dataset: docker.status + - add_fields: + target: "elastic_agent" + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: "agent" + fields: + id: agent-id + - module: docker + metricsets: [info] + index: metrics-generic-default + hosts: ["http://127.0.0.1:8080"] + processors: + - add_fields: + target: "data_stream" + fields: + type: metrics + dataset: generic + namespace: default + - add_fields: + target: "event" + fields: + dataset: generic + - add_fields: + target: "elastic_agent" + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: "agent" + fields: + id: agent-id + - module: apache + metricsets: [info] + index: metrics-generic-testing + hosts: ["http://apache.remote"] + processors: + - add_fields: + fields: + should_be: first + - add_fields: + target: "data_stream" + fields: + type: metrics + dataset: generic + namespace: testing + - add_fields: + target: "event" + fields: + dataset: generic + - add_fields: + target: "elastic_agent" + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: "agent" + fields: + id: agent-id +output: + elasticsearch: + hosts: [127.0.0.1:9200, 127.0.0.1:9300] + namespace: test_namespace + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-packetbeat.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-packetbeat.yml new file mode 100644 index 00000000000..d71499bdef4 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace-packetbeat.yml @@ -0,0 +1,35 @@ +inputs: +- type: packet + processors: + - add_fields: + target: 'elastic_agent' + fields: + id: agent-id + version: 8.0.0 + snapshot: false + - add_fields: + target: 'agent' + fields: + id: agent-id + streams: + - type: flow + timeout: 10s + period: 10s + keep_null: false + data_stream: + dataset: packet.flow + type: logs + - type: icmp + data_stream: + dataset: packet.icmp + type: logs +output: + elasticsearch: + hosts: + - 127.0.0.1:9200 + - 127.0.0.1:9300 + namespace: test_namespace + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= diff --git a/x-pack/elastic-agent/pkg/agent/program/testdata/namespace.yml b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace.yml new file mode 100644 index 00000000000..c2f83a9abf0 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/program/testdata/namespace.yml @@ -0,0 +1,201 @@ +name: Production Website DB Servers +fleet: + enabled: true + access_api_key: VuaCfGcBCdbkQm-e5aOx:ui2lp2axTNmsyakw9tvNnw + protocol: https + hosts: [ localhost:5601 ] + timeout: 30s + agent: + id: fleet-agent-id + logging.level: error + host: + id: host-agent-id + server: + output: + elasticsearch: + hosts: [ 127.0.0.1:9200, 127.0.0.1:9300 ] + username: fleet + password: fleetpassword + +outputs: + default: + type: elasticsearch + namespace: test_namespace + hosts: [127.0.0.1:9200, 127.0.0.1:9300] + username: elastic + password: changeme + api_key: TiNAGG4BaaMdaH1tRfuU:KnR6yE41RrSowb0kQ0HWoA + ca_sha256: 7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= + + monitoring: + type: elasticsearch + api_key: VuaCfGcBCdbkQm-e5aOx:ui2lp2axTNmsyakw9tvNnw + hosts: ["monitoring:9200"] + ca_sha256: "7lHLiyp4J8m9kw38SJ7SURJP4bXRZv/BNxyyXkCcE/M=" + +inputs: +- id: fleet-server-id + type: fleet-server + use_output: default + data_stream: + type: default +- type: docker/metrics + use_output: default + streams: + - metricset: status + processors: + - null + data_stream: + dataset: docker.status + - metricset: info + data_stream: + dataset: "" + hosts: ["http://127.0.0.1:8080"] +- type: logfile + use_output: default + streams: + - paths: + - /var/log/hello1.log + - /var/log/hello2.log + vars: + var: value +- type: logfile + data_stream: + type: testtype + use_output: default + streams: + - paths: + - /var/log/hello3.log + - /var/log/hello4.log + vars: + var: value +- id: apache-metrics-id + type: apache/metrics + data_stream: + namespace: testing + use_output: default + processors: + - add_fields: + fields: + should_be: first + streams: + - enabled: true + metricset: info + hosts: ["http://apache.remote"] + hosts: ["http://apache.local"] +- type: synthetics/http + id: unique-http-id + name: my-http + schedule: '*/5 * * * * * *' + host: "http://localhost:80/service/status" + timeout: 16s + wait: 1s +- type: packet + streams: + - type: flow + timeout: 10s + period: 10s + keep_null: false + data_stream: + dataset: packet.flow + type: logs + - type: icmp + data_stream: + dataset: packet.icmp + type: logs +- id: endpoint-id + type: endpoint + name: endpoint-1 + enabled: true + package: + name: endpoint + version: 0.3.0 + data_stream: + namespace: default + artifact_manifest: + schema_version: v22 + manifest_version: v21 + artifacts: + - endpoint-allowlist-windows: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-windows + - endpoint-allowlist-macos: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-macos + - endpoint-allowlist-linux: + sha256: 1234 + size: 2 + url: /relative/path/to/endpoint-allowlist-linux + policy: + linux: + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + process: logs-endpoint.events.process-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + process: true + file: true + network: true + windows: + malware: + mode: prevent + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + registry: logs-endpoint.events.registry-default + process: logs-endpoint.events.process-default + driver: logs-endpoint.events.driver-default + library: logs-endpoint.events.library-default + alerts: logs-endpoint.alerts-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + registry: true + process: true + security: true + file: true + dns: false + dll_and_driver_load: false + network: true + mac: + malware: + mode: prevent + advanced: + free-form: free-form-value + indices: + network: logs-endpoint.events.network-default + file: logs-endpoint.events.file-default + process: logs-endpoint.events.process-default + alerts: logs-endpoint.alerts-default + metadata: metrics-endpoint.metadata-default + policy: metrics-endpoint.policy-default + telemetry: metrics-endpoint.telemetry-default + logging: + file: info + stdout: debug + events: + process: true + file: true + network: true + +agent.monitoring: + use_output: monitoring + +agent: + reload: 123 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 743d44118d6..1c0c4ba61ad 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 @@ -21,6 +21,7 @@ import ( ) const httpPlusPrefix = "http+" +const defaultMonitoringNamespace = "default" // Monitor is a monitoring interface providing information about the way // how beat is monitored @@ -69,6 +70,14 @@ func (b *Monitor) Close() { // IsMonitoringEnabled returns true if monitoring is enabled. func (b *Monitor) IsMonitoringEnabled() bool { return b.config.Enabled } +// MonitoringNamespace returns monitoring namespace configured. +func (b *Monitor) MonitoringNamespace() string { + if b.config.Namespace == "" { + return defaultMonitoringNamespace + } + return b.config.Namespace +} + // WatchLogs returns true if monitoring is enabled and monitor should watch logs. func (b *Monitor) WatchLogs() bool { return b.config.Enabled && b.config.MonitorLogs } 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 2ce067d4e19..fe18b0fb73e 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go @@ -5,6 +5,7 @@ package config const defaultPort = 6791 +const defaultNamespace = "default" // MonitoringConfig describes a configuration of a monitoring type MonitoringConfig struct { @@ -12,6 +13,7 @@ type MonitoringConfig struct { MonitorLogs bool `yaml:"logs" config:"logs"` MonitorMetrics bool `yaml:"metrics" config:"metrics"` HTTP *MonitoringHTTPConfig `yaml:"http" config:"http"` + Namespace string `yaml:"namespace" config:"namespace"` } // MonitoringHTTPConfig is a config defining HTTP endpoint published by agent @@ -33,5 +35,6 @@ func DefaultConfig() *MonitoringConfig { Enabled: false, Port: defaultPort, }, + Namespace: defaultNamespace, } } diff --git a/x-pack/elastic-agent/pkg/core/monitoring/monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/monitor.go index 00c7a50003a..6c71f4f65fc 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/monitor.go @@ -23,6 +23,7 @@ type Monitor interface { Cleanup(spec program.Spec, pipelineID string) error Reload(cfg *config.Config) error IsMonitoringEnabled() bool + MonitoringNamespace() string WatchLogs() bool WatchMetrics() bool Close() diff --git a/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go index 9ea8f08a788..d98deb90888 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go @@ -66,3 +66,6 @@ func (b *Monitor) WatchLogs() bool { return false } // WatchMetrics return true if monitoring is configured and monitoring metrics is enabled. func (b *Monitor) WatchMetrics() bool { return false } + +// MonitoringNamespace returns monitoring namespace configured. +func (b *Monitor) MonitoringNamespace() string { return "default" } From b17daafded2fd0dbc832855732c29c7133d563cd Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Tue, 29 Jun 2021 10:12:54 +0200 Subject: [PATCH 03/25] [Elastic Agent] Improper casting of int64 (#26520) --- x-pack/elastic-agent/pkg/agent/transpiler/ast.go | 4 +++- x-pack/elastic-agent/pkg/agent/transpiler/ast_test.go | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/elastic-agent/pkg/agent/transpiler/ast.go b/x-pack/elastic-agent/pkg/agent/transpiler/ast.go index 100d8a462a0..31bb2faaa7c 100644 --- a/x-pack/elastic-agent/pkg/agent/transpiler/ast.go +++ b/x-pack/elastic-agent/pkg/agent/transpiler/ast.go @@ -716,8 +716,10 @@ func load(val reflect.Value) (Node, error) { return loadSliceOrArray(val) case reflect.String: return &StrVal{value: val.Interface().(string)}, nil - case reflect.Int, reflect.Int64: + case reflect.Int: return &IntVal{value: val.Interface().(int)}, nil + case reflect.Int64: + return &IntVal{value: int(val.Interface().(int64))}, nil case reflect.Uint: return &UIntVal{value: uint64(val.Interface().(uint))}, nil case reflect.Uint64: diff --git a/x-pack/elastic-agent/pkg/agent/transpiler/ast_test.go b/x-pack/elastic-agent/pkg/agent/transpiler/ast_test.go index e1b22c390ed..1e52d6c6f47 100644 --- a/x-pack/elastic-agent/pkg/agent/transpiler/ast_test.go +++ b/x-pack/elastic-agent/pkg/agent/transpiler/ast_test.go @@ -105,6 +105,7 @@ func TestAST(t *testing.T) { "support integers": { hashmap: map[string]interface{}{ "timeout": 12, + "zero": int64(0), "range": []int{20, 30, 40}, }, ast: &AST{ @@ -121,6 +122,7 @@ func TestAST(t *testing.T) { ), }, &Key{name: "timeout", value: &IntVal{value: 12}}, + &Key{name: "zero", value: &IntVal{value: 0}}, }, }, }, From f8bb3a2cb3223d2484d6af1af21b3b877915146b Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 29 Jun 2021 12:46:19 +0300 Subject: [PATCH 04/25] Refactor add_cloud_metadata to handle ECS fields easier (#26438) --- .../add_cloud_metadata/add_cloud_metadata.go | 41 ++++++------------- .../add_cloud_metadata/http_fetcher.go | 2 +- .../provider_alibaba_cloud.go | 2 +- .../add_cloud_metadata/provider_aws_ec2.go | 2 +- .../add_cloud_metadata/provider_azure_vm.go | 2 +- .../provider_digital_ocean.go | 2 +- .../add_cloud_metadata/provider_google_gce.go | 32 ++++++++------- .../provider_openstack_nova.go | 2 +- .../provider_tencent_cloud.go | 2 +- 9 files changed, 37 insertions(+), 50 deletions(-) diff --git a/libbeat/processors/add_cloud_metadata/add_cloud_metadata.go b/libbeat/processors/add_cloud_metadata/add_cloud_metadata.go index 5a511d96b46..974b8f85bf9 100644 --- a/libbeat/processors/add_cloud_metadata/add_cloud_metadata.go +++ b/libbeat/processors/add_cloud_metadata/add_cloud_metadata.go @@ -118,25 +118,10 @@ func (p *addCloudMetadata) Run(event *beat.Event) (*beat.Event, error) { return event, nil } - // If cloud key exists in event already and overwrite flag is set to false, this processor will not overwrite the - // cloud fields. For example aws module writes cloud.instance.* to events already, with overwrite=false, - // add_cloud_metadata should not overwrite these fields with new values. - if !p.initData.overwrite { - cloudValue, _ := event.GetValue("cloud") - if cloudValue != nil { - err := p.extractECSMeta(event, meta) - if err != nil { - return nil, err - } - return event, nil - } - } - - err := p.extractECSMeta(event, meta) + err := p.addMeta(event, meta) if err != nil { return nil, err } - _, err = event.PutValue("cloud", meta) return event, err } @@ -144,23 +129,21 @@ func (p *addCloudMetadata) String() string { return "add_cloud_metadata=" + p.getMeta().String() } -func (p *addCloudMetadata) extractECSMeta(event *beat.Event, meta common.MapStr) error { - // handle ECS fields first - if !p.initData.overwrite { - orchestratorValue, _ := event.GetValue("orchestrator") - if orchestratorValue != nil { - meta.Delete("orchestrator") - return nil +func (p *addCloudMetadata) addMeta(event *beat.Event, meta common.MapStr) error { + for key, metaVal := range meta { + // If key exists in event already and overwrite flag is set to false, this processor will not overwrite the + // meta fields. For example aws module writes cloud.instance.* to events already, with overwrite=false, + // add_cloud_metadata should not overwrite these fields with new values. + if !p.initData.overwrite { + v, _ := event.GetValue(key) + if v != nil { + continue + } } - } - orchestratorFields, err := meta.GetValue("orchestrator") - if err == nil { - _, err = event.PutValue("orchestrator", orchestratorFields) + _, err := event.PutValue(key, metaVal) if err != nil { return err } } - meta.Delete("orchestrator") - return nil } diff --git a/libbeat/processors/add_cloud_metadata/http_fetcher.go b/libbeat/processors/add_cloud_metadata/http_fetcher.go index e337edd5be9..0af5693526a 100644 --- a/libbeat/processors/add_cloud_metadata/http_fetcher.go +++ b/libbeat/processors/add_cloud_metadata/http_fetcher.go @@ -75,7 +75,7 @@ func (f *httpMetadataFetcher) fetchMetadata(ctx context.Context, client http.Cli // Apply schema. res.metadata = f.conv(res.metadata) - res.metadata["provider"] = f.provider + res.metadata.Put("cloud.provider", f.provider) return res } diff --git a/libbeat/processors/add_cloud_metadata/provider_alibaba_cloud.go b/libbeat/processors/add_cloud_metadata/provider_alibaba_cloud.go index 65dd9c23286..cf82c2d621a 100644 --- a/libbeat/processors/add_cloud_metadata/provider_alibaba_cloud.go +++ b/libbeat/processors/add_cloud_metadata/provider_alibaba_cloud.go @@ -36,7 +36,7 @@ var alibabaCloudMetadataFetcher = provider{ m["service"] = common.MapStr{ "name": "ECS", } - return common.MapStr(m) + return common.MapStr{"cloud": m} } urls, err := getMetadataURLs(c, ecsMetadataHost, []string{ diff --git a/libbeat/processors/add_cloud_metadata/provider_aws_ec2.go b/libbeat/processors/add_cloud_metadata/provider_aws_ec2.go index cbd82571468..350ec63b8c6 100644 --- a/libbeat/processors/add_cloud_metadata/provider_aws_ec2.go +++ b/libbeat/processors/add_cloud_metadata/provider_aws_ec2.go @@ -45,7 +45,7 @@ var ec2MetadataFetcher = provider{ "account": s.Object{"id": c.Str("accountId")}, "image": s.Object{"id": c.Str("imageId")}, }.Apply(m) - return out + return common.MapStr{"cloud": out} } fetcher, err := newMetadataFetcher(config, "aws", nil, metadataHost, ec2Schema, ec2InstanceIdentityURI) diff --git a/libbeat/processors/add_cloud_metadata/provider_azure_vm.go b/libbeat/processors/add_cloud_metadata/provider_azure_vm.go index b3f2a0b3222..8ba8a2284b3 100644 --- a/libbeat/processors/add_cloud_metadata/provider_azure_vm.go +++ b/libbeat/processors/add_cloud_metadata/provider_azure_vm.go @@ -50,7 +50,7 @@ var azureVMMetadataFetcher = provider{ }, "region": c.Str("location"), }.Apply(m) - return out + return common.MapStr{"cloud": out} } fetcher, err := newMetadataFetcher(config, "azure", azHeaders, metadataHost, azSchema, azMetadataURI) diff --git a/libbeat/processors/add_cloud_metadata/provider_digital_ocean.go b/libbeat/processors/add_cloud_metadata/provider_digital_ocean.go index 04da6228378..63c90bc5a96 100644 --- a/libbeat/processors/add_cloud_metadata/provider_digital_ocean.go +++ b/libbeat/processors/add_cloud_metadata/provider_digital_ocean.go @@ -41,7 +41,7 @@ var doMetadataFetcher = provider{ "name": c.Str("serviceName"), }, }.Apply(m) - return out + return common.MapStr{"cloud": out} } doMetadataURI := "/metadata/v1.json" diff --git a/libbeat/processors/add_cloud_metadata/provider_google_gce.go b/libbeat/processors/add_cloud_metadata/provider_google_gce.go index b9d6d4cc203..d6cb4bb74c1 100644 --- a/libbeat/processors/add_cloud_metadata/provider_google_gce.go +++ b/libbeat/processors/add_cloud_metadata/provider_google_gce.go @@ -49,14 +49,15 @@ var gceMetadataFetcher = provider{ gceMetadataURI := "/computeMetadata/v1/?recursive=true&alt=json" gceHeaders := map[string]string{"Metadata-Flavor": "Google"} gceSchema := func(m map[string]interface{}) common.MapStr { - out := common.MapStr{ + cloud := common.MapStr{ "service": common.MapStr{ "name": "GCE", }, } + meta := common.MapStr{} trimLeadingPath := func(key string) { - v, err := out.GetValue(key) + v, err := cloud.GetValue(key) if err != nil { return } @@ -64,7 +65,7 @@ var gceMetadataFetcher = provider{ if !ok { return } - out.Put(key, path.Base(p)) + cloud.Put(key, path.Base(p)) } if instance, ok := m["instance"].(map[string]interface{}); ok { @@ -77,6 +78,10 @@ var gceMetadataFetcher = provider{ "type": c.Str("machineType"), }, "availability_zone": c.Str("zone"), + }.ApplyTo(cloud, instance) + trimLeadingPath("machine.type") + trimLeadingPath("availability_zone") + s.Schema{ "orchestrator": s.Object{ "cluster": c.Dict( "attributes", @@ -85,29 +90,27 @@ var gceMetadataFetcher = provider{ "kubeconfig": c.Str("kubeconfig"), }), }, - }.ApplyTo(out, instance) - trimLeadingPath("machine.type") - trimLeadingPath("availability_zone") + }.ApplyTo(meta, instance) } - if kubeconfig, err := out.GetValue("orchestrator.cluster.kubeconfig"); err == nil { + if kubeconfig, err := meta.GetValue("orchestrator.cluster.kubeconfig"); err == nil { kubeConfig, ok := kubeconfig.(string) if !ok { - out.Delete("orchestrator.cluster.kubeconfig") + meta.Delete("orchestrator.cluster.kubeconfig") } cc := &KubeConfig{} err := yaml.Unmarshal([]byte(kubeConfig), cc) if err != nil { - out.Delete("orchestrator.cluster.kubeconfig") + meta.Delete("orchestrator.cluster.kubeconfig") } if len(cc.Clusters) > 0 { if cc.Clusters[0].Cluster.Server != "" { - out.Delete("orchestrator.cluster.kubeconfig") - out.Put("orchestrator.cluster.url", cc.Clusters[0].Cluster.Server) + meta.Delete("orchestrator.cluster.kubeconfig") + meta.Put("orchestrator.cluster.url", cc.Clusters[0].Cluster.Server) } } } else { - out.Delete("orchestrator") + meta.Delete("orchestrator") } if project, ok := m["project"].(map[string]interface{}); ok { @@ -118,10 +121,11 @@ var gceMetadataFetcher = provider{ "account": s.Object{ "id": c.Str("projectId"), }, - }.ApplyTo(out, project) + }.ApplyTo(cloud, project) } - return out + meta.DeepUpdate(common.MapStr{"cloud": cloud}) + return meta } fetcher, err := newMetadataFetcher(config, provider, gceHeaders, metadataHost, gceSchema, gceMetadataURI) diff --git a/libbeat/processors/add_cloud_metadata/provider_openstack_nova.go b/libbeat/processors/add_cloud_metadata/provider_openstack_nova.go index 01ada43cfb3..9922e853d2e 100644 --- a/libbeat/processors/add_cloud_metadata/provider_openstack_nova.go +++ b/libbeat/processors/add_cloud_metadata/provider_openstack_nova.go @@ -49,7 +49,7 @@ func buildOpenstackNovaCreate(scheme string) func(provider string, c *common.Con m["service"] = common.MapStr{ "name": "Nova", } - return common.MapStr(m) + return common.MapStr{"cloud": m} } urls, err := getMetadataURLsWithScheme(c, scheme, metadataHost, []string{ diff --git a/libbeat/processors/add_cloud_metadata/provider_tencent_cloud.go b/libbeat/processors/add_cloud_metadata/provider_tencent_cloud.go index 0f09f4944ae..f562e2e9609 100644 --- a/libbeat/processors/add_cloud_metadata/provider_tencent_cloud.go +++ b/libbeat/processors/add_cloud_metadata/provider_tencent_cloud.go @@ -36,7 +36,7 @@ var qcloudMetadataFetcher = provider{ m["service"] = common.MapStr{ "name": "CVM", } - return common.MapStr(m) + return common.MapStr{"cloud": m} } urls, err := getMetadataURLs(c, qcloudMetadataHost, []string{ From 77eb466253bd90103b62b8e3d8c7f50e6b1abce8 Mon Sep 17 00:00:00 2001 From: Mario Castro Date: Tue, 29 Jun 2021 13:13:19 +0200 Subject: [PATCH 05/25] [Metricbeat] Add Couchbase's Sync Gateway module (#25599) --- metricbeat/docs/fields.asciidoc | 1205 ++++++++++++++++ metricbeat/docs/modules/syncgateway.asciidoc | 57 + .../docs/modules/syncgateway/db.asciidoc | 25 + .../docs/modules/syncgateway/memory.asciidoc | 24 + .../modules/syncgateway/replication.asciidoc | 18 + .../modules/syncgateway/resources.asciidoc | 25 + metricbeat/docs/modules_list.asciidoc | 6 + x-pack/metricbeat/include/list.go | 5 + x-pack/metricbeat/metricbeat.reference.yml | 12 + .../module/syncgateway/_meta/config.yml | 10 + .../module/syncgateway/_meta/docs.asciidoc | 3 + .../module/syncgateway/_meta/fields.yml | 10 + .../syncgateway/_meta/testdata/config.json | 76 + .../_meta/testdata/expvar.282c.json | 1224 +++++++++++++++++ .../module/syncgateway/db/_meta/data.json | 206 +++ .../module/syncgateway/db/_meta/docs.asciidoc | 1 + .../module/syncgateway/db/_meta/fields.yml | 380 +++++ .../metricbeat/module/syncgateway/db/data.go | 200 +++ .../module/syncgateway/db/data_test.go | 44 + x-pack/metricbeat/module/syncgateway/db/db.go | 75 + x-pack/metricbeat/module/syncgateway/doc.go | 5 + .../metricbeat/module/syncgateway/fields.go | 23 + .../module/syncgateway/memory/_meta/data.json | 49 + .../syncgateway/memory/_meta/docs.asciidoc | 1 + .../syncgateway/memory/_meta/fields.yml | 64 + .../module/syncgateway/memory/data.go | 20 + .../module/syncgateway/memory/data_test.go | 45 + .../module/syncgateway/memory/memory.go | 74 + .../replication/_meta/docs.asciidoc | 1 + .../syncgateway/replication/_meta/fields.yml | 40 + .../module/syncgateway/replication/data.go | 41 + .../syncgateway/replication/data_test.go | 43 + .../syncgateway/replication/replication.go | 74 + .../syncgateway/resources/_meta/data.json | 57 + .../syncgateway/resources/_meta/docs.asciidoc | 1 + .../syncgateway/resources/_meta/fields.yml | 71 + .../module/syncgateway/resources/data.go | 51 + .../module/syncgateway/resources/data_test.go | 43 + .../module/syncgateway/resources/resources.go | 75 + .../metricbeat/module/syncgateway/response.go | 21 + .../module/syncgateway/syncgateway.go | 87 ++ .../metricbeat/module/syncgateway/testing.go | 33 + .../modules.d/syncgateway.yml.disabled | 13 + 43 files changed, 4538 insertions(+) create mode 100644 metricbeat/docs/modules/syncgateway.asciidoc create mode 100644 metricbeat/docs/modules/syncgateway/db.asciidoc create mode 100644 metricbeat/docs/modules/syncgateway/memory.asciidoc create mode 100644 metricbeat/docs/modules/syncgateway/replication.asciidoc create mode 100644 metricbeat/docs/modules/syncgateway/resources.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/_meta/config.yml create mode 100644 x-pack/metricbeat/module/syncgateway/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/syncgateway/_meta/testdata/config.json create mode 100644 x-pack/metricbeat/module/syncgateway/_meta/testdata/expvar.282c.json create mode 100644 x-pack/metricbeat/module/syncgateway/db/_meta/data.json create mode 100644 x-pack/metricbeat/module/syncgateway/db/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/db/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/syncgateway/db/data.go create mode 100644 x-pack/metricbeat/module/syncgateway/db/data_test.go create mode 100644 x-pack/metricbeat/module/syncgateway/db/db.go create mode 100644 x-pack/metricbeat/module/syncgateway/doc.go create mode 100644 x-pack/metricbeat/module/syncgateway/fields.go create mode 100644 x-pack/metricbeat/module/syncgateway/memory/_meta/data.json create mode 100644 x-pack/metricbeat/module/syncgateway/memory/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/memory/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/syncgateway/memory/data.go create mode 100644 x-pack/metricbeat/module/syncgateway/memory/data_test.go create mode 100644 x-pack/metricbeat/module/syncgateway/memory/memory.go create mode 100644 x-pack/metricbeat/module/syncgateway/replication/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/replication/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/syncgateway/replication/data.go create mode 100644 x-pack/metricbeat/module/syncgateway/replication/data_test.go create mode 100644 x-pack/metricbeat/module/syncgateway/replication/replication.go create mode 100644 x-pack/metricbeat/module/syncgateway/resources/_meta/data.json create mode 100644 x-pack/metricbeat/module/syncgateway/resources/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/syncgateway/resources/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/syncgateway/resources/data.go create mode 100644 x-pack/metricbeat/module/syncgateway/resources/data_test.go create mode 100644 x-pack/metricbeat/module/syncgateway/resources/resources.go create mode 100644 x-pack/metricbeat/module/syncgateway/response.go create mode 100644 x-pack/metricbeat/module/syncgateway/syncgateway.go create mode 100644 x-pack/metricbeat/module/syncgateway/testing.go create mode 100644 x-pack/metricbeat/modules.d/syncgateway.yml.disabled diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 6accbbe91dd..6dda8fcef33 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -75,6 +75,7 @@ grouped in the following categories: * <> * <> * <> +* <> * <> * <> * <> @@ -49252,6 +49253,1210 @@ type: object -- +[[exported-fields-syncgateway]] +== SyncGateway fields + +SyncGateway metrics + + +[float] +=== syncgateway + +`syncgateway` contains the information and statistics from SyncGateway. + + + +[float] +=== syncgateway + +Couchbase Sync Gateway metrics. + + + +*`syncgateway.syncgateway.name`*:: ++ +-- +Name of the database on when field `couchbase.syncgateway.type` is `db_stats`. + + +type: keyword + +-- + +[float] +=== metrics + +Metrics of all databases contained in the config file of the SyncGateway instance. + + + + +*`syncgateway.syncgateway.metrics.docs.writes.conflict.count`*:: ++ +-- +type: long + +-- + +*`syncgateway.syncgateway.metrics.docs.writes.count`*:: ++ +-- +type: long + +-- + +*`syncgateway.syncgateway.metrics.docs.writes.bytes`*:: ++ +-- +type: long + +-- + + +*`syncgateway.syncgateway.metrics.replications.active`*:: ++ +-- +Number of active replications + +type: long + +-- + +*`syncgateway.syncgateway.metrics.replications.total`*:: ++ +-- +Total number of replications (active or not) + +type: long + +-- + + + + + +*`syncgateway.syncgateway.gsi.views.tombstones.query.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.tombstones.query.time`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.tombstones.query.error.count`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.access.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.access.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.access.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.channels.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.channels.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.channels.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.channels.star.query.time`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.channels.star.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.channels.star.query.error.count`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.role_access.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.role_access.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.role_access.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.sequences.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.sequences.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.sequences.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.all_docs.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.all_docs.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.all_docs.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.principals.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.principals.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.principals.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.resync.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.resync.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.resync.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.gsi.views.sessions.query.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.gsi.views.sessions.query.error.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.gsi.views.sessions.query.time`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.security.access_errors.count`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.security.auth.failed.count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.security.docs_rejected.count`*:: ++ +-- +type: double + +-- + + + + +*`syncgateway.syncgateway.cache.channel.revs.active`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cache.channel.revs.removal`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cache.channel.revs.tombstone`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cache.channel.hits`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cache.channel.misses`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cache.revs.hits`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cache.revs.misses`*:: ++ +-- +type: double + +-- + + + + +*`syncgateway.syncgateway.cbl.replication.pull.caught_up`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.since_zero`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.total.continuous`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.total.one_shot`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.active.continuous`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.active.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.active.one_shot`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.attachment.bytes`*:: ++ +-- +type: long + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.attachment.count`*:: ++ +-- +type: long + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.request_changes.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.request_changes.time`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.rev.processing_time`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.pull.rev.send.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.pull.rev.send.latency`*:: ++ +-- +type: double + +-- + + + +*`syncgateway.syncgateway.cbl.replication.push.attachment.bytes`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.push.attachment.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.push.doc_push_count`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.push.propose_change.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.push.propose_change.time`*:: ++ +-- +type: double + +-- + + +*`syncgateway.syncgateway.cbl.replication.push.sync_function.count`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.push.sync_function.time`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.cbl.replication.push.write_processing_time`*:: ++ +-- +type: double + +-- + +[float] +=== memstats + +Dumps a large amount of information about the memory heap and garbage collector + + +*`syncgateway.syncgateway.memstats.BuckHashSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.Mallocs`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.PauseTotalNs`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.TotalAlloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.Alloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.GCSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.LastGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.MSpanSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.GCCPUFraction`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.HeapReleased`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.HeapSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.DebugGC`*:: ++ +-- +type: long + +-- + +*`syncgateway.syncgateway.memstats.HeapIdle`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.Lookups`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.HeapObjects`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.MSpanInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.NumForcedGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.OtherSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.Frees`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.NextGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.StackInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.Sys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.NumGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.EnableGC`*:: ++ +-- +type: long + +-- + +*`syncgateway.syncgateway.memstats.HeapAlloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.MCacheInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.MCacheSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.HeapInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.syncgateway.memstats.StackSys`*:: ++ +-- +type: double + +-- + +[float] +=== memory + +SyncGateway memory metrics. It dumps a large amount of information about the memory heap and garbage collector + + + +*`syncgateway.memory.BuckHashSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.Mallocs`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.PauseTotalNs`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.TotalAlloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.Alloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.GCSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.LastGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.MSpanSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.GCCPUFraction`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.HeapReleased`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.HeapSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.DebugGC`*:: ++ +-- +type: long + +-- + +*`syncgateway.memory.HeapIdle`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.Lookups`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.HeapObjects`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.MSpanInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.NumForcedGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.OtherSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.Frees`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.NextGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.StackInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.Sys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.NumGC`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.EnableGC`*:: ++ +-- +type: long + +-- + +*`syncgateway.memory.HeapAlloc`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.MCacheInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.MCacheSys`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.HeapInuse`*:: ++ +-- +type: double + +-- + +*`syncgateway.memory.StackSys`*:: ++ +-- +type: double + +-- + +[float] +=== replication + +SyncGateway per replication metrics. + + + +[float] +=== metrics + +Metrics related with data replication. + + + + +*`syncgateway.replication.metrics.attachment.transferred.bytes`*:: ++ +-- +Number of attachment bytes transferred for this replica. + +type: long + +-- + +*`syncgateway.replication.metrics.attachment.transferred.count`*:: ++ +-- +The total number of attachments transferred since replication started. + +type: long + +-- + + +*`syncgateway.replication.metrics.docs.checked_sent`*:: ++ +-- +The total number of documents checked for changes since replication started. + +type: double + +-- + + +*`syncgateway.replication.metrics.docs.pushed.count`*:: ++ +-- +The total number of documents checked for changes since replication started. + +type: long + +-- + +*`syncgateway.replication.metrics.docs.pushed.failed`*:: ++ +-- +The total number of documents that failed to be pushed since replication started. + +type: long + +-- + +*`syncgateway.replication.id`*:: ++ +-- +ID of the replica. + +type: keyword + +-- + +[float] +=== resources + +SyncGateway global resource utilization + + + +*`syncgateway.resources.error_count`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.goroutines_high_watermark`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.num_goroutines`*:: ++ +-- +type: long + +-- + + +*`syncgateway.resources.process.cpu_percent_utilization`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.process.memory_resident`*:: ++ +-- +type: long + +-- + + + +*`syncgateway.resources.pub_net.recv.bytes`*:: ++ +-- +type: long + +-- + + +*`syncgateway.resources.pub_net.sent.bytes`*:: ++ +-- +type: long + +-- + + +*`syncgateway.resources.admin_net_bytes.recv`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.admin_net_bytes.sent`*:: ++ +-- +type: long + +-- + + + +*`syncgateway.resources.go_memstats.heap.alloc`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.go_memstats.heap.idle`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.go_memstats.heap.inuse`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.go_memstats.heap.released`*:: ++ +-- +type: long + +-- + + +*`syncgateway.resources.go_memstats.pause.ns`*:: ++ +-- +type: long + +-- + + +*`syncgateway.resources.go_memstats.stack.inuse`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.go_memstats.stack.sys`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.go_memstats.sys`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.system_memory_total`*:: ++ +-- +type: long + +-- + +*`syncgateway.resources.warn_count`*:: ++ +-- +type: long + +-- + [[exported-fields-system]] == System fields diff --git a/metricbeat/docs/modules/syncgateway.asciidoc b/metricbeat/docs/modules/syncgateway.asciidoc new file mode 100644 index 00000000000..a0688f60d22 --- /dev/null +++ b/metricbeat/docs/modules/syncgateway.asciidoc @@ -0,0 +1,57 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-module-syncgateway]] +[role="xpack"] +== SyncGateway module + +beta[] + +Sync Gateway is the synchronization server in a Couchbase for Mobile and Edge deployment. This metricset allows to monitor a Sync Gateway instance by using its REST API. + +Sync Gateway access `[host]:[port]/_expvar` on Sync Gateway nodes to fetch metrics data, ensure that the URL is accessible from the host where Metricbeat is running. + + +[float] +=== Example configuration + +The SyncGateway module supports the standard configuration options that are described +in <>. Here is an example configuration: + +[source,yaml] +---- +metricbeat.modules: +- module: syncgateway + metricsets: + - db +# - memory +# - replication +# - resources + period: 10s + + # SyncGateway hosts + hosts: ["127.0.0.1:4985"] +---- + +[float] +=== Metricsets + +The following metricsets are available: + +* <> + +* <> + +* <> + +* <> + +include::syncgateway/db.asciidoc[] + +include::syncgateway/memory.asciidoc[] + +include::syncgateway/replication.asciidoc[] + +include::syncgateway/resources.asciidoc[] + diff --git a/metricbeat/docs/modules/syncgateway/db.asciidoc b/metricbeat/docs/modules/syncgateway/db.asciidoc new file mode 100644 index 00000000000..4bc7a2964e7 --- /dev/null +++ b/metricbeat/docs/modules/syncgateway/db.asciidoc @@ -0,0 +1,25 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-syncgateway-db]] +[role="xpack"] +=== SyncGateway db metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/syncgateway/db/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/syncgateway/db/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules/syncgateway/memory.asciidoc b/metricbeat/docs/modules/syncgateway/memory.asciidoc new file mode 100644 index 00000000000..6ae4f0fedb6 --- /dev/null +++ b/metricbeat/docs/modules/syncgateway/memory.asciidoc @@ -0,0 +1,24 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-syncgateway-memory]] +[role="xpack"] +=== SyncGateway memory metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/syncgateway/memory/_meta/docs.asciidoc[] + + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/syncgateway/memory/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules/syncgateway/replication.asciidoc b/metricbeat/docs/modules/syncgateway/replication.asciidoc new file mode 100644 index 00000000000..0d73b130cfe --- /dev/null +++ b/metricbeat/docs/modules/syncgateway/replication.asciidoc @@ -0,0 +1,18 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-syncgateway-replication]] +[role="xpack"] +=== SyncGateway replication metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/syncgateway/replication/_meta/docs.asciidoc[] + + +==== Fields + +For a description of each field in the metricset, see the +<> section. + diff --git a/metricbeat/docs/modules/syncgateway/resources.asciidoc b/metricbeat/docs/modules/syncgateway/resources.asciidoc new file mode 100644 index 00000000000..1860fe19814 --- /dev/null +++ b/metricbeat/docs/modules/syncgateway/resources.asciidoc @@ -0,0 +1,25 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-syncgateway-resources]] +[role="xpack"] +=== SyncGateway resources metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/syncgateway/resources/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/syncgateway/resources/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index cd1e738c9e4..7917a95594c 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -254,6 +254,11 @@ This file is generated! See scripts/mage/docs_collector.go |<> |<> |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> +|<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | +.4+| .4+| |<> beta[] +|<> beta[] +|<> beta[] +|<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | .18+| .18+| |<> |<> @@ -350,6 +355,7 @@ include::modules/redisenterprise.asciidoc[] include::modules/sql.asciidoc[] include::modules/stan.asciidoc[] include::modules/statsd.asciidoc[] +include::modules/syncgateway.asciidoc[] include::modules/system.asciidoc[] include::modules/tomcat.asciidoc[] include::modules/traefik.asciidoc[] diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index 856c3357746..9b0f402423a 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -60,5 +60,10 @@ import ( _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/stan/subscriptions" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/statsd" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/statsd/server" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway/db" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway/memory" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway/replication" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway/resources" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/tomcat" ) diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 4bd416f7883..0a8bc00d276 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -1352,6 +1352,18 @@ metricbeat.modules: enabled: false #ttl: "30s" +#----------------------------- SyncGateway Module ----------------------------- +- module: syncgateway + metricsets: + - db +# - memory +# - replication +# - resources + period: 10s + + # SyncGateway hosts + hosts: ["127.0.0.1:4985"] + #-------------------------------- Tomcat Module -------------------------------- - module: tomcat metricsets: ['threading', 'cache', 'memory', 'requests'] diff --git a/x-pack/metricbeat/module/syncgateway/_meta/config.yml b/x-pack/metricbeat/module/syncgateway/_meta/config.yml new file mode 100644 index 00000000000..d47955d6da5 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/_meta/config.yml @@ -0,0 +1,10 @@ +- module: syncgateway + metricsets: + - db +# - memory +# - replication +# - resources + period: 10s + + # SyncGateway hosts + hosts: ["127.0.0.1:4985"] diff --git a/x-pack/metricbeat/module/syncgateway/_meta/docs.asciidoc b/x-pack/metricbeat/module/syncgateway/_meta/docs.asciidoc new file mode 100644 index 00000000000..ce6c60d0682 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/_meta/docs.asciidoc @@ -0,0 +1,3 @@ +Sync Gateway is the synchronization server in a Couchbase for Mobile and Edge deployment. This metricset allows to monitor a Sync Gateway instance by using its REST API. + +Sync Gateway access `[host]:[port]/_expvar` on Sync Gateway nodes to fetch metrics data, ensure that the URL is accessible from the host where Metricbeat is running. diff --git a/x-pack/metricbeat/module/syncgateway/_meta/fields.yml b/x-pack/metricbeat/module/syncgateway/_meta/fields.yml new file mode 100644 index 00000000000..1cba880d6d6 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/_meta/fields.yml @@ -0,0 +1,10 @@ +- key: syncgateway + title: "SyncGateway" + description: SyncGateway metrics + release: beta + fields: + - name: syncgateway + type: group + description: > + `syncgateway` contains the information and statistics from SyncGateway. + fields: diff --git a/x-pack/metricbeat/module/syncgateway/_meta/testdata/config.json b/x-pack/metricbeat/module/syncgateway/_meta/testdata/config.json new file mode 100644 index 00000000000..c118d4641fb --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/_meta/testdata/config.json @@ -0,0 +1,76 @@ +{ + "interface": ":4984", + "logging": { + "log_file_path": "/var/tmp/sglogs", + "console": { + "log_level": "debug", + "log_keys": [ + "*" + ] + }, + "error": { + "enabled": true, + "rotation": { + "max_size": 20, + "max_age": 180 + } + }, + "warn": { + "enabled": true, + "rotation": { + "max_size": 20, + "max_age": 90 + } + }, + "info": { + "enabled": false + }, + "debug": { + "enabled": false + } + }, + "databases": { + "beer-sample": { + "import_docs": "continuous", + "enable_shared_bucket_access": true, + "bucket": "beer-sample", + "server": "http://172.17.0.2:8091", + "username": "admin", + "password": "123456", + "num_index_replicas": 0, + "users": { + "GUEST": { + "disabled": true + }, + "admin": { + "password": "123456", + "admin_channels": [ + "*" + ] + } + }, + "revs_limit": 20 + }, + "travel-sample": { + "import_docs": "continuous", + "enable_shared_bucket_access": true, + "bucket": "travel-sample", + "server": "http://172.17.0.2:8091", + "username": "admin", + "password": "123456", + "num_index_replicas": 0, + "users": { + "GUEST": { + "disabled": true + }, + "admin": { + "password": "123456", + "admin_channels": [ + "*" + ] + } + }, + "revs_limit": 20 + } + } +} diff --git a/x-pack/metricbeat/module/syncgateway/_meta/testdata/expvar.282c.json b/x-pack/metricbeat/module/syncgateway/_meta/testdata/expvar.282c.json new file mode 100644 index 00000000000..8b1f71fde74 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/_meta/testdata/expvar.282c.json @@ -0,0 +1,1224 @@ +{ + "cb": { + "ops": {}, + "pools": {} + }, + "cmdline": [ + "sync_gateway", + "--defaultLogFilePath=/var/log/sync_gateway", + "-adminInterface", + ":4985", + "/etc/sync_gateway/sync_gateway.json" + ], + "goblip": {}, + "mc": { + "recv": { + "bytes": { + "0x1f": 1008, + "0x89": 864, + "SASL_AUTH": 864, + "SASL_LIST_MECHS": 2376, + "UPR_OPEN": 864, + "total": 5976 + }, + "errs": {}, + "ops": { + "0x1f": 36, + "0x89": 36, + "SASL_AUTH": 36, + "SASL_LIST_MECHS": 36, + "UPR_OPEN": 36, + "total": 180 + } + }, + "tap": { + "bytes": {}, + "errs": {}, + "ops": {} + }, + "xmit": { + "bytes": { + "0x1f": 3566, + "0x89": 1296, + "NOOP": 720, + "SASL_AUTH": 1512, + "SASL_LIST_MECHS": 864, + "UPR_BUFFERACK": 336, + "UPR_CONTROL": 4932, + "UPR_OPEN": 3170, + "UPR_STREAMREQ": 294912, + "total": 311308 + }, + "errs": {}, + "ops": { + "0x1f": 36, + "0x89": 36, + "NOOP": 30, + "SASL_AUTH": 36, + "SASL_LIST_MECHS": 36, + "UPR_BUFFERACK": 12, + "UPR_CONTROL": 108, + "UPR_OPEN": 36, + "UPR_STREAMREQ": 4096, + "total": 4426 + } + } + }, + "memstats": { + "Alloc": 159398816, + "TotalAlloc": 2719416432, + "Sys": 357708024, + "Lookups": 0, + "Mallocs": 57667615, + "Frees": 55790048, + "HeapAlloc": 159398816, + "HeapSys": 332169216, + "HeapIdle": 67780608, + "HeapInuse": 264388608, + "HeapReleased": 26927104, + "HeapObjects": 1877567, + "StackInuse": 3375104, + "StackSys": 3375104, + "MSpanInuse": 4030632, + "MSpanSys": 4358144, + "MCacheInuse": 20832, + "MCacheSys": 32768, + "BuckHashSys": 1759627, + "GCSys": 13555712, + "OtherSys": 2457453, + "NextGC": 265304208, + "LastGC": 1620310398040906500, + "PauseTotalNs": 88693194, + "PauseNs": [ + 67131, + 17720, + 49699, + 15125, + 26870, + 11396, + 17540, + 28606, + 64253, + 95491, + 26325, + 18928, + 255476, + 622721, + 378524, + 7860579, + 2189850, + 312269, + 160370, + 1127927, + 226473, + 714888, + 399169, + 3320206, + 7245241, + 2639040, + 1084283, + 3470662, + 975960, + 952710, + 166017, + 733559, + 6388460, + 276382, + 4632588, + 640706, + 146091, + 195839, + 4782434, + 79438, + 559445, + 1344800, + 9485458, + 2707508, + 1547026, + 220774, + 2629126, + 9999615, + 226927, + 7472682, + 82887, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PauseEnd": [ + 1620310338920958200, + 1620310351426572000, + 1620310352681769500, + 1620310352686500000, + 1620310352693075200, + 1620310352700478000, + 1620310352745081600, + 1620310352759565600, + 1620310352763341800, + 1620310352767747600, + 1620310352793954800, + 1620310352846218000, + 1620310352905687000, + 1620310352982015700, + 1620310353051933000, + 1620310353138877000, + 1620310353255282200, + 1620310353399916800, + 1620310353720879600, + 1620310354061829600, + 1620310354374070800, + 1620310354696978400, + 1620310355152804000, + 1620310355628574500, + 1620310356137813000, + 1620310356627671300, + 1620310357016540400, + 1620310374534675200, + 1620310374809924900, + 1620310375047449300, + 1620310375474444000, + 1620310375924982000, + 1620310376440657000, + 1620310377146911000, + 1620310377906382000, + 1620310378854651000, + 1620310379714263000, + 1620310380508387800, + 1620310381220176100, + 1620310382398691600, + 1620310383426419200, + 1620310384538631700, + 1620310385624432000, + 1620310387400379100, + 1620310388572275200, + 1620310389941691000, + 1620310391488313600, + 1620310393008522000, + 1620310394713452500, + 1620310396453674500, + 1620310398040906500, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "NumGC": 51, + "NumForcedGC": 0, + "GCCPUFraction": 0.008328526565497294, + "EnableGC": true, + "DebugGC": false, + "BySize": [ + { + "Size": 0, + "Mallocs": 0, + "Frees": 0 + }, + { + "Size": 8, + "Mallocs": 901392, + "Frees": 896474 + }, + { + "Size": 16, + "Mallocs": 29531337, + "Frees": 28456937 + }, + { + "Size": 32, + "Mallocs": 6033284, + "Frees": 5643846 + }, + { + "Size": 48, + "Mallocs": 3201493, + "Frees": 3012460 + }, + { + "Size": 64, + "Mallocs": 797155, + "Frees": 786367 + }, + { + "Size": 80, + "Mallocs": 544250, + "Frees": 538869 + }, + { + "Size": 96, + "Mallocs": 712994, + "Frees": 706044 + }, + { + "Size": 112, + "Mallocs": 300043, + "Frees": 296594 + }, + { + "Size": 128, + "Mallocs": 454667, + "Frees": 453674 + }, + { + "Size": 144, + "Mallocs": 258222, + "Frees": 257167 + }, + { + "Size": 160, + "Mallocs": 197323, + "Frees": 185378 + }, + { + "Size": 176, + "Mallocs": 118510, + "Frees": 117754 + }, + { + "Size": 192, + "Mallocs": 44105, + "Frees": 43694 + }, + { + "Size": 208, + "Mallocs": 130830, + "Frees": 129313 + }, + { + "Size": 224, + "Mallocs": 42617, + "Frees": 42049 + }, + { + "Size": 240, + "Mallocs": 89888, + "Frees": 89150 + }, + { + "Size": 256, + "Mallocs": 300134, + "Frees": 297243 + }, + { + "Size": 288, + "Mallocs": 1747420, + "Frees": 1617371 + }, + { + "Size": 320, + "Mallocs": 4829, + "Frees": 3282 + }, + { + "Size": 352, + "Mallocs": 83681, + "Frees": 82264 + }, + { + "Size": 384, + "Mallocs": 3024, + "Frees": 2009 + }, + { + "Size": 416, + "Mallocs": 2534, + "Frees": 2134 + }, + { + "Size": 448, + "Mallocs": 2288, + "Frees": 1784 + }, + { + "Size": 480, + "Mallocs": 2686, + "Frees": 2434 + }, + { + "Size": 512, + "Mallocs": 277265, + "Frees": 272027 + }, + { + "Size": 576, + "Mallocs": 164320, + "Frees": 152902 + }, + { + "Size": 640, + "Mallocs": 14575, + "Frees": 14272 + }, + { + "Size": 704, + "Mallocs": 8716, + "Frees": 8364 + }, + { + "Size": 768, + "Mallocs": 5289, + "Frees": 5072 + }, + { + "Size": 896, + "Mallocs": 15547, + "Frees": 14356 + }, + { + "Size": 1024, + "Mallocs": 73044, + "Frees": 69817 + }, + { + "Size": 1152, + "Mallocs": 73955, + "Frees": 72310 + }, + { + "Size": 1280, + "Mallocs": 62537, + "Frees": 60565 + }, + { + "Size": 1408, + "Mallocs": 37251, + "Frees": 35700 + }, + { + "Size": 1536, + "Mallocs": 33999, + "Frees": 33097 + }, + { + "Size": 1792, + "Mallocs": 45383, + "Frees": 44658 + }, + { + "Size": 2048, + "Mallocs": 3753, + "Frees": 3688 + }, + { + "Size": 2304, + "Mallocs": 12732, + "Frees": 7985 + }, + { + "Size": 2688, + "Mallocs": 838, + "Frees": 761 + }, + { + "Size": 3072, + "Mallocs": 2908, + "Frees": 2903 + }, + { + "Size": 3200, + "Mallocs": 146, + "Frees": 143 + }, + { + "Size": 3456, + "Mallocs": 567, + "Frees": 492 + }, + { + "Size": 4096, + "Mallocs": 2241, + "Frees": 2136 + }, + { + "Size": 4864, + "Mallocs": 481, + "Frees": 432 + }, + { + "Size": 5376, + "Mallocs": 1494, + "Frees": 1410 + }, + { + "Size": 6144, + "Mallocs": 448, + "Frees": 440 + }, + { + "Size": 6528, + "Mallocs": 161, + "Frees": 158 + }, + { + "Size": 6784, + "Mallocs": 778, + "Frees": 778 + }, + { + "Size": 6912, + "Mallocs": 86, + "Frees": 83 + }, + { + "Size": 8192, + "Mallocs": 1377, + "Frees": 981 + }, + { + "Size": 9472, + "Mallocs": 995, + "Frees": 981 + }, + { + "Size": 9728, + "Mallocs": 2122, + "Frees": 72 + }, + { + "Size": 10240, + "Mallocs": 132, + "Frees": 130 + }, + { + "Size": 10880, + "Mallocs": 137, + "Frees": 137 + }, + { + "Size": 12288, + "Mallocs": 704, + "Frees": 629 + }, + { + "Size": 13568, + "Mallocs": 156, + "Frees": 147 + }, + { + "Size": 14336, + "Mallocs": 62, + "Frees": 60 + }, + { + "Size": 16384, + "Mallocs": 279, + "Frees": 264 + }, + { + "Size": 18432, + "Mallocs": 489, + "Frees": 222 + }, + { + "Size": 19072, + "Mallocs": 15, + "Frees": 15 + } + ] + }, + "syncGateway_changeCache": { + "maxPending": 0 + }, + "syncgateway": { + "global": { + "resource_utilization": { + "admin_net_bytes_recv": 186313933, + "admin_net_bytes_sent": 67278955, + "error_count": 0, + "go_memstats_heapalloc": 143386592, + "go_memstats_heapidle": 81616896, + "go_memstats_heapinuse": 250585088, + "go_memstats_heapreleased": 26927104, + "go_memstats_pausetotalns": 88693194, + "go_memstats_stackinuse": 3342336, + "go_memstats_stacksys": 3342336, + "go_memstats_sys": 357708024, + "goroutines_high_watermark": 311, + "num_goroutines": 308, + "process_cpu_percent_utilization": 0.48708528167446, + "process_memory_resident": 335306752, + "pub_net_bytes_recv": 186313933, + "pub_net_bytes_sent": 67278955, + "system_memory_total": 33291907072, + "warn_count": 6 + } + }, + "per_db": { + "beer-sample": { + "cache": { + "abandoned_seqs": 0, + "chan_cache_active_revs": 0, + "chan_cache_bypass_count": 0, + "chan_cache_channels_added": 0, + "chan_cache_channels_evicted_inactive": 0, + "chan_cache_channels_evicted_nru": 0, + "chan_cache_compact_count": 0, + "chan_cache_compact_time": 0, + "chan_cache_hits": 0, + "chan_cache_max_entries": 0, + "chan_cache_misses": 0, + "chan_cache_num_channels": 0, + "chan_cache_pending_queries": 0, + "chan_cache_removal_revs": 0, + "chan_cache_tombstone_revs": 0, + "high_seq_cached": 7304, + "high_seq_stable": 7305, + "num_active_channels": 0, + "num_skipped_seqs": 0, + "pending_seq_len": 0, + "rev_cache_bypass": 0, + "rev_cache_hits": 0, + "rev_cache_misses": 0, + "skipped_seq_len": 0 + }, + "cbl_replication_pull": { + "attachment_pull_bytes": 0, + "attachment_pull_count": 0, + "max_pending": 222, + "num_replications_active": 0, + "num_pull_repl_active_continuous": 0, + "num_pull_repl_active_one_shot": 0, + "num_pull_repl_caught_up": 0, + "num_pull_repl_since_zero": 0, + "num_pull_repl_total_continuous": 0, + "num_pull_repl_total_one_shot": 0, + "request_changes_count": 0, + "request_changes_time": 0, + "rev_processing_time": 0, + "rev_send_count": 0, + "rev_send_latency": 0 + }, + "cbl_replication_push": { + "attachment_push_bytes": 0, + "attachment_push_count": 0, + "doc_push_count": 0, + "propose_change_count": 0, + "propose_change_time": 0, + "sync_function_count": 0, + "sync_function_time": 0, + "write_processing_time": 0 + }, + "database": { + "abandoned_seqs": 0, + "conflict_write_count": 0, + "crc32c_match_count": 0, + "dcp_caching_count": 7303, + "dcp_caching_time": 47545220448, + "dcp_received_count": 7303, + "dcp_received_time": 71654930936, + "doc_reads_bytes_blip": 0, + "doc_writes_bytes": 2542924, + "doc_writes_bytes_blip": 0, + "doc_writes_xattr_bytes": 1822707, + "high_seq_feed": 14610, + "num_doc_reads_blip": 0, + "num_doc_reads_rest": 0, + "num_doc_writes": 7303, + "num_replications_active": 0, + "num_replications_total": 0, + "num_tombstones_compacted": 0, + "sequence_assigned_count": 7304, + "sequence_get_count": 2, + "sequence_incr_count": 733, + "sequence_released_count": 1, + "sequence_reserved_count": 7305, + "warn_channels_per_doc_count": 0, + "warn_grants_per_doc_count": 0, + "warn_xattr_size_count": 0, + "cache_feed": {}, + "import_feed": {} + }, + "gsi_views": { + "access_query_count": 1, + "access_query_error_count": 0, + "access_query_time": 214030402, + "allDocs_query_count": 0, + "allDocs_query_error_count": 0, + "allDocs_query_time": 0, + "channelsStar_query_count": 0, + "channelsStar_query_error_count": 0, + "channelsStar_query_time": 0, + "channels_query_count": 0, + "channels_query_error_count": 0, + "channels_query_time": 0, + "principals_query_count": 0, + "principals_query_error_count": 0, + "principals_query_time": 0, + "resync_query_count": 0, + "resync_query_error_count": 0, + "resync_query_time": 0, + "roleAccess_query_count": 1, + "roleAccess_query_error_count": 0, + "roleAccess_query_time": 197753953, + "sequences_query_count": 0, + "sequences_query_error_count": 0, + "sequences_query_time": 0, + "sessions_query_count": 0, + "sessions_query_error_count": 0, + "sessions_query_time": 0, + "tombstones_query_count": 0, + "tombstones_query_error_count": 0, + "tombstones_query_time": 0 + }, + "security": { + "auth_failed_count": 0, + "auth_success_count": 0, + "num_access_errors": 0, + "num_docs_rejected": 0, + "total_auth_time": 0 + }, + "shared_bucket_import": { + "import_count": 7303, + "import_cancel_cas": 0, + "import_error_count": 0, + "import_processing_time": 58213371539, + "import_high_seq": 7304, + "import_partitions": 16 + } + }, + "travel-sample": { + "cache": { + "abandoned_seqs": 0, + "chan_cache_active_revs": 0, + "chan_cache_bypass_count": 0, + "chan_cache_channels_added": 0, + "chan_cache_channels_evicted_inactive": 0, + "chan_cache_channels_evicted_nru": 0, + "chan_cache_compact_count": 0, + "chan_cache_compact_time": 0, + "chan_cache_hits": 0, + "chan_cache_max_entries": 0, + "chan_cache_misses": 0, + "chan_cache_num_channels": 0, + "chan_cache_pending_queries": 0, + "chan_cache_removal_revs": 0, + "chan_cache_tombstone_revs": 0, + "high_seq_cached": 31592, + "high_seq_stable": 31595, + "num_active_channels": 0, + "num_skipped_seqs": 0, + "pending_seq_len": 0, + "rev_cache_bypass": 0, + "rev_cache_hits": 0, + "rev_cache_misses": 0, + "skipped_seq_len": 0 + }, + "cbl_replication_pull": { + "attachment_pull_bytes": 0, + "attachment_pull_count": 0, + "max_pending": 260, + "num_replications_active": 0, + "num_pull_repl_active_continuous": 0, + "num_pull_repl_active_one_shot": 0, + "num_pull_repl_caught_up": 0, + "num_pull_repl_since_zero": 0, + "num_pull_repl_total_continuous": 0, + "num_pull_repl_total_one_shot": 0, + "request_changes_count": 0, + "request_changes_time": 0, + "rev_processing_time": 0, + "rev_send_count": 0, + "rev_send_latency": 0 + }, + "cbl_replication_push": { + "attachment_push_bytes": 0, + "attachment_push_count": 0, + "doc_push_count": 0, + "propose_change_count": 0, + "propose_change_time": 0, + "sync_function_count": 0, + "sync_function_time": 0, + "write_processing_time": 0 + }, + "database": { + "abandoned_seqs": 0, + "conflict_write_count": 0, + "crc32c_match_count": 0, + "dcp_caching_count": 31591, + "dcp_caching_time": 157384807512, + "dcp_received_count": 31591, + "dcp_received_time": 292348176079, + "doc_reads_bytes_blip": 0, + "doc_writes_bytes": 36196306, + "doc_writes_bytes_blip": 0, + "doc_writes_xattr_bytes": 7935238, + "high_seq_feed": 63187, + "num_doc_reads_blip": 0, + "num_doc_reads_rest": 0, + "num_doc_writes": 31591, + "num_replications_active": 0, + "num_replications_total": 0, + "num_tombstones_compacted": 0, + "sequence_assigned_count": 31592, + "sequence_get_count": 2, + "sequence_incr_count": 3162, + "sequence_released_count": 3, + "sequence_reserved_count": 31595, + "warn_channels_per_doc_count": 0, + "warn_grants_per_doc_count": 0, + "warn_xattr_size_count": 0, + "cache_feed": {}, + "import_feed": {} + }, + "gsi_views": { + "access_query_count": 1, + "access_query_error_count": 0, + "access_query_time": 116702828, + "allDocs_query_count": 0, + "allDocs_query_error_count": 0, + "allDocs_query_time": 0, + "channelsStar_query_count": 0, + "channelsStar_query_error_count": 0, + "channelsStar_query_time": 0, + "channels_query_count": 0, + "channels_query_error_count": 0, + "channels_query_time": 0, + "principals_query_count": 0, + "principals_query_error_count": 0, + "principals_query_time": 0, + "resync_query_count": 0, + "resync_query_error_count": 0, + "resync_query_time": 0, + "roleAccess_query_count": 1, + "roleAccess_query_error_count": 0, + "roleAccess_query_time": 120046831, + "sequences_query_count": 0, + "sequences_query_error_count": 0, + "sequences_query_time": 0, + "sessions_query_count": 0, + "sessions_query_error_count": 0, + "sessions_query_time": 0, + "tombstones_query_count": 0, + "tombstones_query_error_count": 0, + "tombstones_query_time": 0 + }, + "security": { + "auth_failed_count": 0, + "auth_success_count": 0, + "num_access_errors": 0, + "num_docs_rejected": 0, + "total_auth_time": 0 + }, + "shared_bucket_import": { + "import_count": 31591, + "import_cancel_cas": 0, + "import_error_count": 0, + "import_processing_time": 345830590715, + "import_high_seq": 31592, + "import_partitions": 16 + } + } + }, + "per_replication": { + "rep1": { + "sgr_num_docs_pushed": 0, + "sgr_num_attachment_bytes_transferred": 0, + "sgr_num_attachments_transferred": 0, + "sgr_docs_checked_sent": 0, + "sgr_num_docs_failed_to_push": 0 + } + } + } +} diff --git a/x-pack/metricbeat/module/syncgateway/db/_meta/data.json b/x-pack/metricbeat/module/syncgateway/db/_meta/data.json new file mode 100644 index 00000000000..b9abb061064 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/_meta/data.json @@ -0,0 +1,206 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "syncgateway.db", + "duration": 115000, + "module": "syncgateway" + }, + "metricset": { + "name": "db", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:44949", + "type": "syncgateway" + }, + "syncgateway": { + "db": { + "cache": { + "channel": { + "hits": 0, + "misses": 0, + "revs": { + "active": 0, + "removal": 0, + "tombstone": 0 + } + }, + "revs": { + "hits": 0, + "misses": 0 + } + }, + "cbl": { + "replication": { + "pull": { + "active": { + "continuous": 0, + "count": 0, + "one_shot": 0 + }, + "attachment": { + "bytes": 0, + "count": 0 + }, + "caught_up": 0, + "request_changes": { + "count": 0, + "time": 0 + }, + "rev": { + "processing_time": 0, + "send": { + "count": 0, + "latency": 0 + } + }, + "since_zero": 0, + "total": { + "continuous": 0, + "one_shot": 0 + } + }, + "push": { + "attachment": { + "bytes": 0, + "count": 0 + }, + "doc_push_count": 0, + "propose_change": { + "count": 0, + "time": 0 + }, + "sync_function": { + "count": 0, + "time": 0 + }, + "write_processing_time": 0 + } + } + }, + "gsi": { + "views": { + "access": { + "query": { + "count": 1, + "error": { + "count": 0 + }, + "time": 214030402 + } + }, + "all_docs": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + }, + "channels": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + }, + "star": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + } + }, + "principals": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + }, + "resync": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + }, + "role_access": { + "query": { + "count": 1, + "error": { + "count": 0 + }, + "time": 197753953 + } + }, + "sequences": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + }, + "sessions": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + }, + "tombstones": { + "query": { + "count": 0, + "error": { + "count": 0 + }, + "time": 0 + } + } + } + }, + "metrics": { + "docs": { + "writes": { + "bytes": 2542924, + "conflict": { + "count": 0 + }, + "count": 7303 + } + }, + "replications": { + "active": 0, + "total": 0 + } + }, + "name": "beer-sample", + "security": { + "access_errors": { + "count": 0 + }, + "auth": { + "failed": { + "count": 0 + } + }, + "docs_rejected": { + "count": 0 + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/syncgateway/db/_meta/docs.asciidoc b/x-pack/metricbeat/module/syncgateway/db/_meta/docs.asciidoc new file mode 100644 index 00000000000..f3185e37d4d --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/_meta/docs.asciidoc @@ -0,0 +1 @@ +SyncGateway `db` metriset contains the most relevant information of the module about the db metrics diff --git a/x-pack/metricbeat/module/syncgateway/db/_meta/fields.yml b/x-pack/metricbeat/module/syncgateway/db/_meta/fields.yml new file mode 100644 index 00000000000..4d7d4393e19 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/_meta/fields.yml @@ -0,0 +1,380 @@ +- name: syncgateway + type: group + description: > + Couchbase Sync Gateway metrics. + release: beta + fields: + - name: name + type: keyword + description: > + Name of the database on when field `couchbase.syncgateway.type` is `db_stats`. + - name: metrics + type: group + description: Metrics of all databases contained in the config file of the SyncGateway instance. + fields: + - name: docs + type: group + fields: + - name: writes + type: group + fields: + - name: conflict.count + type: long + - name: count + type: long + - name: bytes + type: long + - name: replications + type: group + fields: + - name: active + type: long + description: Number of active replications + - name: total + type: long + description: Total number of replications (active or not) + - name: gsi + type: group + fields: + - name: views + type: group + fields: + - name: tombstones + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: error.count + type: double + - name: access + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: channels + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: star + type: group + fields: + - name: query + type: group + fields: + - name: time + type: double + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: role_access + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: sequences + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: all_docs + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: principals + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: resync + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: sessions + type: group + fields: + - name: query + type: group + fields: + - name: count + type: double + - name: error + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: security + type: group + fields: + - name: access_errors + type: group + fields: + - name: count + type: double + - name: auth + type: group + fields: + - name: failed + type: group + fields: + - name: count + type: double + - name: docs_rejected + type: group + fields: + - name: count + type: double + - name: cache + type: group + fields: + - name: channel + type: group + fields: + - name: revs + type: group + fields: + - name: active + type: double + - name: removal + type: double + - name: tombstone + type: double + - name: hits + type: double + - name: misses + type: double + - name: revs + type: group + fields: + - name: hits + type: double + - name: misses + type: double + - name: cbl + type: group + fields: + - name: replication + type: group + fields: + - name: pull + type: group + fields: + - name: caught_up + type: double + - name: since_zero + type: double + - name: total + type: group + fields: + - name: continuous + type: double + - name: one_shot + type: double + - name: active + type: group + fields: + - name: continuous + type: double + - name: count + type: double + - name: one_shot + type: double + - name: attachment + type: group + fields: + - name: bytes + type: long + - name: count + type: long + - name: request_changes + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: rev + type: group + fields: + - name: processing_time + type: double + - name: send + type: group + fields: + - name: count + type: double + - name: latency + type: double + - name: push + type: group + fields: + - name: attachment + type: group + fields: + - name: bytes + type: double + - name: count + type: double + - name: doc_push_count + type: double + - name: propose_change + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: sync_function + type: group + fields: + - name: count + type: double + - name: time + type: double + - name: write_processing_time + type: double + - name: memstats + type: group + description: Dumps a large amount of information about the memory heap and garbage collector + fields: + - name: BuckHashSys + type: double + - name: Mallocs + type: double + - name: PauseTotalNs + type: double + - name: TotalAlloc + type: double + - name: Alloc + type: double + - name: GCSys + type: double + - name: LastGC + type: double + - name: MSpanSys + type: double + - name: GCCPUFraction + type: double + - name: HeapReleased + type: double + - name: HeapSys + type: double + - name: DebugGC + type: long + - name: HeapIdle + type: double + - name: Lookups + type: double + - name: HeapObjects + type: double + - name: MSpanInuse + type: double + - name: NumForcedGC + type: double + - name: OtherSys + type: double + - name: Frees + type: double + - name: NextGC + type: double + - name: StackInuse + type: double + - name: Sys + type: double + - name: NumGC + type: double + - name: EnableGC + type: long + - name: HeapAlloc + type: double + - name: MCacheInuse + type: double + - name: MCacheSys + type: double + - name: HeapInuse + type: double + - name: StackSys + type: double diff --git a/x-pack/metricbeat/module/syncgateway/db/data.go b/x-pack/metricbeat/module/syncgateway/db/data.go new file mode 100644 index 00000000000..d8fb8669ffc --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/data.go @@ -0,0 +1,200 @@ +// 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 db + +import ( + s "github.com/elastic/beats/v7/libbeat/common/schema" + c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +type SgResponse struct { + SyncgatewayChangeCache struct { + MaxPending float64 `json:"maxPending"` + } `json:"syncGateway_changeCache"` + Syncgateway Syncgateway `json:"syncgateway"` + MemStats map[string]interface{} `json:"memstats"` +} + +type Syncgateway struct { + Global struct { + ResourceUtilization map[string]interface{} `json:"resource_utilization"` + } `json:"global"` + PerDb map[string]map[string]interface{} `json:"per_db"` + PerReplication map[string]map[string]interface{} `json:"per_replication"` +} + +var ( + dbSchema = s.Schema{ + "cache": c.Dict("cache", s.Schema{ + "channel": s.Object{ + "revs": s.Object{ + "active": c.Float("chan_cache_active_revs"), + "removal": c.Float("chan_cache_removal_revs"), + "tombstone": c.Float("chan_cache_tombstone_revs"), + }, + "hits": c.Float("chan_cache_hits"), + "misses": c.Float("chan_cache_misses"), + }, + "revs": s.Object{ + "hits": c.Float("rev_cache_hits"), + "misses": c.Float("rev_cache_misses"), + }, + }), + "metrics": c.Dict("database", s.Schema{ + "replications": s.Object{ + "active": c.Float("num_replications_active"), + "total": c.Float("num_replications_total"), + }, + "docs": s.Object{ + "writes": s.Object{ + "count": c.Float("num_doc_writes"), + "bytes": c.Float("doc_writes_bytes"), + "conflict": s.Object{"count": c.Float("conflict_write_count")}, + }, + }, + }), + "security": c.Dict("security", s.Schema{ + "auth": s.Object{ + "failed": s.Object{"count": c.Float("auth_failed_count")}, + }, + "access_errors": s.Object{"count": c.Float("num_access_errors")}, + "docs_rejected": s.Object{"count": c.Float("num_docs_rejected")}, + }), + "cbl": s.Object{ + "replication": s.Object{ + "pull": c.Dict("cbl_replication_pull", s.Schema{ + "attachment": s.Object{ + "bytes": c.Float("attachment_pull_bytes"), + "count": c.Float("attachment_pull_count"), + }, + "active": s.Object{ + "count": c.Float("num_replications_active"), + "continuous": c.Float("num_pull_repl_active_continuous"), + "one_shot": c.Float("num_pull_repl_active_one_shot"), + }, + "total": s.Object{ + "continuous": c.Float("num_pull_repl_total_continuous"), + "one_shot": c.Float("num_pull_repl_total_one_shot"), + }, + "caught_up": c.Float("num_pull_repl_caught_up"), + "since_zero": c.Float("num_pull_repl_since_zero"), + "request_changes": s.Object{ + "count": c.Float("request_changes_count"), + "time": c.Float("request_changes_time"), + }, + "rev": s.Object{ + "processing_time": c.Float("rev_processing_time"), + "send": s.Object{ + "count": c.Float("rev_send_count"), + "latency": c.Float("rev_send_latency"), + }, + }, + }), + "push": c.Dict("cbl_replication_push", s.Schema{ + "write_processing_time": c.Float("write_processing_time"), + "doc_push_count": c.Float("doc_push_count"), + "attachment": s.Object{ + "bytes": c.Float("attachment_push_bytes"), + "count": c.Float("attachment_push_count"), + }, + "propose_change": s.Object{ + "count": c.Float("propose_change_count"), + "time": c.Float("propose_change_time"), + }, + "sync_function": s.Object{ + "count": c.Float("sync_function_count"), + "time": c.Float("sync_function_time"), + }, + }), + }, + }, + "gsi": s.Object{ + "views": c.Dict("gsi_views", s.Schema{ + "access": s.Object{ + "query": s.Object{ + "count": c.Float("access_query_count"), + "error": s.Object{"count": c.Float("access_query_error_count")}, + "time": c.Float("access_query_time"), + }, + }, + "all_docs": s.Object{ + "query": s.Object{ + "count": c.Float("allDocs_query_count"), + "error": s.Object{"count": c.Float("allDocs_query_error_count")}, + "time": c.Float("allDocs_query_time"), + }, + }, + "channels": s.Object{ + "star": s.Object{ + "query": s.Object{ + "count": c.Float("channelsStar_query_count"), + "error": s.Object{"count": c.Float("channelsStar_query_error_count")}, + "time": c.Float("channelsStar_query_time"), + }, + }, + "query": s.Object{ + "count": c.Float("channels_query_count"), + "error": s.Object{"count": c.Float("channels_query_error_count")}, + "time": c.Float("channels_query_time"), + }, + }, + "principals": s.Object{ + "query": s.Object{ + "count": c.Float("principals_query_count"), + "error": s.Object{"count": c.Float("principals_query_error_count")}, + "time": c.Float("principals_query_time"), + }, + }, + "resync": s.Object{ + "query": s.Object{ + "count": c.Float("resync_query_count"), + "error": s.Object{"count": c.Float("resync_query_error_count")}, + "time": c.Float("resync_query_time"), + }, + }, + "role_access": s.Object{ + "query": s.Object{ + "count": c.Float("roleAccess_query_count"), + "error": s.Object{"count": c.Float("roleAccess_query_error_count")}, + "time": c.Float("roleAccess_query_time"), + }, + }, + "sequences": s.Object{ + "query": s.Object{ + "count": c.Float("sequences_query_count"), + "error": s.Object{"count": c.Float("sequences_query_error_count")}, + "time": c.Float("sequences_query_time"), + }, + }, + "sessions": s.Object{ + "query": s.Object{ + "count": c.Float("sessions_query_count"), + "error": s.Object{"count": c.Float("sessions_query_error_count")}, + "time": c.Float("sessions_query_time"), + }, + }, + "tombstones": s.Object{ + "query": s.Object{ + "count": c.Float("tombstones_query_count"), + "error": s.Object{"count": c.Float("tombstones_query_error_count")}, + "time": c.Float("tombstones_query_time"), + }, + }, + }), + }, + } +) + +func eventMapping(r mb.ReporterV2, content *syncgateway.SgResponse) { + for dbName, db := range content.Syncgateway.PerDb { + dbData, _ := dbSchema.Apply(db) + dbData.Put("name", dbName) + r.Event(mb.Event{ + MetricSetFields: dbData, + }) + } +} diff --git a/x-pack/metricbeat/module/syncgateway/db/data_test.go b/x-pack/metricbeat/module/syncgateway/db/data_test.go new file mode 100644 index 00000000000..847d2a62259 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/data_test.go @@ -0,0 +1,44 @@ +// 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 db + +import ( + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +func TestData(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + f := mbtest.NewReportingMetricSetV2Error(t, syncgateway.GetConfig([]string{"db"}, server.URL)) + if err := mbtest.WriteEventsReporterV2Error(f, t, ""); err != nil { + t.Fatal("write", err) + } +} + +func TestFetch(t *testing.T) { + t.Skip("Skipping test because it seems like 'TestMetricsetFieldsDocumented' function, used here in this test; has some kind of bug") + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + config := syncgateway.GetConfig([]string{"db"}, server.URL) + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} diff --git a/x-pack/metricbeat/module/syncgateway/db/db.go b/x-pack/metricbeat/module/syncgateway/db/db.go new file mode 100644 index 00000000000..eae750f9bad --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/db/db.go @@ -0,0 +1,75 @@ +// 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 db + +import ( + "fmt" + + "github.com/elastic/beats/v7/metricbeat/helper" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +const ( + defaultScheme = "http" + defaultPath = "/_expvar" +) + +var ( + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +// init registers the MetricSet with the central registry. +// The New method will be called after the setup of the module and before starting to fetch data +func init() { + mb.Registry.MustAddMetricSet("syncgateway", "db", New, + mb.WithHostParser(hostParser), + mb.DefaultMetricSet(), + ) +} + +// MetricSet type defines all fields of the MetricSet +type MetricSet struct { + mb.BaseMetricSet + http *helper.HTTP + mod syncgateway.Module +} + +// New create a new instance of the MetricSet +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + mod, ok := base.Module().(syncgateway.Module) + if !ok { + return nil, fmt.Errorf("error trying to type assert syncgateway.Module. Base module must be composed of syncgateway.Module") + } + + http, err := helper.NewHTTP(base) + if err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + http: http, + mod: mod, + }, nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// 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(reporter mb.ReporterV2) error { + response, err := m.mod.GetSyncgatewayResponse(m.http) + if err != nil { + return err + } + + eventMapping(reporter, response) + + return nil +} diff --git a/x-pack/metricbeat/module/syncgateway/doc.go b/x-pack/metricbeat/module/syncgateway/doc.go new file mode 100644 index 00000000000..2654d21ebd3 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/doc.go @@ -0,0 +1,5 @@ +// 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 syncgateway diff --git a/x-pack/metricbeat/module/syncgateway/fields.go b/x-pack/metricbeat/module/syncgateway/fields.go new file mode 100644 index 00000000000..365091180c4 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/fields.go @@ -0,0 +1,23 @@ +// 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. + +// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. + +package syncgateway + +import ( + "github.com/elastic/beats/v7/libbeat/asset" +) + +func init() { + if err := asset.SetFields("metricbeat", "syncgateway", asset.ModuleFieldsPri, AssetSyncgateway); err != nil { + panic(err) + } +} + +// AssetSyncgateway returns asset data. +// This is the base64 encoded gzipped contents of module/syncgateway. +func AssetSyncgateway() string { + return "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" +} diff --git a/x-pack/metricbeat/module/syncgateway/memory/_meta/data.json b/x-pack/metricbeat/module/syncgateway/memory/_meta/data.json new file mode 100644 index 00000000000..d10b990f967 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/_meta/data.json @@ -0,0 +1,49 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "syncgateway.memory", + "duration": 115000, + "module": "syncgateway" + }, + "metricset": { + "name": "memory", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:39195", + "type": "syncgateway" + }, + "syncgateway": { + "memory": { + "Alloc": 159398816, + "BuckHashSys": 1759627, + "DebugGC": false, + "EnableGC": true, + "Frees": 55790048, + "GCCPUFraction": 0.008328526565497294, + "GCSys": 13555712, + "HeapAlloc": 159398816, + "HeapIdle": 67780608, + "HeapInuse": 264388608, + "HeapObjects": 1877567, + "HeapReleased": 26927104, + "HeapSys": 332169216, + "LastGC": 1620310398040906500, + "Lookups": 0, + "MCacheInuse": 20832, + "MCacheSys": 32768, + "MSpanInuse": 4030632, + "MSpanSys": 4358144, + "Mallocs": 57667615, + "NextGC": 265304208, + "NumForcedGC": 0, + "NumGC": 51, + "OtherSys": 2457453, + "PauseTotalNs": 88693194, + "StackInuse": 3375104, + "StackSys": 3375104, + "Sys": 357708024, + "TotalAlloc": 2719416432 + } + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/syncgateway/memory/_meta/docs.asciidoc b/x-pack/metricbeat/module/syncgateway/memory/_meta/docs.asciidoc new file mode 100644 index 00000000000..69772dee2ca --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/_meta/docs.asciidoc @@ -0,0 +1 @@ +SyncGateway `memory` metriset contains detailed information about the memory usage of the SyncGateway Go's process. diff --git a/x-pack/metricbeat/module/syncgateway/memory/_meta/fields.yml b/x-pack/metricbeat/module/syncgateway/memory/_meta/fields.yml new file mode 100644 index 00000000000..824a590fbdb --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/_meta/fields.yml @@ -0,0 +1,64 @@ +- name: memory + type: group + description: > + SyncGateway memory metrics. It dumps a large amount of information about the memory heap and garbage collector + release: beta + fields: + - name: BuckHashSys + type: double + - name: Mallocs + type: double + - name: PauseTotalNs + type: double + - name: TotalAlloc + type: double + - name: Alloc + type: double + - name: GCSys + type: double + - name: LastGC + type: double + - name: MSpanSys + type: double + - name: GCCPUFraction + type: double + - name: HeapReleased + type: double + - name: HeapSys + type: double + - name: DebugGC + type: long + - name: HeapIdle + type: double + - name: Lookups + type: double + - name: HeapObjects + type: double + - name: MSpanInuse + type: double + - name: NumForcedGC + type: double + - name: OtherSys + type: double + - name: Frees + type: double + - name: NextGC + type: double + - name: StackInuse + type: double + - name: Sys + type: double + - name: NumGC + type: double + - name: EnableGC + type: long + - name: HeapAlloc + type: double + - name: MCacheInuse + type: double + - name: MCacheSys + type: double + - name: HeapInuse + type: double + - name: StackSys + type: double diff --git a/x-pack/metricbeat/module/syncgateway/memory/data.go b/x-pack/metricbeat/module/syncgateway/memory/data.go new file mode 100644 index 00000000000..b51f91f3006 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/data.go @@ -0,0 +1,20 @@ +// 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 memory + +import ( + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +func eventMapping(r mb.ReporterV2, content *syncgateway.SgResponse) { + delete(content.MemStats, "BySize") + delete(content.MemStats, "PauseNs") + delete(content.MemStats, "PauseEnd") + + r.Event(mb.Event{ + MetricSetFields: content.MemStats, + }) +} diff --git a/x-pack/metricbeat/module/syncgateway/memory/data_test.go b/x-pack/metricbeat/module/syncgateway/memory/data_test.go new file mode 100644 index 00000000000..ad6ab9d98ff --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/data_test.go @@ -0,0 +1,45 @@ +// 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 memory + +import ( + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +func TestData(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + config := syncgateway.GetConfig([]string{"memory"}, server.URL) + + f := mbtest.NewReportingMetricSetV2Error(t, config) + if err := mbtest.WriteEventsReporterV2Error(f, t, ""); err != nil { + t.Fatal("write", err) + } +} + +func TestFetch(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + config := syncgateway.GetConfig([]string{"memory"}, server.URL) + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} diff --git a/x-pack/metricbeat/module/syncgateway/memory/memory.go b/x-pack/metricbeat/module/syncgateway/memory/memory.go new file mode 100644 index 00000000000..0edc000d0f3 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/memory/memory.go @@ -0,0 +1,74 @@ +// 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 memory + +import ( + "fmt" + + "github.com/elastic/beats/v7/metricbeat/helper" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +const ( + defaultScheme = "http" + defaultPath = "/_expvar" +) + +var ( + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +// init registers the MetricSet with the central registry. +// The New method will be called after the setup of the module and before starting to fetch data +func init() { + mb.Registry.MustAddMetricSet("syncgateway", "memory", New, + mb.WithHostParser(hostParser), + ) +} + +// MetricSet type defines all fields of the MetricSet +type MetricSet struct { + mb.BaseMetricSet + http *helper.HTTP + mod syncgateway.Module +} + +// New create a new instance of the MetricSet +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + mod, ok := base.Module().(syncgateway.Module) + if !ok { + return nil, fmt.Errorf("error trying to type assert syncgateway.Module. Base module must be composed of syncgateway.Module") + } + + http, err := helper.NewHTTP(base) + if err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + http: http, + mod: mod, + }, nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// 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(reporter mb.ReporterV2) error { + response, err := m.mod.GetSyncgatewayResponse(m.http) + if err != nil { + return err + } + + eventMapping(reporter, response) + + return nil +} diff --git a/x-pack/metricbeat/module/syncgateway/replication/_meta/docs.asciidoc b/x-pack/metricbeat/module/syncgateway/replication/_meta/docs.asciidoc new file mode 100644 index 00000000000..691e7df6b77 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/replication/_meta/docs.asciidoc @@ -0,0 +1 @@ +SyncGateway `replication` metriset contains information about the replicas. Note that you won't see any data if you don't have any replicas configured on your Couchbase buckets. diff --git a/x-pack/metricbeat/module/syncgateway/replication/_meta/fields.yml b/x-pack/metricbeat/module/syncgateway/replication/_meta/fields.yml new file mode 100644 index 00000000000..79f4e909efb --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/replication/_meta/fields.yml @@ -0,0 +1,40 @@ +- name: replication + type: group + description: > + SyncGateway per replication metrics. + release: beta + fields: + - name: metrics + type: group + description: Metrics related with data replication. + fields: + - name: attachment + type: group + fields: + - name: transferred + type: group + fields: + - name: bytes + type: long + description: Number of attachment bytes transferred for this replica. + - name: count + type: long + description: The total number of attachments transferred since replication started. + - name: docs + type: group + fields: + - name: checked_sent + type: double + description: The total number of documents checked for changes since replication started. + - name: pushed + type: group + fields: + - name: count + type: long + description: The total number of documents checked for changes since replication started. + - name: failed + type: long + description: The total number of documents that failed to be pushed since replication started. + - name: id + type: keyword + description: ID of the replica. diff --git a/x-pack/metricbeat/module/syncgateway/replication/data.go b/x-pack/metricbeat/module/syncgateway/replication/data.go new file mode 100644 index 00000000000..55b68b7c213 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/replication/data.go @@ -0,0 +1,41 @@ +// 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 replication + +import ( + "github.com/elastic/beats/v7/libbeat/common" + s "github.com/elastic/beats/v7/libbeat/common/schema" + c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +var replicationSchema = s.Schema{ + "docs": s.Object{ + "pushed": s.Object{ + "count": c.Int("sgr_num_docs_pushed"), + "failed": c.Int("sgr_num_docs_failed_to_push"), + }, + "checked_sent": c.Int("sgr_docs_checked_sent"), + }, + "attachment": s.Object{ + "transferred": s.Object{ + "bytes": c.Int("sgr_num_attachment_bytes_transferred"), + "count": c.Int("sgr_num_attachments_transferred"), + }, + }, +} + +func eventMapping(r mb.ReporterV2, content *syncgateway.SgResponse) { + for replID, replData := range content.Syncgateway.PerReplication { + replData, _ := replicationSchema.Apply(replData) + r.Event(mb.Event{ + MetricSetFields: common.MapStr{ + "id": replID, + "metrics": replData, + }, + }) + } +} diff --git a/x-pack/metricbeat/module/syncgateway/replication/data_test.go b/x-pack/metricbeat/module/syncgateway/replication/data_test.go new file mode 100644 index 00000000000..a622bb656e3 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/replication/data_test.go @@ -0,0 +1,43 @@ +// 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 replication + +import ( + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +func TestData(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + f := mbtest.NewReportingMetricSetV2Error(t, syncgateway.GetConfig([]string{"replication"}, server.URL)) + if err := mbtest.WriteEventsReporterV2Error(f, t, ""); err != nil { + t.Fatal("write", err) + } +} + +func TestFetch(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + config := syncgateway.GetConfig([]string{"replication"}, server.URL) + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} diff --git a/x-pack/metricbeat/module/syncgateway/replication/replication.go b/x-pack/metricbeat/module/syncgateway/replication/replication.go new file mode 100644 index 00000000000..3ce9be66705 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/replication/replication.go @@ -0,0 +1,74 @@ +// 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 replication + +import ( + "fmt" + + "github.com/elastic/beats/v7/metricbeat/helper" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +const ( + defaultScheme = "http" + defaultPath = "/_expvar" +) + +var ( + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +// init registers the MetricSet with the central registry. +// The New method will be called after the setup of the module and before starting to fetch data +func init() { + mb.Registry.MustAddMetricSet("syncgateway", "replication", New, + mb.WithHostParser(hostParser), + ) +} + +// MetricSet type defines all fields of the MetricSet +type MetricSet struct { + mb.BaseMetricSet + http *helper.HTTP + mod syncgateway.Module +} + +// New create a new instance of the MetricSet +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + mod, ok := base.Module().(syncgateway.Module) + if !ok { + return nil, fmt.Errorf("error trying to type assert syncgateway.Module. Base module must be composed of syncgateway.Module") + } + + http, err := helper.NewHTTP(base) + if err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + http: http, + mod: mod, + }, nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// 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(reporter mb.ReporterV2) error { + response, err := m.mod.GetSyncgatewayResponse(m.http) + if err != nil { + return err + } + + eventMapping(reporter, response) + + return nil +} diff --git a/x-pack/metricbeat/module/syncgateway/resources/_meta/data.json b/x-pack/metricbeat/module/syncgateway/resources/_meta/data.json new file mode 100644 index 00000000000..d9968ce3523 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/_meta/data.json @@ -0,0 +1,57 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "syncgateway.resources", + "duration": 115000, + "module": "syncgateway" + }, + "metricset": { + "name": "resources", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:37571", + "type": "syncgateway" + }, + "syncgateway": { + "resources": { + "admin_net_bytes": { + "recv": 186313933, + "sent": 67278955 + }, + "error_count": 0, + "go_memstats": { + "heap": { + "alloc": 143386592, + "idle": 81616896, + "inuse": 250585088, + "released": 26927104 + }, + "pause": { + "ns": 88693194 + }, + "stack": { + "inuse": 3342336, + "sys": 3342336 + }, + "sys": 357708024 + }, + "goroutines_high_watermark": 311, + "num_goroutines": 308, + "process": { + "cpu_percent_utilization": 0, + "memory_resident": 335306752 + }, + "pub_net": { + "recv": { + "bytes": 186313933 + }, + "sent": { + "bytes": 67278955 + } + }, + "system_memory_total": 33291907072, + "warn_count": 6 + } + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/syncgateway/resources/_meta/docs.asciidoc b/x-pack/metricbeat/module/syncgateway/resources/_meta/docs.asciidoc new file mode 100644 index 00000000000..7f252b51dfd --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/_meta/docs.asciidoc @@ -0,0 +1 @@ +SyncGateway `resources` metriset contains about the global resource utilization of the SyncGateway instance. diff --git a/x-pack/metricbeat/module/syncgateway/resources/_meta/fields.yml b/x-pack/metricbeat/module/syncgateway/resources/_meta/fields.yml new file mode 100644 index 00000000000..0de117b6fc1 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/_meta/fields.yml @@ -0,0 +1,71 @@ +- name: resources + type: group + description: > + SyncGateway global resource utilization + release: beta + fields: + - name: error_count + type: long + - name: goroutines_high_watermark + type: long + - name: num_goroutines + type: long + - name: process + type: group + fields: + - name: cpu_percent_utilization + type: long + - name: memory_resident + type: long + - name: pub_net + type: group + fields: + - name: recv + type: group + fields: + - name: bytes + type: long + - name: sent + type: group + fields: + - name: bytes + type: long + - name: admin_net_bytes + type: group + fields: + - name: recv + type: long + - name: sent + type: long + - name: go_memstats + type: group + fields: + - name: heap + type: group + fields: + - name: alloc + type: long + - name: idle + type: long + - name: inuse + type: long + - name: released + type: long + - name: pause + type: group + fields: + - name: ns + type: long + - name: stack + type: group + fields: + - name: inuse + type: long + - name: sys + type: long + - name: sys + type: long + - name: system_memory_total + type: long + - name: warn_count + type: long diff --git a/x-pack/metricbeat/module/syncgateway/resources/data.go b/x-pack/metricbeat/module/syncgateway/resources/data.go new file mode 100644 index 00000000000..46fcd2781da --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/data.go @@ -0,0 +1,51 @@ +// 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 resources + +import ( + s "github.com/elastic/beats/v7/libbeat/common/schema" + c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +var globalSchema = s.Schema{ + "go_memstats": s.Object{ + "heap": s.Object{ + "alloc": c.Int("go_memstats_heapalloc"), + "idle": c.Int("go_memstats_heapidle"), + "inuse": c.Int("go_memstats_heapinuse"), + "released": c.Int("go_memstats_heapreleased"), + }, + "pause": s.Object{"ns": c.Int("go_memstats_pausetotalns")}, + "stack": s.Object{ + "inuse": c.Int("go_memstats_stackinuse"), + "sys": c.Int("go_memstats_stacksys"), + }, + "sys": c.Int("go_memstats_sys"), + }, + "admin_net_bytes": s.Object{ + "recv": c.Int("admin_net_bytes_recv"), + "sent": c.Int("admin_net_bytes_sent"), + }, + "error_count": c.Int("error_count"), + "goroutines_high_watermark": c.Int("goroutines_high_watermark"), + "num_goroutines": c.Int("num_goroutines"), + "process": s.Object{ + "cpu_percent_utilization": c.Int("process_cpu_percent_utilization"), + "memory_resident": c.Int("process_memory_resident"), + }, + "pub_net": s.Object{ + "recv": s.Object{"bytes": c.Int("pub_net_bytes_recv")}, + "sent": s.Object{"bytes": c.Int("pub_net_bytes_sent")}, + }, + "system_memory_total": c.Int("system_memory_total"), + "warn_count": c.Int("warn_count"), +} + +func eventMapping(r mb.ReporterV2, content *syncgateway.SgResponse) { + globalData, _ := globalSchema.Apply(content.Syncgateway.Global.ResourceUtilization) + r.Event(mb.Event{MetricSetFields: globalData}) +} diff --git a/x-pack/metricbeat/module/syncgateway/resources/data_test.go b/x-pack/metricbeat/module/syncgateway/resources/data_test.go new file mode 100644 index 00000000000..7c0824770f4 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/data_test.go @@ -0,0 +1,43 @@ +// 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 resources + +import ( + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +func TestData(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + f := mbtest.NewReportingMetricSetV2Error(t, syncgateway.GetConfig([]string{"resources"}, server.URL)) + if err := mbtest.WriteEventsReporterV2Error(f, t, ""); err != nil { + t.Fatal("write", err) + } +} + +func TestFetch(t *testing.T) { + mux := syncgateway.CreateTestMuxer() + server := httptest.NewServer(mux) + defer server.Close() + + config := syncgateway.GetConfig([]string{"resources"}, server.URL) + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} diff --git a/x-pack/metricbeat/module/syncgateway/resources/resources.go b/x-pack/metricbeat/module/syncgateway/resources/resources.go new file mode 100644 index 00000000000..2a4d8446ea7 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/resources/resources.go @@ -0,0 +1,75 @@ +// 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 resources + +import ( + "fmt" + + "github.com/elastic/beats/v7/metricbeat/helper" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/syncgateway" +) + +const ( + defaultScheme = "http" + defaultPath = "/_expvar" +) + +var ( + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +// init registers the MetricSet with the central registry. +// The New method will be called after the setup of the module and before starting to fetch data +func init() { + mb.Registry.MustAddMetricSet("syncgateway", "resources", New, + mb.WithHostParser(hostParser), + mb.DefaultMetricSet(), + ) +} + +// MetricSet type defines all fields of the MetricSet +type MetricSet struct { + mb.BaseMetricSet + http *helper.HTTP + mod syncgateway.Module +} + +// New create a new instance of the MetricSet +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + mod, ok := base.Module().(syncgateway.Module) + if !ok { + return nil, fmt.Errorf("error trying to type assert syncgateway.Module. Base module must be composed of syncgateway.Module") + } + + http, err := helper.NewHTTP(base) + if err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + http: http, + mod: mod, + }, nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// 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(reporter mb.ReporterV2) error { + response, err := m.mod.GetSyncgatewayResponse(m.http) + if err != nil { + return err + } + + eventMapping(reporter, response) + + return nil +} diff --git a/x-pack/metricbeat/module/syncgateway/response.go b/x-pack/metricbeat/module/syncgateway/response.go new file mode 100644 index 00000000000..a11b092f629 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/response.go @@ -0,0 +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 syncgateway + +type SgResponse struct { + SyncgatewayChangeCache struct { + MaxPending float64 `json:"maxPending"` + } `json:"syncGateway_changeCache"` + Syncgateway Syncgateway `json:"syncgateway"` + MemStats map[string]interface{} `json:"memstats"` +} + +type Syncgateway struct { + Global struct { + ResourceUtilization map[string]interface{} `json:"resource_utilization"` + } `json:"global"` + PerDb map[string]map[string]interface{} `json:"per_db"` + PerReplication map[string]map[string]interface{} `json:"per_replication"` +} diff --git a/x-pack/metricbeat/module/syncgateway/syncgateway.go b/x-pack/metricbeat/module/syncgateway/syncgateway.go new file mode 100644 index 00000000000..dfd2e16cb84 --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/syncgateway.go @@ -0,0 +1,87 @@ +// 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 syncgateway + +import ( + "encoding/json" + "sync" + "time" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/helper" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +func init() { + // Register the ModuleFactory function for the "kubernetes" module. + if err := mb.Registry.AddModule("syncgateway", ModuleBuilder()); err != nil { + panic(err) + } +} + +// FetchPeriodThreshold is the threshold to use when checking if the cluster state call in this cache should be +// fetched again. It's used as a percentage so 0.9 means that cache is invalidated if at least 90% of period time has +// passed. This small threshold is to avoid race conditions where one of the X number of calls that happen after each +// period do not fetch new data while other does, becoming unsync by [period] seconds. It does not fully solve the +// problem because the period waits aren't guaranteed but it should be mostly enough. +const FetchPeriodThreshold = 0.9 + +type Module interface { + mb.Module + GetSyncgatewayResponse(http *helper.HTTP) (*SgResponse, error) +} + +type exprVarCache struct { + lock sync.Mutex + lastFetchTimestamp time.Time + + cachedData SgResponse +} + +type module struct { + mb.BaseModule + + expvarCache *exprVarCache + cacheHash uint64 +} + +func ModuleBuilder() func(base mb.BaseModule) (mb.Module, error) { + expvarCache := &exprVarCache{} + + return func(base mb.BaseModule) (mb.Module, error) { + m := module{ + BaseModule: base, + expvarCache: expvarCache, + } + return &m, nil + } +} + +func (m *module) GetSyncgatewayResponse(http *helper.HTTP) (*SgResponse, error) { + m.expvarCache.lock.Lock() + defer m.expvarCache.lock.Unlock() + + elapsedFromLastFetch := time.Since(m.expvarCache.lastFetchTimestamp) + + //Check the lifetime of current response data + if elapsedFromLastFetch == 0 || elapsedFromLastFetch >= (time.Duration(float64(m.Config().Period)*FetchPeriodThreshold)) { + //Fetch data again + byt, err := http.FetchContent() + if err != nil { + return nil, err + } + + input := SgResponse{} + if err = json.Unmarshal(byt, &input); err != nil { + return nil, errors.Wrap(err, "error unmarshalling JSON of SyncGateway expvar response") + } + + m.expvarCache.cachedData = input + m.expvarCache.lastFetchTimestamp = time.Now() + } + + return &m.expvarCache.cachedData, nil +} diff --git a/x-pack/metricbeat/module/syncgateway/testing.go b/x-pack/metricbeat/module/syncgateway/testing.go new file mode 100644 index 00000000000..88c2d309c2a --- /dev/null +++ b/x-pack/metricbeat/module/syncgateway/testing.go @@ -0,0 +1,33 @@ +// 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 syncgateway + +import ( + "fmt" + "io/ioutil" + "net/http" +) + +func CreateTestMuxer() *http.ServeMux { + mux := http.NewServeMux() + + mux.Handle("/_expvar", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + input, _ := ioutil.ReadFile("../_meta/testdata/expvar.282c.json") + _, err := w.Write(input) + if err != nil { + fmt.Println("error writing response on mock server") + } + })) + + return mux +} + +func GetConfig(metricsets []string, host string) map[string]interface{} { + return map[string]interface{}{ + "module": "syncgateway", + "metricsets": metricsets, + "hosts": []string{host}, + } +} diff --git a/x-pack/metricbeat/modules.d/syncgateway.yml.disabled b/x-pack/metricbeat/modules.d/syncgateway.yml.disabled new file mode 100644 index 00000000000..54c42a11809 --- /dev/null +++ b/x-pack/metricbeat/modules.d/syncgateway.yml.disabled @@ -0,0 +1,13 @@ +# Module: syncgateway +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-syncgateway.html + +- module: syncgateway + metricsets: + - db +# - memory +# - replication +# - resources + period: 10s + + # SyncGateway hosts + hosts: ["127.0.0.1:4985"] From b061836bcebf7ae055b2184924f634fba1cf2232 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 29 Jun 2021 07:29:10 -0400 Subject: [PATCH 06/25] Logging code cleanup related to Nomad auto-discovery (#26498) * Logging and code cleanup related to Nomad auto-discover * Fix a few doc nits * Update heartbeat log line assertion * Add complete example with discovery and add_nomad_metadata * Fix secret_id and document minimal ACL policy Closes #26456 --- filebeat/autodiscover/builder/hints/logs.go | 39 ++++------ .../autodiscover/builder/hints/logs_test.go | 11 +-- filebeat/docs/autodiscover-hints.asciidoc | 77 ++++++++++++++++--- .../docs/autodiscover-nomad-config.asciidoc | 4 +- heartbeat/tests/system/test_autodiscovery.py | 2 +- libbeat/autodiscover/autodiscover.go | 2 +- libbeat/autodiscover/builder/helper.go | 26 ++++--- libbeat/autodiscover/builder/plugin.go | 2 +- libbeat/docs/shared-autodiscover.asciidoc | 17 +++- .../autodiscover/providers/nomad/config.go | 5 +- .../autodiscover/providers/nomad/nomad.go | 25 +++--- x-pack/libbeat/common/nomad/metadata.go | 6 +- x-pack/libbeat/common/nomad/watcher.go | 30 ++++---- .../docs/add_nomad_metadata.asciidoc | 16 +++- 14 files changed, 167 insertions(+), 95 deletions(-) diff --git a/filebeat/autodiscover/builder/hints/logs.go b/filebeat/autodiscover/builder/hints/logs.go index 037dd3f402e..4fb86cd9e18 100644 --- a/filebeat/autodiscover/builder/hints/logs.go +++ b/filebeat/autodiscover/builder/hints/logs.go @@ -52,15 +52,14 @@ var validModuleNames = regexp.MustCompile("[^a-zA-Z0-9\\_\\-]+") type logHints struct { config *config registry *fileset.ModuleRegistry + log *logp.Logger } // NewLogHints builds a log hints builder func NewLogHints(cfg *common.Config) (autodiscover.Builder, error) { config := defaultConfig() - err := cfg.Unpack(&config) - - if err != nil { - return nil, fmt.Errorf("unable to unpack hints config due to error: %v", err) + if err := cfg.Unpack(&config); err != nil { + return nil, fmt.Errorf("unable to unpack hints config due to error: %w", err) } moduleRegistry, err := fileset.NewModuleRegistry(nil, beat.Info{}, false) @@ -68,39 +67,33 @@ func NewLogHints(cfg *common.Config) (autodiscover.Builder, error) { return nil, err } - return &logHints{&config, moduleRegistry}, nil + return &logHints{&config, moduleRegistry, logp.NewLogger("hints.builder")}, nil } // Create config based on input hints in the bus event func (l *logHints) CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config { var hints common.MapStr - hIface, ok := event["hints"] - if ok { - hints, _ = hIface.(common.MapStr) - } - - inputConfig := l.getInputsConfigs(hints) - - // If default config is disabled return nothing unless it's explicty enabled - if !l.config.DefaultConfig.Enabled() && !builder.IsEnabled(hints, l.config.Key) { - logp.Debug("hints.builder", "default config is disabled: %+v", event) - return []*common.Config{} + if hintsIfc, found := event["hints"]; found { + hints, _ = hintsIfc.(common.MapStr) } - // If explictly disabled, return nothing - if builder.IsDisabled(hints, l.config.Key) { - logp.Debug("hints.builder", "logs disabled by hint: %+v", event) - return []*common.Config{} + // Hint must be explicitly enabled when default_config sets enabled=false. + if !l.config.DefaultConfig.Enabled() && !builder.IsEnabled(hints, l.config.Key) || + builder.IsDisabled(hints, l.config.Key) { + l.log.Debugw("Hints config is not enabled.", "autodiscover.event", event) + return nil } - if inputConfig != nil { - configs := []*common.Config{} + if inputConfig := l.getInputsConfigs(hints); inputConfig != nil { + var configs []*common.Config for _, cfg := range inputConfig { if config, err := common.NewConfigFrom(cfg); err == nil { configs = append(configs, config) + } else { + l.log.Warnw("Failed to create config from input.", "error", err) } } - logp.Debug("hints.builder", "generated config %+v", configs) + l.log.Debugf("Generated %d input configs from hint.", len(configs)) // Apply information in event to the template to generate the final config return template.ApplyConfigTemplate(event, configs) } diff --git a/filebeat/autodiscover/builder/hints/logs_test.go b/filebeat/autodiscover/builder/hints/logs_test.go index 0dadfe54798..e00ec39920e 100644 --- a/filebeat/autodiscover/builder/hints/logs_test.go +++ b/filebeat/autodiscover/builder/hints/logs_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/bus" @@ -692,9 +693,9 @@ func TestGenerateHints(t *testing.T) { for _, test := range tests { // Configure path for modules access abs, _ := filepath.Abs("../../..") - err := paths.InitPaths(&paths.Path{ + require.NoError(t, paths.InitPaths(&paths.Path{ Home: abs, - }) + })) l, err := NewLogHints(test.config) if err != nil { @@ -927,9 +928,9 @@ func TestGenerateHintsWithPaths(t *testing.T) { // Configure path for modules access abs, _ := filepath.Abs("../../..") - err := paths.InitPaths(&paths.Path{ + require.NoError(t, paths.InitPaths(&paths.Path{ Home: abs, - }) + })) l, err := NewLogHints(cfg) if err != nil { @@ -937,7 +938,7 @@ func TestGenerateHintsWithPaths(t *testing.T) { } cfgs := l.CreateConfig(test.event) - assert.Equal(t, test.len, len(cfgs), test.msg) + require.Equal(t, test.len, len(cfgs), test.msg) if test.len != 0 { config := common.MapStr{} err := cfgs[0].Unpack(&config) diff --git a/filebeat/docs/autodiscover-hints.asciidoc b/filebeat/docs/autodiscover-hints.asciidoc index b63fb6979bd..55b8f4adb5f 100644 --- a/filebeat/docs/autodiscover-hints.asciidoc +++ b/filebeat/docs/autodiscover-hints.asciidoc @@ -259,7 +259,9 @@ You can label Docker containers with useful info to decode logs structured as JS [float] ==== Nomad -Nomad autodiscover provider supports hints using the https://www.nomadproject.io/docs/job-specification/meta.html[`meta` stanza]. To enable it just set `hints.enabled`: +Nomad autodiscover provider supports hints using the +https://www.nomadproject.io/docs/job-specification/meta.html[`meta` stanza]. To +enable it just set `hints.enabled`: [source,yaml] ----- @@ -269,7 +271,8 @@ filebeat.autodiscover: hints.enabled: true ----- -You can configure the default config that will be launched when a new job is seen, like this: +You can configure the default config that will be launched when a new job is +seen, like this: [source,yaml] ----- @@ -278,13 +281,13 @@ filebeat.autodiscover: - type: nomad hints.enabled: true hints.default_config: - type: nomad + type: log paths: - - /var/lib/nomad/alloc/${data.nomad.allocation.id}/alloc/logs/${data.nomad.task.name}.* + - /opt/nomad/alloc/${data.nomad.allocation.id}/alloc/logs/${data.nomad.task.name}.* ----- -You can also disable default settings entirely, so only Jobs annotated like `co.elastic.logs/enabled: true` -will be retrieved: +You can also disable the default config such that only logs from jobs explicitly +annotated with `"co.elastic.logs/enabled" = "true"` will be collected: [source,yaml] ----- @@ -292,17 +295,67 @@ filebeat.autodiscover: providers: - type: nomad hints.enabled: true - hints.default_config.enabled: false + hints.default_config: + enabled: false + type: log + paths: + - /opt/nomad/alloc/${data.nomad.allocation.id}/alloc/logs/${data.nomad.task.name}.* ----- -You can annotate Nomad Jobs using the `meta` stanza with useful info to spin up {beatname_uc} inputs -or modules: +You can annotate Nomad Jobs using the `meta` stanza with useful info to spin up +{beatname_uc} inputs or modules: [source,hcl] ----- meta { - "co.elastic.logs/multiline.pattern" = "^\[" - "co.elastic.logs/multiline.negate" = true - "co.elastic.logs/multiline.match" = after + "co.elastic.logs/enabled" = "true" + "co.elastic.logs/multiline.pattern" = "^\\[" + "co.elastic.logs/multiline.negate" = "true" + "co.elastic.logs/multiline.match" = "after" } ----- + +If you are using autodiscover then in most cases you will want to use the +<> processor to enrich events with +Nomad metadata. This example configures {{beatname_uc}} to connect to the local +Nomad agent over HTTPS and adds the Nomad allocation ID to all events from the +input. Later in the pipeline the `add_nomad_metadata` processor will use that ID +to enrich the event. + +[source,yaml] +----- +filebeat.autodiscover: + providers: + - type: nomad + address: https://localhost:4646 + hints.enabled: true + hints.default_config: + enabled: false <1> + type: log + paths: + - /opt/nomad/alloc/${data.nomad.allocation.id}/alloc/logs/${data.nomad.task.name}.* + processors: + - add_fields: <2> + target: nomad + fields: + allocation.id: ${data.nomad.allocation.id} + +processors: + - add_nomad_metadata: <3> + when.has_fields.fields: [nomad.allocation.id] + address: https://localhost:4646 + default_indexers.enabled: false + default_matchers.enabled: false + indexers: + - allocation_uuid: + matchers: + - fields: + lookup_fields: + - 'nomad.allocation.id' +----- +<1> The default config is disabled meaning any task without the +`"co.elastic.logs/enabled" = "true"` metadata will be ignored. +<2> The `add_fields` processor populates the `nomad.allocation.id` field with +the Nomad allocation UUID. +<3> The `add_nomad_metadata` processor is configured at the global level so +that it is only instantiated one time which saves resources. diff --git a/filebeat/docs/autodiscover-nomad-config.asciidoc b/filebeat/docs/autodiscover-nomad-config.asciidoc index 2e72ae7fae7..b04255223ab 100644 --- a/filebeat/docs/autodiscover-nomad-config.asciidoc +++ b/filebeat/docs/autodiscover-nomad-config.asciidoc @@ -43,6 +43,6 @@ filebeat.autodiscover: - /var/lib/nomad/alloc/${data.nomad.allocation.id}/alloc/logs/${data.nomad.task.name}.* ------------------------------------------------------------------------------------- -WARNING: The `docker` input is currently not supported. Nomad doesn't expose the container id -associated with the allocation. Without the container id, there is no way of generating the proper +WARNING: The `docker` input is currently not supported. Nomad doesn't expose the container ID +associated with the allocation. Without the container ID, there is no way of generating the proper path for reading the container's logs. diff --git a/heartbeat/tests/system/test_autodiscovery.py b/heartbeat/tests/system/test_autodiscovery.py index 7f5060ace81..cbc1b679981 100644 --- a/heartbeat/tests/system/test_autodiscovery.py +++ b/heartbeat/tests/system/test_autodiscovery.py @@ -40,7 +40,7 @@ def test_docker(self): proc = self.start_beat() self.wait_until(lambda: self.log_contains( - re.compile('autodiscover.+Got a start event:', re.I))) + re.compile('autodiscover.+Got a start event', re.I))) self.wait_until(lambda: self.output_count(lambda x: x >= 1)) diff --git a/libbeat/autodiscover/autodiscover.go b/libbeat/autodiscover/autodiscover.go index f36faa6b8f2..8c6977e8362 100644 --- a/libbeat/autodiscover/autodiscover.go +++ b/libbeat/autodiscover/autodiscover.go @@ -169,7 +169,7 @@ func (a *Autodiscover) worker() { } func (a *Autodiscover) handleStart(event bus.Event) bool { - a.logger.Debugf("Got a start event: %v", event) + a.logger.Debugw("Got a start event.", "autodiscover.event", event) eventID := getID(event) if eventID == "" { diff --git a/libbeat/autodiscover/builder/helper.go b/libbeat/autodiscover/builder/helper.go index faaa112c65f..6f78973e6fb 100644 --- a/libbeat/autodiscover/builder/helper.go +++ b/libbeat/autodiscover/builder/helper.go @@ -29,6 +29,8 @@ import ( "github.com/elastic/beats/v7/libbeat/logp" ) +const logName = "autodiscover.builder" + // GetContainerID returns the id of a container func GetContainerID(container common.MapStr) string { id, _ := container["id"].(string) @@ -92,7 +94,7 @@ func GetProcessors(hints common.MapStr, key string) []common.MapStr { if str, ok := value.(string); ok { cfg := common.MapStr{} if err := json.Unmarshal([]byte(str), &cfg); err != nil { - logp.Debug("autodiscover.builder", "unable to unmarshal json due to error: %v", err) + logp.NewLogger(logName).Debugw("Unable to unmarshal json due to error", "error", err) continue } proc[key] = cfg @@ -124,7 +126,7 @@ func GetConfigs(hints common.MapStr, key, name string) []common.MapStr { var configs []common.MapStr for _, key := range nums { - rawCfg, _ := raw[key] + rawCfg := raw[key] if config, ok := rawCfg.(common.MapStr); ok { configs = append(configs, config) } @@ -159,15 +161,15 @@ func GetHintAsConfigs(hints common.MapStr, key string) []common.MapStr { if str[0] != '[' { cfg := common.MapStr{} if err := json.Unmarshal([]byte(str), &cfg); err != nil { - logp.Debug("autodiscover.builder", "unable to unmarshal json due to error: %v", err) + logp.NewLogger(logName).Debugw("Unable to unmarshal json due to error", "error", err) return nil } return []common.MapStr{cfg} } - cfg := []common.MapStr{} + var cfg []common.MapStr if err := json.Unmarshal([]byte(str), &cfg); err != nil { - logp.Debug("autodiscover.builder", "unable to unmarshal json due to error: %v", err) + logp.NewLogger(logName).Debugw("Unable to unmarshal json due to error", "error", err) return nil } return cfg @@ -175,7 +177,7 @@ func GetHintAsConfigs(hints common.MapStr, key string) []common.MapStr { return nil } -// IsEnabled will return true when 'enabled' is **explicity** set to true +// IsEnabled will return true when 'enabled' is **explicitly** set to true. func IsEnabled(hints common.MapStr, key string) bool { if value, err := hints.GetValue(fmt.Sprintf("%s.enabled", key)); err == nil { enabled, _ := strconv.ParseBool(value.(string)) @@ -185,14 +187,16 @@ func IsEnabled(hints common.MapStr, key string) bool { return false } -// IsDisabled will return true when 'enabled' key is **explicity** set to false +// IsDisabled will return true when 'enabled' is **explicitly** set to false. func IsDisabled(hints common.MapStr, key string) bool { if value, err := hints.GetValue(fmt.Sprintf("%s.enabled", key)); err == nil { enabled, err := strconv.ParseBool(value.(string)) - if err == nil { - logp.Debug("autodiscover.builder", "error parsing 'enabled' hint from: %+v", hints) - return !enabled + if err != nil { + logp.NewLogger(logName).Debugw("Error parsing 'enabled' hint.", + "error", err, "autodiscover.hints", hints) + return false } + return !enabled } // keep reading disable (deprecated) for backwards compatibility @@ -271,7 +275,7 @@ func GetHintsAsList(hints common.MapStr, key string) []common.MapStr { var configs []common.MapStr for _, key := range nums { - rawCfg, _ := raw[key] + rawCfg := raw[key] if config, ok := rawCfg.(common.MapStr); ok { configs = append(configs, config) } diff --git a/libbeat/autodiscover/builder/plugin.go b/libbeat/autodiscover/builder/plugin.go index 83abccc2097..8ad423da13f 100644 --- a/libbeat/autodiscover/builder/plugin.go +++ b/libbeat/autodiscover/builder/plugin.go @@ -29,7 +29,7 @@ type builderPlugin struct { builder autodiscover.BuilderConstructor } -var pluginKey = "libbeat.autodiscover.builder" +const pluginKey = "libbeat.autodiscover.builder" // Plugin accepts a BuilderConstructor to be registered as a plugin func Plugin(name string, b autodiscover.BuilderConstructor) map[string][]interface{} { diff --git a/libbeat/docs/shared-autodiscover.asciidoc b/libbeat/docs/shared-autodiscover.asciidoc index 7bfed6f8f74..1d19a0f4bac 100644 --- a/libbeat/docs/shared-autodiscover.asciidoc +++ b/libbeat/docs/shared-autodiscover.asciidoc @@ -482,7 +482,21 @@ The `nomad` autodiscover provider has the following configuration settings: `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. +`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. @@ -496,6 +510,7 @@ The `nomad` autodiscover provider has the following configuration settings: `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[] diff --git a/x-pack/libbeat/autodiscover/providers/nomad/config.go b/x-pack/libbeat/autodiscover/providers/nomad/config.go index 1a611aceee3..5ce13556d91 100644 --- a/x-pack/libbeat/autodiscover/providers/nomad/config.go +++ b/x-pack/libbeat/autodiscover/providers/nomad/config.go @@ -41,9 +41,6 @@ type Config struct { func defaultConfig() *Config { return &Config{ Address: "http://127.0.0.1:4646", - Region: "", - Namespace: "", - SecretID: "", Scope: ScopeNode, allowStale: true, waitTime: 15 * time.Second, @@ -53,7 +50,7 @@ func defaultConfig() *Config { } } -// Validate ensures correctness of config +// Validate ensures correctness of config. func (c *Config) Validate() error { // Make sure that prefix doesn't ends with a '.' if c.Prefix[len(c.Prefix)-1] == '.' && c.Prefix != "." { diff --git a/x-pack/libbeat/autodiscover/providers/nomad/nomad.go b/x-pack/libbeat/autodiscover/providers/nomad/nomad.go index 6b3d9bc70fa..17284c49fd7 100644 --- a/x-pack/libbeat/autodiscover/providers/nomad/nomad.go +++ b/x-pack/libbeat/autodiscover/providers/nomad/nomad.go @@ -50,12 +50,10 @@ func AutodiscoverBuilder( c *common.Config, keystore keystore.Keystore, ) (autodiscover.Provider, error) { - cfgwarn.Experimental("The nomad autodiscover is experimental") + cfgwarn.Experimental("The nomad autodiscover provider is experimental.") config := defaultConfig() - - err := c.Unpack(&config) - if err != nil { + if err := c.Unpack(&config); err != nil { return nil, err } @@ -130,18 +128,18 @@ func AutodiscoverBuilder( watcher.AddEventHandler(nomad.ResourceEventHandlerFuncs{ AddFunc: func(obj nomad.Resource) { - logger.Debugf("Watcher Allocation add: %+v", obj.ID) + logger.Debugw("Nomad allocation added", "nomad.allocation.id", obj.ID) p.emit(&obj, "start") }, UpdateFunc: func(obj nomad.Resource) { - logger.Debugf("nomad", "Watcher Allocation update: %+v", obj.ID) + logger.Debugw("Nomad allocation updated", "nomad.allocation.id", obj.ID) p.emit(&obj, "stop") // We have a CleanupTimeout grace period (defaults to 15s) to wait for the stop event // to be processed time.AfterFunc(config.CleanupTimeout, func() { p.emit(&obj, "start") }) }, DeleteFunc: func(obj nomad.Resource) { - logger.Debugf("Watcher Allocation delete: %+v", obj.ID) + logger.Debugw("Nomad allocation deleted", "nomad.allocation.id", obj.ID) p.emit(&obj, "stop") }, }) @@ -152,7 +150,7 @@ func AutodiscoverBuilder( // Start for Runner interface. func (p *Provider) Start() { if err := p.watcher.Start(); err != nil { - p.logger.Errorf("Error starting nomad autodiscover provider: %s", err) + p.logger.Errorw("Error starting nomad autodiscover provider", "error", err) } } @@ -175,7 +173,7 @@ func (p *Provider) emit(obj *nomad.Resource, flag string) { // the NodeID host, err := p.metagen.AllocationNodeName(obj.NodeID) if err != nil { - p.logger.Errorf("Error fetching node information: %s", err) + p.logger.Errorw("Error fetching node information", "error", err) } // If we cannot get a host, we assume that the allocation was stopped @@ -189,7 +187,7 @@ func (p *Provider) emit(obj *nomad.Resource, flag string) { // common metadata from the entire allocation allocMeta := p.metagen.ResourceMetadata(*obj) - // job metadatata merged with the task metadata + // job metadata merged with the task metadata tasks := p.metagen.GroupMeta(obj.Job) // emit per-task separated events @@ -225,7 +223,7 @@ func (p *Provider) publish(event bus.Event) { // Call all appenders to append any extra configuration p.appenders.Append(event) - p.logger.Debugf("nomad", "Publishing event: %+v", event) + p.logger.Debugw("Publishing nomad autodiscover event.", "autodiscover.event", event) p.bus.Publish(event) } @@ -275,12 +273,9 @@ func (p *Provider) generateHints(event bus.Event) bus.Event { cname := builder.GetContainerName(container) hints := builder.GenerateHints(tasks, cname, p.config.Prefix) - - p.logger.Debugf("Generated hints from %+v %+v", tasks, hints) - if len(hints) != 0 { + if len(hints) > 0 { e["hints"] = hints } - p.logger.Debugf("nomad", "Generated builder event %+v", e) prefix := strings.Split(p.config.Prefix, ".")[0] tasks.Delete(prefix) diff --git a/x-pack/libbeat/common/nomad/metadata.go b/x-pack/libbeat/common/nomad/metadata.go index b0648b6e3e7..51e2fe93ebc 100644 --- a/x-pack/libbeat/common/nomad/metadata.go +++ b/x-pack/libbeat/common/nomad/metadata.go @@ -82,7 +82,7 @@ func (g *metaGenerator) ResourceMetadata(obj Resource) common.MapStr { // Returns an array of per-task metadata aggregating the group metadata into the // task metadata func (g *metaGenerator) GroupMeta(job *Job) []common.MapStr { - tasksMeta := []common.MapStr{} + var tasksMeta []common.MapStr for _, group := range job.TaskGroups { meta := make(map[string]string, len(job.Meta)) @@ -131,7 +131,7 @@ func (g *metaGenerator) GroupMeta(job *Job) []common.MapStr { // Returns per-task metadata func (g *metaGenerator) tasksMeta(group *TaskGroup) []common.MapStr { - tasks := []common.MapStr{} + var tasks []common.MapStr for _, task := range group.Tasks { var svcNames, svcTags, svcCanaryTags []string @@ -201,7 +201,7 @@ func generateMapSubset(input common.MapStr, keys []string, dedot bool) common.Ma } // AllocationNodeName returns Name of the node where the task is allocated. It -// does one additional API call to circunvent the empty NodeName property of +// does one additional API call to circumvent the empty NodeName property of // older Nomad versions (up to v0.8) func (g *metaGenerator) AllocationNodeName(id string) (string, error) { if name, ok := g.nodesCache[id]; ok { diff --git a/x-pack/libbeat/common/nomad/watcher.go b/x-pack/libbeat/common/nomad/watcher.go index eba77e764ad..31cb5590ff9 100644 --- a/x-pack/libbeat/common/nomad/watcher.go +++ b/x-pack/libbeat/common/nomad/watcher.go @@ -45,7 +45,7 @@ type WatchOptions struct { SyncTimeout time.Duration // Node is used for filtering events Node string - // Namespace is used for filtering events on specified namespacesx, + // Namespace is used for filtering events on specified namespaces. Namespace string // RefreshInterval is the time interval that the Nomad API will be queried RefreshInterval time.Duration @@ -103,7 +103,7 @@ func (w *watcher) AddEventHandler(h ResourceEventHandlerFuncs) { // Sync the allocations on the given node and update the local metadata func (w *watcher) sync() error { - w.logger.Debugf("Syncing allocations and metadata") + w.logger.Debug("Syncing allocations and metadata") w.logger.Debugf("Starting with WaitIndex=%v", w.waitIndex) queryOpts := &api.QueryOptions{ @@ -114,21 +114,20 @@ func (w *watcher) sync() error { allocations, meta, err := w.getAllocations(queryOpts) if err != nil { - return fmt.Errorf("listing allocations: %w", err) + return fmt.Errorf("failed listing allocations: %w", err) } - w.logger.Debugf("Found %d allocations", len(allocations)) - remoteWaitIndex := meta.LastIndex localWaitIndex := queryOpts.WaitIndex // Only emit updated metadata if the WaitIndex have changed if remoteWaitIndex <= localWaitIndex { w.logger.Debugf("Allocations index is unchanged remoteWaitIndex=%v == localWaitIndex=%v", - fmt.Sprint(remoteWaitIndex), fmt.Sprint(localWaitIndex)) + remoteWaitIndex, localWaitIndex) return nil } + 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 { @@ -184,7 +183,7 @@ func (w *watcher) sync() error { func (w *watcher) watch() { // Failures counter, do exponential backoff on retries var failures uint - logp.Info("Nomad: %s", "Watching API for resource events") + w.logger.Info("Watching API for resource events") ticker := time.NewTicker(w.options.RefreshInterval) defer ticker.Stop() @@ -193,9 +192,8 @@ func (w *watcher) watch() { case <-w.done: return case <-ticker.C: - err := w.sync() - if err != nil { - logp.Err("Nomad: Error while watching for allocation changes %v", err) + if err := w.sync(); err != nil { + w.logger.Warnw("Error while watching for Nomad allocation changes. Backing off and continuing.", "error", err) backoff(failures) failures++ } @@ -215,11 +213,14 @@ func (w *watcher) getAllocations(queryOpts *api.QueryOptions) ([]*api.Allocation if err != nil { return nil, meta, err } + var allocations []*api.Allocation for _, stub := range stubs { allocation, _, err := w.client.Allocations().Info(stub.ID, queryOpts) if err != nil { - w.logger.Warnf("Failed to get details of allocation '%s'", stub.ID) + w.logger.Warnw("Failed to get details of an allocation.", + "nomad.allocation.id", stub.ID) + continue } allocations = append(allocations, allocation) } @@ -232,12 +233,11 @@ func (w *watcher) fetchNodeID() (string, error) { AllowStale: w.options.AllowStale, } - // Fetch the nodeId from the node name, used to filter the allocations - // If for some reason the NodeID changes filebeat will have to be restarted + // Fetch the nodeId from the node name, used to filter the allocations. + // If for some reason the NodeID changes filebeat will have to be restarted. nodes, _, err := w.client.Nodes().List(queryOpts) - if err != nil { - w.logger.Fatalf("Nomad: Fetching node list err %s", err.Error()) + w.logger.Errorw("Failed fetching Nomad node list.", "error", err) return "", err } diff --git a/x-pack/libbeat/processors/add_nomad_metadata/docs/add_nomad_metadata.asciidoc b/x-pack/libbeat/processors/add_nomad_metadata/docs/add_nomad_metadata.asciidoc index 1ab6b8cab03..31c4d2ede20 100644 --- a/x-pack/libbeat/processors/add_nomad_metadata/docs/add_nomad_metadata.asciidoc +++ b/x-pack/libbeat/processors/add_nomad_metadata/docs/add_nomad_metadata.asciidoc @@ -32,7 +32,21 @@ uses `http://127.0.0.1:4646` by default. in this namespace will be annotated. `region`:: (Optional) Region to watch. If set, only events for allocations in this region will be annotated. -`secretID`:: (Optional) SecretID to use when connecting with the agent API. +`secret_id`:: (Optional) SecretID to use when connecting with the agent API. +This is an example ACL policy to apply to the token. + +[source,hcl] +---- +namespace "*" { + policy = "read" +} +node { + policy = "read" +} +agent { + policy = "read" +} +---- `refresh_interval`:: (Optional) Interval used to updated the cached metadata. It defaults to 30 seconds. `cleanup_timeout`:: (Optional) After an allocation has been removed, time to From 9e670f74ac43b17cb5f559db2d4d42396aca3a46 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Tue, 29 Jun 2021 08:51:32 -0500 Subject: [PATCH 07/25] [Filebeat] Add network direction processor to Zeek and Suricata modules (#24620) * Add network direction processor to zeek and suricata module * Add Snort & Sonicwall * update changelog * use ES network_direction processor * Revert "use ES network_direction processor" This reverts commit 1c5722d9f1f6cd5370ef3f3d7a882e49731a4e3d. * update docs with new variable * Removed Snort and Sonicwall * update docs * missed one Co-authored-by: Marius Iversen --- CHANGELOG.next.asciidoc | 1 + filebeat/docs/modules/suricata.asciidoc | 9 + filebeat/docs/modules/zeek.asciidoc | 746 ++++++++++++++++++ .../module/suricata/_meta/docs.asciidoc | 9 + .../module/suricata/eve/config/eve.yml | 7 + .../filebeat/module/suricata/eve/manifest.yml | 2 + .../eve/test/eve-6.0.log-expected.json | 1 + .../eve/test/eve-alerts.log-expected.json | 22 + .../eve/test/eve-dns-4.1.4.log-expected.json | 24 + .../eve/test/eve-small.log-expected.json | 11 + .../filebeat/module/zeek/_meta/docs.asciidoc | 746 ++++++++++++++++++ .../zeek/connection/config/connection.yml | 7 + .../module/zeek/connection/manifest.yml | 2 + .../test/connection-json.log-expected.json | 4 +- .../module/zeek/dce_rpc/config/dce_rpc.yml | 7 + .../filebeat/module/zeek/dce_rpc/manifest.yml | 2 + .../test/dce_rpc-json.log-expected.json | 1 + .../filebeat/module/zeek/dhcp/config/dhcp.yml | 7 + x-pack/filebeat/module/zeek/dhcp/manifest.yml | 2 + .../dhcp/test/dhcp-json.log-expected.json | 1 + .../filebeat/module/zeek/dnp3/config/dnp3.yml | 7 + x-pack/filebeat/module/zeek/dnp3/manifest.yml | 2 + .../dnp3/test/dnp3-json.log-expected.json | 1 + .../filebeat/module/zeek/dns/config/dns.yml | 11 + x-pack/filebeat/module/zeek/dns/manifest.yml | 2 + .../zeek/dns/test/dns-json.log-expected.json | 6 + .../filebeat/module/zeek/dpd/config/dpd.yml | 7 + x-pack/filebeat/module/zeek/dpd/manifest.yml | 2 + .../zeek/dpd/test/dpd-json.log-expected.json | 1 + .../filebeat/module/zeek/ftp/config/ftp.yml | 7 + x-pack/filebeat/module/zeek/ftp/manifest.yml | 2 + .../zeek/ftp/test/ftp.log-expected.json | 3 + .../filebeat/module/zeek/http/config/http.yml | 8 + x-pack/filebeat/module/zeek/http/manifest.yml | 2 + .../http/test/http-json.log-expected.json | 4 + .../module/zeek/intel/config/intel.yml | 7 + .../filebeat/module/zeek/intel/manifest.yml | 2 + .../intel/test/intel-json.log-expected.json | 1 + .../filebeat/module/zeek/irc/config/irc.yml | 7 + x-pack/filebeat/module/zeek/irc/manifest.yml | 2 + .../zeek/irc/test/irc-json.log-expected.json | 3 + .../module/zeek/kerberos/config/kerberos.yml | 7 + .../module/zeek/kerberos/manifest.yml | 2 + .../test/kerberos-json.log-expected.json | 1 + .../module/zeek/modbus/config/modbus.yml | 7 + .../filebeat/module/zeek/modbus/manifest.yml | 2 + .../modbus/test/modbus-json.log-expected.json | 1 + .../module/zeek/mysql/config/mysql.yml | 7 + .../filebeat/module/zeek/mysql/manifest.yml | 2 + .../mysql/test/mysql-json.log-expected.json | 1 + .../module/zeek/notice/config/notice.yml | 7 + .../filebeat/module/zeek/notice/manifest.yml | 2 + .../notice/test/notice-json.log-expected.json | 1 + .../filebeat/module/zeek/ntlm/config/ntlm.yml | 7 + x-pack/filebeat/module/zeek/ntlm/manifest.yml | 2 + .../ntlm/test/ntlm-json.log-expected.json | 1 + .../filebeat/module/zeek/ntp/config/ntp.yml | 7 + x-pack/filebeat/module/zeek/ntp/manifest.yml | 2 + .../zeek/ntp/test/ntp-json.log-expected.json | 2 + .../module/zeek/radius/config/radius.yml | 7 + .../filebeat/module/zeek/radius/manifest.yml | 2 + .../radius/test/radius-json.log-expected.json | 1 + .../filebeat/module/zeek/rdp/config/rdp.yml | 7 + x-pack/filebeat/module/zeek/rdp/manifest.yml | 2 + .../zeek/rdp/test/rdp-json.log-expected.json | 1 + .../filebeat/module/zeek/rfb/config/rfb.yml | 7 + x-pack/filebeat/module/zeek/rfb/manifest.yml | 2 + .../zeek/rfb/test/rfb-json.log-expected.json | 1 + .../zeek/signature/config/signature.yml | 7 + .../module/zeek/signature/manifest.yml | 2 + .../test/signature-json.log-expected.json | 1 + .../filebeat/module/zeek/sip/config/sip.yml | 7 + x-pack/filebeat/module/zeek/sip/manifest.yml | 2 + .../zeek/sip/test/sip-json.log-expected.json | 3 + .../module/zeek/smb_cmd/config/smb_cmd.yml | 7 + .../filebeat/module/zeek/smb_cmd/manifest.yml | 2 + .../test/smb_cmd-json.log-expected.json | 1 + .../zeek/smb_files/config/smb_files.yml | 7 + .../module/zeek/smb_files/manifest.yml | 2 + .../test/smb_files-json.log-expected.json | 1 + .../zeek/smb_mapping/config/smb_mapping.yml | 7 + .../module/zeek/smb_mapping/manifest.yml | 2 + .../test/smb_mapping-json.log-expected.json | 1 + .../filebeat/module/zeek/smtp/config/smtp.yml | 7 + x-pack/filebeat/module/zeek/smtp/manifest.yml | 2 + .../smtp/test/smtp-json.log-expected.json | 1 + .../filebeat/module/zeek/snmp/config/snmp.yml | 7 + x-pack/filebeat/module/zeek/snmp/manifest.yml | 2 + .../snmp/test/snmp-json.log-expected.json | 1 + .../module/zeek/socks/config/socks.yml | 7 + .../filebeat/module/zeek/socks/manifest.yml | 2 + .../socks/test/socks-json.log-expected.json | 1 + .../filebeat/module/zeek/ssh/config/ssh.yml | 7 + x-pack/filebeat/module/zeek/ssh/manifest.yml | 2 + .../zeek/ssh/test/ssh-json.log-expected.json | 1 + .../filebeat/module/zeek/ssl/config/ssl.yml | 7 + x-pack/filebeat/module/zeek/ssl/manifest.yml | 2 + .../zeek/ssl/test/ssl-json.log-expected.json | 2 + ...3-and-custom-fields-json.log-expected.json | 1 + .../module/zeek/syslog/config/syslog.yml | 7 + .../filebeat/module/zeek/syslog/manifest.yml | 2 + .../zeek/traceroute/config/traceroute.yml | 7 + .../module/zeek/traceroute/manifest.yml | 2 + .../test/traceroute-json.log-expected.json | 1 + .../module/zeek/tunnel/config/tunnel.yml | 7 + .../filebeat/module/zeek/tunnel/manifest.yml | 2 + .../tunnel/test/tunnel-json.log-expected.json | 1 + .../module/zeek/weird/config/weird.yml | 7 + .../filebeat/module/zeek/weird/manifest.yml | 2 + .../weird/test/weird-json.log-expected.json | 1 + 110 files changed, 1930 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 06c21b8b48f..1250f7ff555 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -813,6 +813,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add new grok pattern for iptables module for Ubiquiti UDM {issue}25615[25615] {pull}25616[25616] - Add multiline support to aws-s3 input. {issue}25249[25249] {pull}25710[25710] - Add monitoring metrics to the `aws-s3` input. {pull}25711[25711] +- Added `network.direction` fields to Zeek and Suricata modules using the `add_network_direction` processor {pull}24620[24620] - Add Content-Type override to aws-s3 input. {issue}25697[25697] {pull}25772[25772] - In Cisco Umbrella fileset add users from cisco.umbrella.identities to related.user. {pull}25776[25776] - Add fingerprint processor to generate fixed ids for `google_workspace` events. {pull}25841[25841] diff --git a/filebeat/docs/modules/suricata.asciidoc b/filebeat/docs/modules/suricata.asciidoc index 0e7348b291d..4426a8f2cc4 100644 --- a/filebeat/docs/modules/suricata.asciidoc +++ b/filebeat/docs/modules/suricata.asciidoc @@ -51,6 +51,15 @@ A list of tags to include in events. Including `forwarded` indicates that the events did not originate on this host and causes `host.name` to not be added to events. Defaults to `[suricata]`. +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + [float] === Example dashboard diff --git a/filebeat/docs/modules/zeek.asciidoc b/filebeat/docs/modules/zeek.asciidoc index 3fbb1a27b94..1d73f24d3e1 100644 --- a/filebeat/docs/modules/zeek.asciidoc +++ b/filebeat/docs/modules/zeek.asciidoc @@ -30,6 +30,752 @@ with newer versions of Zeek. Zeek requires a Unix-like platform, and it currently supports Linux, FreeBSD, and Mac OS X. +[float] +==== `capture_loss` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `connection` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dce_rpc` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dhcp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dnp3` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dns` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dpd` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `ftp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `http` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `intel` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `irc` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `kerberos` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `modbus` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `mysql` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `notice` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ntls` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ntp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ocsp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `pe` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `radius` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `rdp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `rfb` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `signature` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `sip` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_cmd` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_mapping` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smtp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `snmp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `socks` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ssh` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ssl` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `stats` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `syslog` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `traceroute` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `tunnel` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `weird` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `x509` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + [float] === Example dashboard diff --git a/x-pack/filebeat/module/suricata/_meta/docs.asciidoc b/x-pack/filebeat/module/suricata/_meta/docs.asciidoc index 08d5feb61cb..27a5acab512 100644 --- a/x-pack/filebeat/module/suricata/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/suricata/_meta/docs.asciidoc @@ -46,6 +46,15 @@ A list of tags to include in events. Including `forwarded` indicates that the events did not originate on this host and causes `host.name` to not be added to events. Defaults to `[suricata]`. +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + [float] === Example dashboard diff --git a/x-pack/filebeat/module/suricata/eve/config/eve.yml b/x-pack/filebeat/module/suricata/eve/config/eve.yml index 56bd78a9122..13d5b23c5de 100644 --- a/x-pack/filebeat/module/suricata/eve/config/eve.yml +++ b/x-pack/filebeat/module/suricata/eve/config/eve.yml @@ -42,6 +42,13 @@ processors: - suricata.eve.timestamp {{ if .community_id }} - community_id: +{{ end }} +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} {{ end }} - registered_domain: when: diff --git a/x-pack/filebeat/module/suricata/eve/manifest.yml b/x-pack/filebeat/module/suricata/eve/manifest.yml index a712ab66336..ae3b99ba315 100644 --- a/x-pack/filebeat/module/suricata/eve/manifest.yml +++ b/x-pack/filebeat/module/suricata/eve/manifest.yml @@ -12,6 +12,8 @@ var: default: [suricata] - name: community_id default: true + - name: internal_networks + default: [ private ] ingest_pipeline: - ingest/pipeline.yml diff --git a/x-pack/filebeat/module/suricata/eve/test/eve-6.0.log-expected.json b/x-pack/filebeat/module/suricata/eve/test/eve-6.0.log-expected.json index c95a0baa7d9..26adbe46301 100644 --- a/x-pack/filebeat/module/suricata/eve/test/eve-6.0.log-expected.json +++ b/x-pack/filebeat/module/suricata/eve/test/eve-6.0.log-expected.json @@ -30,6 +30,7 @@ "message": "Potentially Bad Traffic", "network.bytes": 1372, "network.community_id": "1:/b5R3BDG/6TU2Pu+pRF8w6d1Z18=", + "network.direction": "inbound", "network.packets": 11, "network.protocol": "http", "network.transport": "tcp", diff --git a/x-pack/filebeat/module/suricata/eve/test/eve-alerts.log-expected.json b/x-pack/filebeat/module/suricata/eve/test/eve-alerts.log-expected.json index 97b556a628a..c9878e61a1c 100644 --- a/x-pack/filebeat/module/suricata/eve/test/eve-alerts.log-expected.json +++ b/x-pack/filebeat/module/suricata/eve/test/eve-alerts.log-expected.json @@ -39,6 +39,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:Tx1T2pcsxn4KDSlkBTi/5q9tZuo=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -120,6 +121,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:A30Bhw0tTI2EifayU+MwAocMCZs=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -201,6 +203,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:QI9ZBw/ltPo2cnzG5ne3IrgSdhw=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -282,6 +285,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:kvem4ydd+kylAQHyyYnQUREfRDY=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -363,6 +367,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:HpBUwS4J4Fkh+ON3BdMMGV4jy8I=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -444,6 +449,7 @@ "message": "Attempted Information Leak", "network.bytes": 2001, "network.community_id": "1:Bp3vB9bJiV2y/u23rxSpviRLSto=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -525,6 +531,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 2151, "network.community_id": "1:/kMBCIkdcM80Xtj2MYPWlkzcovg=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -606,6 +613,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 904, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 7, "network.protocol": "http", "network.transport": "tcp", @@ -687,6 +695,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 4287, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 11, "network.protocol": "http", "network.transport": "tcp", @@ -768,6 +777,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 95353, "network.community_id": "1:/kMBCIkdcM80Xtj2MYPWlkzcovg=", + "network.direction": "outbound", "network.packets": 126, "network.protocol": "http", "network.transport": "tcp", @@ -849,6 +859,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 151605, "network.community_id": "1:/kMBCIkdcM80Xtj2MYPWlkzcovg=", + "network.direction": "outbound", "network.packets": 185, "network.protocol": "http", "network.transport": "tcp", @@ -930,6 +941,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 341985, "network.community_id": "1:/kMBCIkdcM80Xtj2MYPWlkzcovg=", + "network.direction": "outbound", "network.packets": 377, "network.protocol": "http", "network.transport": "tcp", @@ -1011,6 +1023,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 101449, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 131, "network.protocol": "http", "network.transport": "tcp", @@ -1092,6 +1105,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 181775, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 210, "network.protocol": "http", "network.transport": "tcp", @@ -1173,6 +1187,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 388131, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 412, "network.protocol": "http", "network.transport": "tcp", @@ -1254,6 +1269,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 482156, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 504, "network.protocol": "http", "network.transport": "tcp", @@ -1335,6 +1351,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 903684, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 916, "network.protocol": "http", "network.transport": "tcp", @@ -1416,6 +1433,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 908100, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 921, "network.protocol": "http", "network.transport": "tcp", @@ -1496,6 +1514,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 1504422, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 1503, "network.protocol": "http", "network.transport": "tcp", @@ -1576,6 +1595,7 @@ "message": "Not Suspicious Traffic", "network.bytes": 1658832, "network.community_id": "1:v4+r8WgQyj/+LOpAIRGXwdlh/Xk=", + "network.direction": "outbound", "network.packets": 1654, "network.protocol": "http", "network.transport": "tcp", @@ -1637,6 +1657,7 @@ "input.type": "log", "log.offset": 16546, "network.community_id": "1:qsGDjYDIWp+kHhxotTdhPbUaWSo=", + "network.direction": "internal", "network.protocol": "tls", "network.transport": "tcp", "related.hash": [ @@ -1717,6 +1738,7 @@ "message": "", "network.bytes": 5734, "network.community_id": "1:W6fjhboFUwyEchJ3ELaqSBzDEJE=", + "network.direction": "internal", "network.packets": 15, "network.protocol": "tls", "network.transport": "tcp", diff --git a/x-pack/filebeat/module/suricata/eve/test/eve-dns-4.1.4.log-expected.json b/x-pack/filebeat/module/suricata/eve/test/eve-dns-4.1.4.log-expected.json index c320226749e..202d0f84df2 100644 --- a/x-pack/filebeat/module/suricata/eve/test/eve-dns-4.1.4.log-expected.json +++ b/x-pack/filebeat/module/suricata/eve/test/eve-dns-4.1.4.log-expected.json @@ -24,6 +24,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:HActqwgIaYeC8fc4sfMGrL8jjaI=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -71,6 +72,7 @@ "input.type": "log", "log.offset": 280, "network.community_id": "1:Z5dwZB2hQ1ZuxC+6Jw04VtuJ1lw=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -134,6 +136,7 @@ "input.type": "log", "log.offset": 564, "network.community_id": "1:Z5dwZB2hQ1ZuxC+6Jw04VtuJ1lw=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -198,6 +201,7 @@ "input.type": "log", "log.offset": 1089, "network.community_id": "1:HActqwgIaYeC8fc4sfMGrL8jjaI=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -247,6 +251,7 @@ "input.type": "log", "log.offset": 1552, "network.community_id": "1:vfjW/QLkaS6+iMbv/HRuEOgqA4o=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -295,6 +300,7 @@ "input.type": "log", "log.offset": 1835, "network.community_id": "1:SDBTqhsjpXwQyrvRX6xpeEaMsAg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -386,6 +392,7 @@ "input.type": "log", "log.offset": 2122, "network.community_id": "1:vfjW/QLkaS6+iMbv/HRuEOgqA4o=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -481,6 +488,7 @@ "input.type": "log", "log.offset": 3116, "network.community_id": "1:SDBTqhsjpXwQyrvRX6xpeEaMsAg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -533,6 +541,7 @@ "input.type": "log", "log.offset": 4327, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -581,6 +590,7 @@ "input.type": "log", "log.offset": 4610, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -637,6 +647,7 @@ "input.type": "log", "log.offset": 4896, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -698,6 +709,7 @@ "input.type": "log", "log.offset": 5288, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -760,6 +772,7 @@ "input.type": "log", "log.offset": 5675, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -822,6 +835,7 @@ "input.type": "log", "log.offset": 6062, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -884,6 +898,7 @@ "input.type": "log", "log.offset": 6446, "network.community_id": "1:O4Lt3gevExgYQL5MQJq7vgssBrQ=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -943,6 +958,7 @@ "input.type": "log", "log.offset": 6829, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1004,6 +1020,7 @@ "input.type": "log", "log.offset": 7221, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1066,6 +1083,7 @@ "input.type": "log", "log.offset": 7636, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1128,6 +1146,7 @@ "input.type": "log", "log.offset": 8051, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1190,6 +1209,7 @@ "input.type": "log", "log.offset": 8466, "network.community_id": "1:NKecJMP5cHplk+fr2uNww69SdWg=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1241,6 +1261,7 @@ "input.type": "log", "log.offset": 8881, "network.community_id": "1:zh0UVYktuWGDSL+4ROPa1CTtEPE=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1289,6 +1310,7 @@ "input.type": "log", "log.offset": 9165, "network.community_id": "1:fuLDtU46PU3PHindOSCj0JKYUaA=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1380,6 +1402,7 @@ "input.type": "log", "log.offset": 9452, "network.community_id": "1:zh0UVYktuWGDSL+4ROPa1CTtEPE=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -1475,6 +1498,7 @@ "input.type": "log", "log.offset": 10310, "network.community_id": "1:fuLDtU46PU3PHindOSCj0JKYUaA=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ diff --git a/x-pack/filebeat/module/suricata/eve/test/eve-small.log-expected.json b/x-pack/filebeat/module/suricata/eve/test/eve-small.log-expected.json index 8fb7eb1a9ee..312ed45c58b 100644 --- a/x-pack/filebeat/module/suricata/eve/test/eve-small.log-expected.json +++ b/x-pack/filebeat/module/suricata/eve/test/eve-small.log-expected.json @@ -18,6 +18,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:NLm1MbaBR6humQxEQI2Ai7h/XiI=", + "network.direction": "internal", "network.protocol": "ssh", "network.transport": "tcp", "related.ip": [ @@ -66,6 +67,7 @@ "message": "Potential Corporate Privacy Violation", "network.bytes": 1136, "network.community_id": "1:BWtsS+4pk477zAwfzve3Nm+x1Ms=", + "network.direction": "internal", "network.packets": 7, "network.protocol": "tls", "network.transport": "tcp", @@ -128,6 +130,7 @@ "input.type": "log", "log.offset": 985, "network.community_id": "1:gjMiDGtS5SVvdwzjjQdAKGBrDA4=", + "network.direction": "internal", "network.protocol": "http", "network.transport": "tcp", "related.hosts": [ @@ -184,6 +187,7 @@ "input.type": "log", "log.offset": 1507, "network.community_id": "1:XhhAO/Twj86+bD+1fV8FnpLIEDs=", + "network.direction": "internal", "network.protocol": "http", "network.transport": "tcp", "related.hosts": [ @@ -257,6 +261,7 @@ "input.type": "log", "log.offset": 2347, "network.community_id": "1:pC3b0nBNCU4LxSue53drHp4b4cs=", + "network.direction": "internal", "network.protocol": "dns", "network.transport": "udp", "related.ip": [ @@ -443,6 +448,7 @@ "input.type": "log", "log.offset": 4683, "network.community_id": "1:u67AuA4ybOaspT7mp9OZ3jWvnKw=", + "network.direction": "outbound", "network.protocol": "tls", "network.transport": "tcp", "related.hash": [ @@ -517,6 +523,7 @@ "log.offset": 5308, "network.bytes": 110, "network.community_id": "1:fNUIKjMfx/xaM1gOO3eaVAeWLZA=", + "network.direction": "external", "network.packets": 1, "network.transport": "udp", "related.ip": [ @@ -563,6 +570,7 @@ "input.type": "log", "log.offset": 5796, "network.community_id": "1:Y8m38aDR9cy/emlD86XGhosniqY=", + "network.direction": "internal", "network.protocol": "http", "network.transport": "tcp", "related.hosts": [ @@ -613,6 +621,7 @@ "input.type": "log", "log.offset": 6267, "network.community_id": "1:SKXuhLNyv4gfe01gqILs5v+qx40=", + "network.direction": "internal", "network.protocol": "tls", "network.transport": "tcp", "related.hash": [ @@ -684,6 +693,7 @@ "input.type": "log", "log.offset": 6958, "network.community_id": "1:UHWPAQmxXu8t7EWZzPx9jl6b6TM=", + "network.direction": "internal", "network.protocol": "http", "network.transport": "tcp", "related.hosts": [ @@ -736,6 +746,7 @@ "input.type": "log", "log.offset": 7401, "network.community_id": "1:0dSnqQKCiJXvy6HxZlV+50/b68k=", + "network.direction": "internal", "network.protocol": "tls", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/_meta/docs.asciidoc b/x-pack/filebeat/module/zeek/_meta/docs.asciidoc index aaef3f7803e..a597a61bdc6 100644 --- a/x-pack/filebeat/module/zeek/_meta/docs.asciidoc +++ b/x-pack/filebeat/module/zeek/_meta/docs.asciidoc @@ -25,6 +25,752 @@ with newer versions of Zeek. Zeek requires a Unix-like platform, and it currently supports Linux, FreeBSD, and Mac OS X. +[float] +==== `capture_loss` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `connection` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dce_rpc` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dhcp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dnp3` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dns` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `dpd` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `ftp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `http` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `intel` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `irc` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `kerberos` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `modbus` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `mysql` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `notice` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ntls` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ntp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ocsp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `pe` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `radius` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `rdp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `rfb` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `signature` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `sip` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_cmd` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_files` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smb_mapping` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `smtp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `snmp` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `socks` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ssh` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `ssl` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `stats` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +[float] +==== `syslog` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `traceroute` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `tunnel` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `weird` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + +`var.internal_networks`:: + +A list of CIDR ranges describing the IP addresses that +you consider internal. This is used in determining the value of +`network.direction`. The values +can be either a CIDR value or one of the named ranges supported by the +<> condition. The default value is `[private]` +which classifies RFC 1918 (IPv4) and RFC 4193 (IPv6) addresses as internal. + +[float] +==== `x509` log fileset settings + +include::../include/var-paths.asciidoc[] + +*`var.tags`*:: + +A list of tags to include in events. Including `forwarded` indicates that the +events did not originate on this host and causes `host.name` to not be added to +events. Defaults to `[suricata]`. + [float] === Example dashboard diff --git a/x-pack/filebeat/module/zeek/connection/config/connection.yml b/x-pack/filebeat/module/zeek/connection/config/connection.yml index d1316761181..00ce320e463 100644 --- a/x-pack/filebeat/module/zeek/connection/config/connection.yml +++ b/x-pack/filebeat/module/zeek/connection/config/connection.yml @@ -99,6 +99,13 @@ processors: icmp_code: zeek.connection.icmp.code else: community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/connection/manifest.yml b/x-pack/filebeat/module/zeek/connection/manifest.yml index 08f79bc28ca..9cf9d5127fa 100644 --- a/x-pack/filebeat/module/zeek/connection/manifest.yml +++ b/x-pack/filebeat/module/zeek/connection/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/conn.log - name: tags default: [zeek.connection] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/connection.yml diff --git a/x-pack/filebeat/module/zeek/connection/test/connection-json.log-expected.json b/x-pack/filebeat/module/zeek/connection/test/connection-json.log-expected.json index ee633382786..611d4b41bda 100644 --- a/x-pack/filebeat/module/zeek/connection/test/connection-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/connection/test/connection-json.log-expected.json @@ -263,8 +263,8 @@ "source.packets": 0, "source.port": 46408, "tags": [ - "zeek.connection", - "local_orig" + "local_orig", + "zeek.connection" ], "zeek.connection.history": "C", "zeek.connection.local_orig": true, diff --git a/x-pack/filebeat/module/zeek/dce_rpc/config/dce_rpc.yml b/x-pack/filebeat/module/zeek/dce_rpc/config/dce_rpc.yml index c48c9660bd9..566f885d249 100644 --- a/x-pack/filebeat/module/zeek/dce_rpc/config/dce_rpc.yml +++ b/x-pack/filebeat/module/zeek/dce_rpc/config/dce_rpc.yml @@ -55,6 +55,13 @@ processors: - protocol - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/dce_rpc/manifest.yml b/x-pack/filebeat/module/zeek/dce_rpc/manifest.yml index 01bef572b67..8cd608dc878 100644 --- a/x-pack/filebeat/module/zeek/dce_rpc/manifest.yml +++ b/x-pack/filebeat/module/zeek/dce_rpc/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/dce_rpc.log - name: tags default: [zeek.dce_rpc] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/dce_rpc.yml diff --git a/x-pack/filebeat/module/zeek/dce_rpc/test/dce_rpc-json.log-expected.json b/x-pack/filebeat/module/zeek/dce_rpc/test/dce_rpc-json.log-expected.json index 822fd214a51..a42f28836ab 100644 --- a/x-pack/filebeat/module/zeek/dce_rpc/test/dce_rpc-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/dce_rpc/test/dce_rpc-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:SJNAD5vtzZuhQjGtfaI8svTnyuw=", + "network.direction": "internal", "network.protocol": "dce_rpc", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/dhcp/config/dhcp.yml b/x-pack/filebeat/module/zeek/dhcp/config/dhcp.yml index d965fa44e1b..bfe423c839a 100644 --- a/x-pack/filebeat/module/zeek/dhcp/config/dhcp.yml +++ b/x-pack/filebeat/module/zeek/dhcp/config/dhcp.yml @@ -117,6 +117,13 @@ processors: - protocol - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/dhcp/manifest.yml b/x-pack/filebeat/module/zeek/dhcp/manifest.yml index ee4a7c24f3b..aadaf2c923a 100644 --- a/x-pack/filebeat/module/zeek/dhcp/manifest.yml +++ b/x-pack/filebeat/module/zeek/dhcp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/dhcp.log - name: tags default: [zeek.dhcp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/dhcp.yml diff --git a/x-pack/filebeat/module/zeek/dhcp/test/dhcp-json.log-expected.json b/x-pack/filebeat/module/zeek/dhcp/test/dhcp-json.log-expected.json index b10a71fdd77..40e43895bec 100644 --- a/x-pack/filebeat/module/zeek/dhcp/test/dhcp-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/dhcp/test/dhcp-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:HsGjbon+HsK9xnMq+1A32BR9C4Y=", + "network.direction": "internal", "network.name": "localdomain", "network.protocol": "dhcp", "network.transport": "udp", diff --git a/x-pack/filebeat/module/zeek/dnp3/config/dnp3.yml b/x-pack/filebeat/module/zeek/dnp3/config/dnp3.yml index a7f0192b777..227c850cdc3 100644 --- a/x-pack/filebeat/module/zeek/dnp3/config/dnp3.yml +++ b/x-pack/filebeat/module/zeek/dnp3/config/dnp3.yml @@ -65,6 +65,13 @@ processors: - protocol - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/dnp3/manifest.yml b/x-pack/filebeat/module/zeek/dnp3/manifest.yml index 97829b3d0d0..c2b305d8e9b 100644 --- a/x-pack/filebeat/module/zeek/dnp3/manifest.yml +++ b/x-pack/filebeat/module/zeek/dnp3/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/dnp3.log - name: tags default: [zeek.dnp3] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/dnp3.yml diff --git a/x-pack/filebeat/module/zeek/dnp3/test/dnp3-json.log-expected.json b/x-pack/filebeat/module/zeek/dnp3/test/dnp3-json.log-expected.json index bb22f51cf06..056f2e0d028 100644 --- a/x-pack/filebeat/module/zeek/dnp3/test/dnp3-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/dnp3/test/dnp3-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:E57Z1w3RrSdR+fi6rSZblbQVhzY=", + "network.direction": "external", "network.protocol": "dnp3", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/dns/config/dns.yml b/x-pack/filebeat/module/zeek/dns/config/dns.yml index f68c77cbcdb..8d308a75933 100644 --- a/x-pack/filebeat/module/zeek/dns/config/dns.yml +++ b/x-pack/filebeat/module/zeek/dns/config/dns.yml @@ -7,6 +7,10 @@ exclude_files: [".gz$"] tags: {{.tags | tojson}} publisher_pipeline.disable_host: {{ inList .tags "forwarded" }} +fields_under_root: true +fields: + network.protocol: dns + processors: - rename: fields: @@ -201,6 +205,13 @@ processors: - info - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - drop_fields: ignore_missing: true fields: diff --git a/x-pack/filebeat/module/zeek/dns/manifest.yml b/x-pack/filebeat/module/zeek/dns/manifest.yml index 4ff46df94b9..37ccaaf46ea 100644 --- a/x-pack/filebeat/module/zeek/dns/manifest.yml +++ b/x-pack/filebeat/module/zeek/dns/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/dns.log - name: tags default: [zeek.dns] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/dns.yml diff --git a/x-pack/filebeat/module/zeek/dns/test/dns-json.log-expected.json b/x-pack/filebeat/module/zeek/dns/test/dns-json.log-expected.json index 03d8f10a3ac..d27f42275e9 100644 --- a/x-pack/filebeat/module/zeek/dns/test/dns-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/dns/test/dns-json.log-expected.json @@ -53,6 +53,8 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:Z26DBGVYoBKQ1FT6qfPaAqBnJik=", + "network.direction": "internal", + "network.protocol": "dns", "network.transport": "udp", "related.ip": [ "192.168.86.1", @@ -121,6 +123,8 @@ "input.type": "log", "log.offset": 566, "network.community_id": "1:Jq0sRtlGSMjsvMBE1ZYybbR2tI0=", + "network.direction": "external", + "network.protocol": "dns", "network.transport": "udp", "related.ip": [ "fe80::4ef:15cf:769f:ff21", @@ -183,6 +187,8 @@ "input.type": "log", "log.offset": 909, "network.community_id": "1:QIR5YXlirWwWA18ZyY/RnvQoaic=", + "network.direction": "outbound", + "network.protocol": "dns", "network.transport": "udp", "related.ip": [ "192.168.86.237", diff --git a/x-pack/filebeat/module/zeek/dpd/config/dpd.yml b/x-pack/filebeat/module/zeek/dpd/config/dpd.yml index 38261f1b2f7..24679c7d5d8 100644 --- a/x-pack/filebeat/module/zeek/dpd/config/dpd.yml +++ b/x-pack/filebeat/module/zeek/dpd/config/dpd.yml @@ -54,6 +54,13 @@ processors: - connection - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/dpd/manifest.yml b/x-pack/filebeat/module/zeek/dpd/manifest.yml index 854eadbf491..7f6fa8e0a14 100644 --- a/x-pack/filebeat/module/zeek/dpd/manifest.yml +++ b/x-pack/filebeat/module/zeek/dpd/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/dpd.log - name: tags default: [zeek.dpd] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/dpd.yml diff --git a/x-pack/filebeat/module/zeek/dpd/test/dpd-json.log-expected.json b/x-pack/filebeat/module/zeek/dpd/test/dpd-json.log-expected.json index e36fc1dcbc2..10e0ed1b7fc 100644 --- a/x-pack/filebeat/module/zeek/dpd/test/dpd-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/dpd/test/dpd-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:b+Szw+ia464igf5e+MwW1WUzw9Y=", + "network.direction": "internal", "network.transport": "tcp", "related.ip": [ "192.168.10.10", diff --git a/x-pack/filebeat/module/zeek/ftp/config/ftp.yml b/x-pack/filebeat/module/zeek/ftp/config/ftp.yml index bb5854631e4..a777b98eabe 100644 --- a/x-pack/filebeat/module/zeek/ftp/config/ftp.yml +++ b/x-pack/filebeat/module/zeek/ftp/config/ftp.yml @@ -83,6 +83,13 @@ processors: - info - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/ftp/manifest.yml b/x-pack/filebeat/module/zeek/ftp/manifest.yml index 1f37ead03d0..2a6025e9cfd 100644 --- a/x-pack/filebeat/module/zeek/ftp/manifest.yml +++ b/x-pack/filebeat/module/zeek/ftp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/ftp.log - name: tags default: [zeek.ftp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/ftp.yml diff --git a/x-pack/filebeat/module/zeek/ftp/test/ftp.log-expected.json b/x-pack/filebeat/module/zeek/ftp/test/ftp.log-expected.json index e6a47bd369e..0830fae2eaa 100644 --- a/x-pack/filebeat/module/zeek/ftp/test/ftp.log-expected.json +++ b/x-pack/filebeat/module/zeek/ftp/test/ftp.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:Szmpl33Czo3dQvU2V4/SrHfmBC0=", + "network.direction": "internal", "network.protocol": "ftp", "network.transport": "tcp", "related.ip": [ @@ -72,6 +73,7 @@ "input.type": "log", "log.offset": 394, "network.community_id": "1:Szmpl33Czo3dQvU2V4/SrHfmBC0=", + "network.direction": "internal", "network.protocol": "ftp", "network.transport": "tcp", "related.ip": [ @@ -120,6 +122,7 @@ "input.type": "log", "log.offset": 688, "network.community_id": "1:Szmpl33Czo3dQvU2V4/SrHfmBC0=", + "network.direction": "internal", "network.protocol": "ftp", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/http/config/http.yml b/x-pack/filebeat/module/zeek/http/config/http.yml index 6b0973bea30..292f92d4c58 100644 --- a/x-pack/filebeat/module/zeek/http/config/http.yml +++ b/x-pack/filebeat/module/zeek/http/config/http.yml @@ -12,6 +12,7 @@ json.keys_under_root: false fields_under_root: true fields: network.transport: tcp + network.protocol: http processors: - rename: @@ -91,6 +92,13 @@ processors: - info - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/http/manifest.yml b/x-pack/filebeat/module/zeek/http/manifest.yml index acf134c2333..3bc4ea2c527 100644 --- a/x-pack/filebeat/module/zeek/http/manifest.yml +++ b/x-pack/filebeat/module/zeek/http/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/http.log - name: tags default: [zeek.http] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/http.yml diff --git a/x-pack/filebeat/module/zeek/http/test/http-json.log-expected.json b/x-pack/filebeat/module/zeek/http/test/http-json.log-expected.json index 0b101cda6e1..c5e64d5aee8 100644 --- a/x-pack/filebeat/module/zeek/http/test/http-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/http/test/http-json.log-expected.json @@ -38,6 +38,8 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:dtBPRfpKEZyg1iOHss95buwv+cw=", + "network.direction": "outbound", + "network.protocol": "http", "network.transport": "tcp", "related.ip": [ "10.178.98.102", @@ -111,6 +113,8 @@ "input.type": "log", "log.offset": 574, "network.community_id": "1:Ol0Btm49e1mxnu/BXm1GM8w5ixY=", + "network.direction": "outbound", + "network.protocol": "http", "network.transport": "tcp", "related.ip": [ "10.20.8.197", diff --git a/x-pack/filebeat/module/zeek/intel/config/intel.yml b/x-pack/filebeat/module/zeek/intel/config/intel.yml index 3af7f9a6a85..5a0d8967c0a 100644 --- a/x-pack/filebeat/module/zeek/intel/config/intel.yml +++ b/x-pack/filebeat/module/zeek/intel/config/intel.yml @@ -64,6 +64,13 @@ processors: type: - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/intel/manifest.yml b/x-pack/filebeat/module/zeek/intel/manifest.yml index a84788f4d75..c89feeed149 100644 --- a/x-pack/filebeat/module/zeek/intel/manifest.yml +++ b/x-pack/filebeat/module/zeek/intel/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/intel.log - name: tags default: [zeek.intel] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/intel.yml diff --git a/x-pack/filebeat/module/zeek/intel/test/intel-json.log-expected.json b/x-pack/filebeat/module/zeek/intel/test/intel-json.log-expected.json index d9de4e04efd..c22918b6f78 100644 --- a/x-pack/filebeat/module/zeek/intel/test/intel-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/intel/test/intel-json.log-expected.json @@ -21,6 +21,7 @@ "fileset.name": "intel", "input.type": "log", "log.offset": 0, + "network.direction": "outbound", "related.ip": [ "192.168.1.1", "198.41.0.4" diff --git a/x-pack/filebeat/module/zeek/irc/config/irc.yml b/x-pack/filebeat/module/zeek/irc/config/irc.yml index de8d91c2b99..1a7f1ac9a1d 100644 --- a/x-pack/filebeat/module/zeek/irc/config/irc.yml +++ b/x-pack/filebeat/module/zeek/irc/config/irc.yml @@ -69,6 +69,13 @@ processors: - protocol - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/irc/manifest.yml b/x-pack/filebeat/module/zeek/irc/manifest.yml index 36cf10a5bb3..804199e78dc 100644 --- a/x-pack/filebeat/module/zeek/irc/manifest.yml +++ b/x-pack/filebeat/module/zeek/irc/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/irc.log - name: tags default: [zeek.irc] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/irc.yml diff --git a/x-pack/filebeat/module/zeek/irc/test/irc-json.log-expected.json b/x-pack/filebeat/module/zeek/irc/test/irc-json.log-expected.json index 0c495c74bd5..0d4aa51901f 100644 --- a/x-pack/filebeat/module/zeek/irc/test/irc-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/irc/test/irc-json.log-expected.json @@ -28,6 +28,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:YdkGov/c+KLtmg7Cf5DLDB4+YdQ=", + "network.direction": "outbound", "network.protocol": "irc", "network.transport": "tcp", "related.ip": [ @@ -75,6 +76,7 @@ "input.type": "log", "log.offset": 206, "network.community_id": "1:YdkGov/c+KLtmg7Cf5DLDB4+YdQ=", + "network.direction": "outbound", "network.protocol": "irc", "network.transport": "tcp", "related.ip": [ @@ -127,6 +129,7 @@ "input.type": "log", "log.offset": 432, "network.community_id": "1:YdkGov/c+KLtmg7Cf5DLDB4+YdQ=", + "network.direction": "outbound", "network.protocol": "irc", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/kerberos/config/kerberos.yml b/x-pack/filebeat/module/zeek/kerberos/config/kerberos.yml index c2eee02dd7a..6b6a97affe8 100644 --- a/x-pack/filebeat/module/zeek/kerberos/config/kerberos.yml +++ b/x-pack/filebeat/module/zeek/kerberos/config/kerberos.yml @@ -101,6 +101,13 @@ processors: field: zeek.kerberos.client target_prefix: "" - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/kerberos/manifest.yml b/x-pack/filebeat/module/zeek/kerberos/manifest.yml index 3f527b15013..281cd6ea3e8 100644 --- a/x-pack/filebeat/module/zeek/kerberos/manifest.yml +++ b/x-pack/filebeat/module/zeek/kerberos/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/kerberos.log - name: tags default: [zeek.kerberos] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/kerberos.yml diff --git a/x-pack/filebeat/module/zeek/kerberos/test/kerberos-json.log-expected.json b/x-pack/filebeat/module/zeek/kerberos/test/kerberos-json.log-expected.json index 43862a49170..38bafd60641 100644 --- a/x-pack/filebeat/module/zeek/kerberos/test/kerberos-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/kerberos/test/kerberos-json.log-expected.json @@ -23,6 +23,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:DW/lSsosl8gZ8pqO9kKMm7cZheQ=", + "network.direction": "internal", "network.protocol": "kerberos", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/modbus/config/modbus.yml b/x-pack/filebeat/module/zeek/modbus/config/modbus.yml index 7b2767d6d43..635b73224f3 100644 --- a/x-pack/filebeat/module/zeek/modbus/config/modbus.yml +++ b/x-pack/filebeat/module/zeek/modbus/config/modbus.yml @@ -70,6 +70,13 @@ processors: fields: outcome: success - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/modbus/manifest.yml b/x-pack/filebeat/module/zeek/modbus/manifest.yml index c4afd6315d4..73fc02e009e 100644 --- a/x-pack/filebeat/module/zeek/modbus/manifest.yml +++ b/x-pack/filebeat/module/zeek/modbus/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/modbus.log - name: tags default: [zeek.modbus] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/modbus.yml diff --git a/x-pack/filebeat/module/zeek/modbus/test/modbus-json.log-expected.json b/x-pack/filebeat/module/zeek/modbus/test/modbus-json.log-expected.json index ba9034a3621..d0fbe505d0b 100644 --- a/x-pack/filebeat/module/zeek/modbus/test/modbus-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/modbus/test/modbus-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:jEXbR2FqHyMgLJgyYyFQN3yxbpc=", + "network.direction": "internal", "network.protocol": "modbus", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/mysql/config/mysql.yml b/x-pack/filebeat/module/zeek/mysql/config/mysql.yml index fdf41190d75..44a4515ed99 100644 --- a/x-pack/filebeat/module/zeek/mysql/config/mysql.yml +++ b/x-pack/filebeat/module/zeek/mysql/config/mysql.yml @@ -69,6 +69,13 @@ processors: fields: outcome: failure - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/mysql/manifest.yml b/x-pack/filebeat/module/zeek/mysql/manifest.yml index bba253a418e..5d7d6c9824b 100644 --- a/x-pack/filebeat/module/zeek/mysql/manifest.yml +++ b/x-pack/filebeat/module/zeek/mysql/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/mysql.log - name: tags default: [zeek.mysql] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/mysql.yml diff --git a/x-pack/filebeat/module/zeek/mysql/test/mysql-json.log-expected.json b/x-pack/filebeat/module/zeek/mysql/test/mysql-json.log-expected.json index 676080e9d3e..54a6c19e12e 100644 --- a/x-pack/filebeat/module/zeek/mysql/test/mysql-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/mysql/test/mysql-json.log-expected.json @@ -23,6 +23,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:0HUQbshhYbATQXDHv/ysOs0DlZA=", + "network.direction": "internal", "network.protocol": "mysql", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/notice/config/notice.yml b/x-pack/filebeat/module/zeek/notice/config/notice.yml index 480992351e8..588411dd535 100644 --- a/x-pack/filebeat/module/zeek/notice/config/notice.yml +++ b/x-pack/filebeat/module/zeek/notice/config/notice.yml @@ -101,6 +101,13 @@ processors: type: - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/notice/manifest.yml b/x-pack/filebeat/module/zeek/notice/manifest.yml index e14f7222065..746d8734138 100644 --- a/x-pack/filebeat/module/zeek/notice/manifest.yml +++ b/x-pack/filebeat/module/zeek/notice/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/notice.log - name: tags default: [zeek.notice] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/notice.yml diff --git a/x-pack/filebeat/module/zeek/notice/test/notice-json.log-expected.json b/x-pack/filebeat/module/zeek/notice/test/notice-json.log-expected.json index 8fa5ffbaf48..7d804ac76db 100644 --- a/x-pack/filebeat/module/zeek/notice/test/notice-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/notice/test/notice-json.log-expected.json @@ -59,6 +59,7 @@ "fileset.name": "notice", "input.type": "log", "log.offset": 357, + "network.direction": "external", "related.ip": [ "207.154.238.205", "8.42.77.171" diff --git a/x-pack/filebeat/module/zeek/ntlm/config/ntlm.yml b/x-pack/filebeat/module/zeek/ntlm/config/ntlm.yml index 0f203f4e985..b56492d47c7 100644 --- a/x-pack/filebeat/module/zeek/ntlm/config/ntlm.yml +++ b/x-pack/filebeat/module/zeek/ntlm/config/ntlm.yml @@ -83,6 +83,13 @@ processors: fields: outcome: failure - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/ntlm/manifest.yml b/x-pack/filebeat/module/zeek/ntlm/manifest.yml index e16e6ec8b3a..bbeac1c6878 100644 --- a/x-pack/filebeat/module/zeek/ntlm/manifest.yml +++ b/x-pack/filebeat/module/zeek/ntlm/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/ntlm.log - name: tags default: [zeek.ntlm] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/ntlm.yml diff --git a/x-pack/filebeat/module/zeek/ntlm/test/ntlm-json.log-expected.json b/x-pack/filebeat/module/zeek/ntlm/test/ntlm-json.log-expected.json index d6f6099290c..0f4c276be58 100644 --- a/x-pack/filebeat/module/zeek/ntlm/test/ntlm-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/ntlm/test/ntlm-json.log-expected.json @@ -20,6 +20,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:zxnXAE/Cme5fQhh6sJLs7GItc08=", + "network.direction": "internal", "network.protocol": "ntlm", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/ntp/config/ntp.yml b/x-pack/filebeat/module/zeek/ntp/config/ntp.yml index 8b0eeced08a..33d16335d4f 100644 --- a/x-pack/filebeat/module/zeek/ntp/config/ntp.yml +++ b/x-pack/filebeat/module/zeek/ntp/config/ntp.yml @@ -51,6 +51,13 @@ processors: protocol: ntp transport: udp - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/ntp/manifest.yml b/x-pack/filebeat/module/zeek/ntp/manifest.yml index 034861b73fe..f91e2ef5431 100644 --- a/x-pack/filebeat/module/zeek/ntp/manifest.yml +++ b/x-pack/filebeat/module/zeek/ntp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/ntp.log - name: tags default: [zeek.ntp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/ntp.yml diff --git a/x-pack/filebeat/module/zeek/ntp/test/ntp-json.log-expected.json b/x-pack/filebeat/module/zeek/ntp/test/ntp-json.log-expected.json index 0d9f847e271..7c7b34cbefa 100644 --- a/x-pack/filebeat/module/zeek/ntp/test/ntp-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/ntp/test/ntp-json.log-expected.json @@ -27,6 +27,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:IDiKR+C1G8mk7LQhFpp+4p1tHrk=", + "network.direction": "external", "network.protocol": "ntp", "network.transport": "udp", "network.type": "ipv4", @@ -89,6 +90,7 @@ "input.type": "log", "log.offset": 335, "network.community_id": "1:IDiKR+C1G8mk7LQhFpp+4p1tHrk=", + "network.direction": "external", "network.protocol": "ntp", "network.transport": "udp", "network.type": "ipv4", diff --git a/x-pack/filebeat/module/zeek/radius/config/radius.yml b/x-pack/filebeat/module/zeek/radius/config/radius.yml index 4102f85e680..908e4143bf9 100644 --- a/x-pack/filebeat/module/zeek/radius/config/radius.yml +++ b/x-pack/filebeat/module/zeek/radius/config/radius.yml @@ -55,6 +55,13 @@ processors: - info - connection - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/radius/manifest.yml b/x-pack/filebeat/module/zeek/radius/manifest.yml index d3bdee065b0..d66478b1689 100644 --- a/x-pack/filebeat/module/zeek/radius/manifest.yml +++ b/x-pack/filebeat/module/zeek/radius/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/radius.log - name: tags default: [zeek.radius] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/radius.yml diff --git a/x-pack/filebeat/module/zeek/radius/test/radius-json.log-expected.json b/x-pack/filebeat/module/zeek/radius/test/radius-json.log-expected.json index bd8ab187529..83824400fa3 100644 --- a/x-pack/filebeat/module/zeek/radius/test/radius-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/radius/test/radius-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:3SdDgWXPnheV2oGfVmxQjfwtr8E=", + "network.direction": "internal", "network.protocol": "radius", "network.transport": "udp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/rdp/config/rdp.yml b/x-pack/filebeat/module/zeek/rdp/config/rdp.yml index 9ae4b226b14..b3a9b1c3db4 100644 --- a/x-pack/filebeat/module/zeek/rdp/config/rdp.yml +++ b/x-pack/filebeat/module/zeek/rdp/config/rdp.yml @@ -85,6 +85,13 @@ processors: - protocol - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/rdp/manifest.yml b/x-pack/filebeat/module/zeek/rdp/manifest.yml index 0a2bc7b77ec..b9293c5c7ca 100644 --- a/x-pack/filebeat/module/zeek/rdp/manifest.yml +++ b/x-pack/filebeat/module/zeek/rdp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/rdp.log - name: tags default: [zeek.rdp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/rdp.yml diff --git a/x-pack/filebeat/module/zeek/rdp/test/rdp-json.log-expected.json b/x-pack/filebeat/module/zeek/rdp/test/rdp-json.log-expected.json index 1d2763f149b..0eda0a721d8 100644 --- a/x-pack/filebeat/module/zeek/rdp/test/rdp-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/rdp/test/rdp-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:PsQu6lSZioPVi0A5K7UaeGsVqS0=", + "network.direction": "internal", "network.protocol": "rdp", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/rfb/config/rfb.yml b/x-pack/filebeat/module/zeek/rfb/config/rfb.yml index 3cda29c1ae3..f608167cf27 100644 --- a/x-pack/filebeat/module/zeek/rfb/config/rfb.yml +++ b/x-pack/filebeat/module/zeek/rfb/config/rfb.yml @@ -70,6 +70,13 @@ processors: - connection - info - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/rfb/manifest.yml b/x-pack/filebeat/module/zeek/rfb/manifest.yml index 4bba4f4f37c..2172035aca6 100644 --- a/x-pack/filebeat/module/zeek/rfb/manifest.yml +++ b/x-pack/filebeat/module/zeek/rfb/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/rfb.log - name: tags default: [zeek.rfb] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/rfb.yml diff --git a/x-pack/filebeat/module/zeek/rfb/test/rfb-json.log-expected.json b/x-pack/filebeat/module/zeek/rfb/test/rfb-json.log-expected.json index 822336f5ea8..dcd221c6fad 100644 --- a/x-pack/filebeat/module/zeek/rfb/test/rfb-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/rfb/test/rfb-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:AtPVA5phuztnwqMfO/2142WXVdY=", + "network.direction": "internal", "network.protocol": "rfb", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/signature/config/signature.yml b/x-pack/filebeat/module/zeek/signature/config/signature.yml index 8fd0b3a4344..7c477faf90d 100644 --- a/x-pack/filebeat/module/zeek/signature/config/signature.yml +++ b/x-pack/filebeat/module/zeek/signature/config/signature.yml @@ -44,6 +44,13 @@ processors: fields: kind: alert - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/signature/manifest.yml b/x-pack/filebeat/module/zeek/signature/manifest.yml index e0d005622d0..9ac3efc4452 100644 --- a/x-pack/filebeat/module/zeek/signature/manifest.yml +++ b/x-pack/filebeat/module/zeek/signature/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/signatures.log - name: tags default: [zeek.signature] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/signature.yml diff --git a/x-pack/filebeat/module/zeek/signature/test/signature-json.log-expected.json b/x-pack/filebeat/module/zeek/signature/test/signature-json.log-expected.json index d06eb256245..6951cedca70 100644 --- a/x-pack/filebeat/module/zeek/signature/test/signature-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/signature/test/signature-json.log-expected.json @@ -18,6 +18,7 @@ "fileset.name": "signature", "input.type": "log", "log.offset": 0, + "network.direction": "external", "related.ip": [ "124.51.137.154", "160.218.27.63" diff --git a/x-pack/filebeat/module/zeek/sip/config/sip.yml b/x-pack/filebeat/module/zeek/sip/config/sip.yml index 5a309499b56..9849a0f90ac 100644 --- a/x-pack/filebeat/module/zeek/sip/config/sip.yml +++ b/x-pack/filebeat/module/zeek/sip/config/sip.yml @@ -92,6 +92,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/sip/manifest.yml b/x-pack/filebeat/module/zeek/sip/manifest.yml index 2186e6b0f3f..20e4ccacc33 100644 --- a/x-pack/filebeat/module/zeek/sip/manifest.yml +++ b/x-pack/filebeat/module/zeek/sip/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/sip.log - name: tags default: [zeek.sip] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/sip.yml diff --git a/x-pack/filebeat/module/zeek/sip/test/sip-json.log-expected.json b/x-pack/filebeat/module/zeek/sip/test/sip-json.log-expected.json index 55c08baec97..5352052b0cd 100644 --- a/x-pack/filebeat/module/zeek/sip/test/sip-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/sip/test/sip-json.log-expected.json @@ -29,6 +29,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:t8Jl0amIXPHemzxKgsLjtkB+ewo=", + "network.direction": "outbound", "network.protocol": "sip", "network.transport": "udp", "related.ip": [ @@ -100,6 +101,7 @@ "input.type": "log", "log.offset": 805, "network.community_id": "1:U/Makwsc8lm6pVKLfRMzoNTI++0=", + "network.direction": "external", "network.protocol": "sip", "network.transport": "udp", "related.ip": [ @@ -185,6 +187,7 @@ "input.type": "log", "log.offset": 1654, "network.community_id": "1:0hvHF/bh5wFKg7nfRXxsno4F198=", + "network.direction": "external", "network.protocol": "sip", "network.transport": "udp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/smb_cmd/config/smb_cmd.yml b/x-pack/filebeat/module/zeek/smb_cmd/config/smb_cmd.yml index 0db0030d97c..0453f5d2594 100644 --- a/x-pack/filebeat/module/zeek/smb_cmd/config/smb_cmd.yml +++ b/x-pack/filebeat/module/zeek/smb_cmd/config/smb_cmd.yml @@ -98,6 +98,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/smb_cmd/manifest.yml b/x-pack/filebeat/module/zeek/smb_cmd/manifest.yml index 331cafae30f..d8dd3223277 100644 --- a/x-pack/filebeat/module/zeek/smb_cmd/manifest.yml +++ b/x-pack/filebeat/module/zeek/smb_cmd/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/smb_cmd.log - name: tags default: [zeek.smb_cmd] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/smb_cmd.yml diff --git a/x-pack/filebeat/module/zeek/smb_cmd/test/smb_cmd-json.log-expected.json b/x-pack/filebeat/module/zeek/smb_cmd/test/smb_cmd-json.log-expected.json index dea6f2dda60..66651b05cea 100644 --- a/x-pack/filebeat/module/zeek/smb_cmd/test/smb_cmd-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/smb_cmd/test/smb_cmd-json.log-expected.json @@ -21,6 +21,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:SJNAD5vtzZuhQjGtfaI8svTnyuw=", + "network.direction": "internal", "network.protocol": "smb", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/smb_files/config/smb_files.yml b/x-pack/filebeat/module/zeek/smb_files/config/smb_files.yml index 7a51cf5cd15..91c589b55dd 100644 --- a/x-pack/filebeat/module/zeek/smb_files/config/smb_files.yml +++ b/x-pack/filebeat/module/zeek/smb_files/config/smb_files.yml @@ -58,6 +58,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/smb_files/manifest.yml b/x-pack/filebeat/module/zeek/smb_files/manifest.yml index bdbf0324fd9..1c176d8fd39 100644 --- a/x-pack/filebeat/module/zeek/smb_files/manifest.yml +++ b/x-pack/filebeat/module/zeek/smb_files/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/smb_files.log - name: tags default: [zeek.smb_files] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/smb_files.yml diff --git a/x-pack/filebeat/module/zeek/smb_files/test/smb_files-json.log-expected.json b/x-pack/filebeat/module/zeek/smb_files/test/smb_files-json.log-expected.json index aba4c5e6489..db4e59fef89 100644 --- a/x-pack/filebeat/module/zeek/smb_files/test/smb_files-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/smb_files/test/smb_files-json.log-expected.json @@ -29,6 +29,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:k308wDxRMx/FIEzeh+YwD86zgoA=", + "network.direction": "internal", "network.protocol": "smb", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/smb_mapping/config/smb_mapping.yml b/x-pack/filebeat/module/zeek/smb_mapping/config/smb_mapping.yml index ce6cf08cd60..8437d7cd95f 100644 --- a/x-pack/filebeat/module/zeek/smb_mapping/config/smb_mapping.yml +++ b/x-pack/filebeat/module/zeek/smb_mapping/config/smb_mapping.yml @@ -54,6 +54,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/smb_mapping/manifest.yml b/x-pack/filebeat/module/zeek/smb_mapping/manifest.yml index f4afd881b54..6cceda0d585 100644 --- a/x-pack/filebeat/module/zeek/smb_mapping/manifest.yml +++ b/x-pack/filebeat/module/zeek/smb_mapping/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/smb_mapping.log - name: tags default: [zeek.smb_mapping] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/smb_mapping.yml diff --git a/x-pack/filebeat/module/zeek/smb_mapping/test/smb_mapping-json.log-expected.json b/x-pack/filebeat/module/zeek/smb_mapping/test/smb_mapping-json.log-expected.json index 95bb44ae35b..5c6616d773c 100644 --- a/x-pack/filebeat/module/zeek/smb_mapping/test/smb_mapping-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/smb_mapping/test/smb_mapping-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:k308wDxRMx/FIEzeh+YwD86zgoA=", + "network.direction": "internal", "network.protocol": "smb", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/smtp/config/smtp.yml b/x-pack/filebeat/module/zeek/smtp/config/smtp.yml index d8735b9ec08..e7999331b70 100644 --- a/x-pack/filebeat/module/zeek/smtp/config/smtp.yml +++ b/x-pack/filebeat/module/zeek/smtp/config/smtp.yml @@ -64,6 +64,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/smtp/manifest.yml b/x-pack/filebeat/module/zeek/smtp/manifest.yml index bc0d180278b..ace763487d2 100644 --- a/x-pack/filebeat/module/zeek/smtp/manifest.yml +++ b/x-pack/filebeat/module/zeek/smtp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/smtp.log - name: tags default: [zeek.smtp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/smtp.yml diff --git a/x-pack/filebeat/module/zeek/smtp/test/smtp-json.log-expected.json b/x-pack/filebeat/module/zeek/smtp/test/smtp-json.log-expected.json index 61e1be27bf6..1feda03d153 100644 --- a/x-pack/filebeat/module/zeek/smtp/test/smtp-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/smtp/test/smtp-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:38H0puTqOoHT/5r2bKFUVSXifQw=", + "network.direction": "internal", "network.protocol": "smtp", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/snmp/config/snmp.yml b/x-pack/filebeat/module/zeek/snmp/config/snmp.yml index 2973ef5728e..28d2abf7e63 100644 --- a/x-pack/filebeat/module/zeek/snmp/config/snmp.yml +++ b/x-pack/filebeat/module/zeek/snmp/config/snmp.yml @@ -66,6 +66,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/snmp/manifest.yml b/x-pack/filebeat/module/zeek/snmp/manifest.yml index e25fb364b1e..28eb5127b88 100644 --- a/x-pack/filebeat/module/zeek/snmp/manifest.yml +++ b/x-pack/filebeat/module/zeek/snmp/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/snmp.log - name: tags default: [zeek.snmp] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/snmp.yml diff --git a/x-pack/filebeat/module/zeek/snmp/test/snmp-json.log-expected.json b/x-pack/filebeat/module/zeek/snmp/test/snmp-json.log-expected.json index 47c6aace67f..41c2cf3262a 100644 --- a/x-pack/filebeat/module/zeek/snmp/test/snmp-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/snmp/test/snmp-json.log-expected.json @@ -19,6 +19,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:X15ey/8/tEH+tlelK6P+GfgwBPc=", + "network.direction": "internal", "network.protocol": "snmp", "network.transport": "udp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/socks/config/socks.yml b/x-pack/filebeat/module/zeek/socks/config/socks.yml index f094ce08298..c98a893934c 100644 --- a/x-pack/filebeat/module/zeek/socks/config/socks.yml +++ b/x-pack/filebeat/module/zeek/socks/config/socks.yml @@ -64,6 +64,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/socks/manifest.yml b/x-pack/filebeat/module/zeek/socks/manifest.yml index 55c4a387524..06a9de15d7e 100644 --- a/x-pack/filebeat/module/zeek/socks/manifest.yml +++ b/x-pack/filebeat/module/zeek/socks/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/socks.log - name: tags default: [zeek.socks] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/socks.yml diff --git a/x-pack/filebeat/module/zeek/socks/test/socks-json.log-expected.json b/x-pack/filebeat/module/zeek/socks/test/socks-json.log-expected.json index 0a45d16a569..2c4c9fe0f87 100644 --- a/x-pack/filebeat/module/zeek/socks/test/socks-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/socks/test/socks-json.log-expected.json @@ -20,6 +20,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:1Hp/o0hOC62lAwrV+a0ZKDE3rrs=", + "network.direction": "external", "network.protocol": "socks", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/ssh/config/ssh.yml b/x-pack/filebeat/module/zeek/ssh/config/ssh.yml index de6a74747e0..89b91b8b9c4 100644 --- a/x-pack/filebeat/module/zeek/ssh/config/ssh.yml +++ b/x-pack/filebeat/module/zeek/ssh/config/ssh.yml @@ -73,6 +73,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/ssh/manifest.yml b/x-pack/filebeat/module/zeek/ssh/manifest.yml index 9d2f39212b5..99e51bc4e63 100644 --- a/x-pack/filebeat/module/zeek/ssh/manifest.yml +++ b/x-pack/filebeat/module/zeek/ssh/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/ssh.log - name: tags default: [zeek.ssh] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/ssh.yml diff --git a/x-pack/filebeat/module/zeek/ssh/test/ssh-json.log-expected.json b/x-pack/filebeat/module/zeek/ssh/test/ssh-json.log-expected.json index e0f16cfc692..7172e08c3a5 100644 --- a/x-pack/filebeat/module/zeek/ssh/test/ssh-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/ssh/test/ssh-json.log-expected.json @@ -20,6 +20,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:42tg9bemt74qgrdvJOy2n5Veg4A=", + "network.direction": "internal", "network.protocol": "ssh", "network.transport": "tcp", "related.ip": [ diff --git a/x-pack/filebeat/module/zeek/ssl/config/ssl.yml b/x-pack/filebeat/module/zeek/ssl/config/ssl.yml index cd37a3499ac..e5c4760ae3e 100644 --- a/x-pack/filebeat/module/zeek/ssl/config/ssl.yml +++ b/x-pack/filebeat/module/zeek/ssl/config/ssl.yml @@ -91,6 +91,13 @@ processors: - connection - protocol - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/ssl/manifest.yml b/x-pack/filebeat/module/zeek/ssl/manifest.yml index 49e474dfadc..d602418cfec 100644 --- a/x-pack/filebeat/module/zeek/ssl/manifest.yml +++ b/x-pack/filebeat/module/zeek/ssl/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/ssl.log - name: tags default: [zeek.ssl] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/ssl.yml diff --git a/x-pack/filebeat/module/zeek/ssl/test/ssl-json.log-expected.json b/x-pack/filebeat/module/zeek/ssl/test/ssl-json.log-expected.json index db88b09da23..d7c6816aa06 100644 --- a/x-pack/filebeat/module/zeek/ssl/test/ssl-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/ssl/test/ssl-json.log-expected.json @@ -30,6 +30,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:1PMhYqOKBIyRAQeMbg/pWiJ198g=", + "network.direction": "outbound", "network.transport": "tcp", "related.ip": [ "10.178.98.102", @@ -112,6 +113,7 @@ "input.type": "log", "log.offset": 635, "network.community_id": "1:zYbLmqRN6PLPB067HNAiAQISqvI=", + "network.direction": "outbound", "network.transport": "tcp", "related.ip": [ "10.178.98.102", diff --git a/x-pack/filebeat/module/zeek/ssl/test/ssl-with-ja3-and-custom-fields-json.log-expected.json b/x-pack/filebeat/module/zeek/ssl/test/ssl-with-ja3-and-custom-fields-json.log-expected.json index c4b3cb7a871..6f3cac8fdca 100644 --- a/x-pack/filebeat/module/zeek/ssl/test/ssl-with-ja3-and-custom-fields-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/ssl/test/ssl-with-ja3-and-custom-fields-json.log-expected.json @@ -20,6 +20,7 @@ "input.type": "log", "log.offset": 0, "network.community_id": "1:qNHgoGHFvyhhK2jU7LlS3537ODc=", + "network.direction": "internal", "network.transport": "tcp", "related.ip": [ "10.0.0.1", diff --git a/x-pack/filebeat/module/zeek/syslog/config/syslog.yml b/x-pack/filebeat/module/zeek/syslog/config/syslog.yml index 4c343767225..6d5f43a1989 100644 --- a/x-pack/filebeat/module/zeek/syslog/config/syslog.yml +++ b/x-pack/filebeat/module/zeek/syslog/config/syslog.yml @@ -54,6 +54,13 @@ processors: fields: kind: event - community_id: +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: '' fields: diff --git a/x-pack/filebeat/module/zeek/syslog/manifest.yml b/x-pack/filebeat/module/zeek/syslog/manifest.yml index 03a80586303..10ec76396bd 100644 --- a/x-pack/filebeat/module/zeek/syslog/manifest.yml +++ b/x-pack/filebeat/module/zeek/syslog/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/syslog.log - name: tags default: [zeek.syslog] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/syslog.yml diff --git a/x-pack/filebeat/module/zeek/traceroute/config/traceroute.yml b/x-pack/filebeat/module/zeek/traceroute/config/traceroute.yml index 4ff304af84c..4798abe4cae 100644 --- a/x-pack/filebeat/module/zeek/traceroute/config/traceroute.yml +++ b/x-pack/filebeat/module/zeek/traceroute/config/traceroute.yml @@ -34,6 +34,13 @@ processors: - {from: "destination.address", to: "destination.ip", type: "ip"} ignore_missing: true fail_on_error: false +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: event fields: diff --git a/x-pack/filebeat/module/zeek/traceroute/manifest.yml b/x-pack/filebeat/module/zeek/traceroute/manifest.yml index 0761e9b3bf4..b357530bb1b 100644 --- a/x-pack/filebeat/module/zeek/traceroute/manifest.yml +++ b/x-pack/filebeat/module/zeek/traceroute/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/traceroute.log - name: tags default: [zeek.traceroute] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/traceroute.yml diff --git a/x-pack/filebeat/module/zeek/traceroute/test/traceroute-json.log-expected.json b/x-pack/filebeat/module/zeek/traceroute/test/traceroute-json.log-expected.json index 34d600174ac..89e3ebcbe09 100644 --- a/x-pack/filebeat/module/zeek/traceroute/test/traceroute-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/traceroute/test/traceroute-json.log-expected.json @@ -22,6 +22,7 @@ "fileset.name": "traceroute", "input.type": "log", "log.offset": 0, + "network.direction": "outbound", "network.transport": "udp", "related.ip": [ "192.168.1.1", diff --git a/x-pack/filebeat/module/zeek/tunnel/config/tunnel.yml b/x-pack/filebeat/module/zeek/tunnel/config/tunnel.yml index 7aa335e79b7..a1aee290083 100644 --- a/x-pack/filebeat/module/zeek/tunnel/config/tunnel.yml +++ b/x-pack/filebeat/module/zeek/tunnel/config/tunnel.yml @@ -45,6 +45,13 @@ processors: - {from: "zeek.tunnel.action", to: "event.action"} ignore_missing: true fail_on_error: false +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: event fields: diff --git a/x-pack/filebeat/module/zeek/tunnel/manifest.yml b/x-pack/filebeat/module/zeek/tunnel/manifest.yml index a0618a12b7e..0e36b8914ca 100644 --- a/x-pack/filebeat/module/zeek/tunnel/manifest.yml +++ b/x-pack/filebeat/module/zeek/tunnel/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/tunnel.log - name: tags default: [zeek.tunnel] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/tunnel.yml diff --git a/x-pack/filebeat/module/zeek/tunnel/test/tunnel-json.log-expected.json b/x-pack/filebeat/module/zeek/tunnel/test/tunnel-json.log-expected.json index 7070aaf5b2c..9138243618c 100644 --- a/x-pack/filebeat/module/zeek/tunnel/test/tunnel-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/tunnel/test/tunnel-json.log-expected.json @@ -24,6 +24,7 @@ "fileset.name": "tunnel", "input.type": "log", "log.offset": 0, + "network.direction": "external", "related.ip": [ "132.16.110.133", "132.16.146.79" diff --git a/x-pack/filebeat/module/zeek/weird/config/weird.yml b/x-pack/filebeat/module/zeek/weird/config/weird.yml index a7401372d19..1218c28c129 100644 --- a/x-pack/filebeat/module/zeek/weird/config/weird.yml +++ b/x-pack/filebeat/module/zeek/weird/config/weird.yml @@ -45,6 +45,13 @@ processors: - {from: "zeek.weird.name", to: "rule.name"} ignore_missing: true fail_on_error: false +{{ if .internal_networks }} + - add_network_direction: + source: source.ip + destination: destination.ip + target: network.direction + internal_networks: {{ .internal_networks | tojson }} +{{ end }} - add_fields: target: event fields: diff --git a/x-pack/filebeat/module/zeek/weird/manifest.yml b/x-pack/filebeat/module/zeek/weird/manifest.yml index 3e91c91c64a..18eef40dff6 100644 --- a/x-pack/filebeat/module/zeek/weird/manifest.yml +++ b/x-pack/filebeat/module/zeek/weird/manifest.yml @@ -10,6 +10,8 @@ var: - /usr/local/var/logs/current/weird.log - name: tags default: [zeek.weird] + - name: internal_networks + default: [ private ] ingest_pipeline: ingest/pipeline.yml input: config/weird.yml diff --git a/x-pack/filebeat/module/zeek/weird/test/weird-json.log-expected.json b/x-pack/filebeat/module/zeek/weird/test/weird-json.log-expected.json index cc9f7f49508..2965e9fb098 100644 --- a/x-pack/filebeat/module/zeek/weird/test/weird-json.log-expected.json +++ b/x-pack/filebeat/module/zeek/weird/test/weird-json.log-expected.json @@ -17,6 +17,7 @@ "fileset.name": "weird", "input.type": "log", "log.offset": 0, + "network.direction": "internal", "related.ip": [ "192.168.1.1", "192.168.1.2" From c45aba59df1429f3f6859f61ae5295fae9d22baf Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Tue, 29 Jun 2021 09:12:10 -0500 Subject: [PATCH 08/25] [Filebeat] Fix `threatintel.indicator.url.full` field not populating (#26508) * #26351: Fix Threat Intel Full URL field * update changelog * remove commented items * updated pipelines per comments --- CHANGELOG.next.asciidoc | 1 + .../threatintel/abuseurl/ingest/pipeline.yml | 18 +--- .../test/abusechurl.ndjson.log-expected.json | 100 ++++++++++++++++++ .../threatintel/anomali/ingest/pipeline.yml | 11 +- .../anomali_limo.ndjson.log-expected.json | 85 +++++++++++++++ .../anomalithreatstream/ingest/pipeline.yml | 5 + .../test/generated.log-expected.json | 25 +++++ .../threatintel/misp/ingest/pipeline.yml | 23 ++-- .../test/misp_sample.ndjson.log-expected.json | 2 + .../threatintel/otx/ingest/pipeline.yml | 15 +-- .../otx/test/otx_sample.ndjson.log | 3 + .../test/otx_sample.ndjson.log-expected.json | 65 ++++++++++++ 12 files changed, 312 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1250f7ff555..c535654c921 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -388,6 +388,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add improvements to the azure activitylogs and platformlogs ingest pipelines. {pull}26148[26148] - Fix `kibana.log` pipeline when `event.duration` calculation becomes a Long. {issue}24556[24556] {pull}25675[25675] - Removed incorrect `http.request.referrer` field from `aws.elb` module. {issue}26435[26435] {pull}26441[26441] +- Fix `threatintel.indicator.url.full` not being populated. {issue}26351[26351] {pull}26508[26508] *Heartbeat* diff --git a/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml index ed2ebeda10d..95759247e93 100644 --- a/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/abuseurl/ingest/pipeline.yml @@ -31,14 +31,6 @@ processors: - set: field: threatintel.indicator.type value: url -- set: - field: threatintel.indicator.url.scheme - value: https - if: ctx?.threatintel?.abuseurl?.url.startsWith('https:') -- set: - field: threatintel.indicator.url.scheme - value: http - if: ctx?.threatintel?.abuseurl?.url.startsWith('http:') - date: field: threatintel.abuseurl.date_added target_field: threatintel.indicator.first_seen @@ -51,11 +43,10 @@ processors: target_field: threatintel.indicator.url keep_original: true remove_if_successful: true -- rename: - field: threatintel.abuseurl.url - target_field: threatintel.indicator.url.full - ignore_missing: true - if: ctx?.threatintel?.indicator?.url?.original == null && ctx?.threatintel?.abuseurl?.url != null +- set: + field: threatintel.indicator.url.full + copy_from: threatintel.indicator.url.original + ignore_empty_value: true - rename: field: threatintel.abuseurl.host target_field: threatintel.indicator.domain @@ -65,7 +56,6 @@ processors: target_field: event.reference ignore_missing: true - # Host can be both IP addresses and domain names - grok: field: threatintel.abuseurl.host 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 e0c47170106..a37eb5f45de 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 @@ -30,6 +30,7 @@ "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, @@ -66,6 +67,7 @@ "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, @@ -102,6 +104,7 @@ "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, @@ -138,6 +141,7 @@ "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, @@ -174,6 +178,7 @@ "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, @@ -210,6 +215,7 @@ "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, @@ -246,6 +252,7 @@ "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, @@ -282,6 +289,7 @@ "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, @@ -318,6 +326,7 @@ "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, @@ -354,6 +363,7 @@ "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, @@ -390,6 +400,7 @@ "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, @@ -426,6 +437,7 @@ "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, @@ -462,6 +474,7 @@ "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, @@ -498,6 +511,7 @@ "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, @@ -534,6 +548,7 @@ "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, @@ -570,6 +585,7 @@ "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, @@ -606,6 +622,7 @@ "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, @@ -642,6 +659,7 @@ "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, @@ -678,6 +696,7 @@ "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, @@ -714,6 +733,7 @@ "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, @@ -750,6 +770,7 @@ "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, @@ -786,6 +807,7 @@ "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, @@ -822,6 +844,7 @@ "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, @@ -858,6 +881,7 @@ "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, @@ -893,6 +917,7 @@ "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, @@ -928,6 +953,7 @@ "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, @@ -963,6 +989,7 @@ "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, @@ -998,6 +1025,7 @@ "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, @@ -1033,6 +1061,7 @@ "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, @@ -1068,6 +1097,7 @@ "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, @@ -1104,6 +1134,7 @@ "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, @@ -1141,6 +1172,7 @@ "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, @@ -1177,6 +1209,7 @@ "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, @@ -1212,6 +1245,7 @@ "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, @@ -1247,6 +1281,7 @@ "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, @@ -1282,6 +1317,7 @@ "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, @@ -1317,6 +1353,7 @@ "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, @@ -1352,6 +1389,7 @@ "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, @@ -1388,6 +1426,7 @@ "threatintel.indicator.provider": "geenensp", "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, @@ -1423,6 +1462,7 @@ "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, @@ -1459,6 +1499,7 @@ "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, @@ -1495,6 +1536,7 @@ "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, @@ -1531,6 +1573,7 @@ "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, @@ -1567,6 +1610,7 @@ "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, @@ -1603,6 +1647,7 @@ "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, @@ -1639,6 +1684,7 @@ "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, @@ -1675,6 +1721,7 @@ "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, @@ -1711,6 +1758,7 @@ "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, @@ -1747,6 +1795,7 @@ "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, @@ -1783,6 +1832,7 @@ "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, @@ -1819,6 +1869,7 @@ "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, @@ -1855,6 +1906,7 @@ "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, @@ -1891,6 +1943,7 @@ "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, @@ -1926,6 +1979,7 @@ "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" @@ -1960,6 +2014,7 @@ "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" @@ -1994,6 +2049,7 @@ "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" @@ -2028,6 +2084,7 @@ "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" @@ -2062,6 +2119,7 @@ "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" @@ -2096,6 +2154,7 @@ "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" @@ -2130,6 +2189,7 @@ "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" @@ -2164,6 +2224,7 @@ "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" @@ -2198,6 +2259,7 @@ "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" @@ -2232,6 +2294,7 @@ "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" @@ -2266,6 +2329,7 @@ "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" @@ -2300,6 +2364,7 @@ "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" @@ -2334,6 +2399,7 @@ "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" @@ -2368,6 +2434,7 @@ "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" @@ -2402,6 +2469,7 @@ "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" @@ -2436,6 +2504,7 @@ "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" @@ -2470,6 +2539,7 @@ "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" @@ -2504,6 +2574,7 @@ "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" @@ -2538,6 +2609,7 @@ "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" @@ -2572,6 +2644,7 @@ "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" @@ -2606,6 +2679,7 @@ "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" @@ -2640,6 +2714,7 @@ "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" @@ -2674,6 +2749,7 @@ "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" @@ -2708,6 +2784,7 @@ "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" @@ -2742,6 +2819,7 @@ "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" @@ -2776,6 +2854,7 @@ "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" @@ -2810,6 +2889,7 @@ "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" @@ -2844,6 +2924,7 @@ "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" @@ -2878,6 +2959,7 @@ "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" @@ -2912,6 +2994,7 @@ "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" @@ -2946,6 +3029,7 @@ "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" @@ -2980,6 +3064,7 @@ "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" @@ -3014,6 +3099,7 @@ "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" @@ -3048,6 +3134,7 @@ "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" @@ -3082,6 +3169,7 @@ "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" @@ -3116,6 +3204,7 @@ "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" @@ -3150,6 +3239,7 @@ "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" @@ -3184,6 +3274,7 @@ "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" @@ -3218,6 +3309,7 @@ "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" @@ -3252,6 +3344,7 @@ "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" @@ -3286,6 +3379,7 @@ "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" @@ -3320,6 +3414,7 @@ "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" @@ -3354,6 +3449,7 @@ "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" @@ -3388,6 +3484,7 @@ "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" @@ -3422,6 +3519,7 @@ "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" @@ -3456,6 +3554,7 @@ "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" @@ -3490,6 +3589,7 @@ "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" diff --git a/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml index 239cbc608f5..963671c0cb0 100644 --- a/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/anomali/ingest/pipeline.yml @@ -65,7 +65,7 @@ processors: if: "ctx?.threatintel?.anomali?.valid_from != null" - grok: field: threatintel.anomali.pattern - patterns: + patterns: - "^\\[%{DATA:_tmp.threattype}:value%{SPACE}=%{SPACE}'%{DATA:_tmp.threatvalue}'\\]" - rename: field: _tmp.threattype @@ -82,11 +82,10 @@ processors: keep_original: true remove_if_successful: true if: ctx?.threatintel?.indicator?.type == 'url' -- rename: - field: _tmp.threatvalue - target_field: threatintel.indicator.url.full - ignore_missing: true - if: ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.indicator?.url?.original == null +- set: + field: threatintel.indicator.url.full + copy_from: threatintel.indicator.url.original + ignore_empty_value: true - rename: field: _tmp.threatvalue target_field: threatintel.indicator.email.address 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 d647be09675..1adbe043c7c 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 @@ -31,6 +31,7 @@ "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" @@ -67,6 +68,7 @@ "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" @@ -102,6 +104,7 @@ "threatintel.anomali.valid_from": "2020-01-22T02:58:57.570Z", "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" @@ -137,6 +140,7 @@ "threatintel.anomali.valid_from": "2020-01-22T02:58:59.366Z", "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" @@ -173,6 +177,7 @@ "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" @@ -209,6 +214,7 @@ "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" @@ -277,6 +283,7 @@ "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" @@ -313,6 +320,7 @@ "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" @@ -348,6 +356,7 @@ "threatintel.anomali.valid_from": "2020-01-22T02:59:25.626Z", "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" @@ -416,6 +425,7 @@ "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" @@ -451,6 +461,7 @@ "threatintel.anomali.valid_from": "2020-01-22T02:59:41.228Z", "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" @@ -550,6 +561,7 @@ "threatintel.anomali.valid_from": "2020-01-22T02:59:51.442Z", "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" @@ -586,6 +598,7 @@ "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" @@ -622,6 +635,7 @@ "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" @@ -658,6 +672,7 @@ "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" @@ -694,6 +709,7 @@ "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" @@ -730,6 +746,7 @@ "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" @@ -766,6 +783,7 @@ "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" @@ -802,6 +820,7 @@ "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" @@ -838,6 +857,7 @@ "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" @@ -874,6 +894,7 @@ "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" @@ -941,6 +962,7 @@ "threatintel.anomali.valid_from": "2020-01-22T03:00:57.729Z", "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" @@ -977,6 +999,7 @@ "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" @@ -1013,6 +1036,7 @@ "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" @@ -1049,6 +1073,7 @@ "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" @@ -1117,6 +1142,7 @@ "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" @@ -1185,6 +1211,7 @@ "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" @@ -1220,6 +1247,7 @@ "threatintel.anomali.valid_from": "2020-01-22T03:02:52.496Z", "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" @@ -1256,6 +1284,7 @@ "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" @@ -1292,6 +1321,7 @@ "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" @@ -1328,6 +1358,7 @@ "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" @@ -1363,6 +1394,7 @@ "threatintel.anomali.valid_from": "2020-01-22T03:04:32.717Z", "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" @@ -1398,6 +1430,7 @@ "threatintel.anomali.valid_from": "2020-01-22T03:04:56.858Z", "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" @@ -1434,6 +1467,7 @@ "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" @@ -1502,6 +1536,7 @@ "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" @@ -1538,6 +1573,7 @@ "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" @@ -1574,6 +1610,7 @@ "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" @@ -1609,6 +1646,7 @@ "threatintel.anomali.valid_from": "2020-01-23T03:02:47.364Z", "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" @@ -1645,6 +1683,7 @@ "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" @@ -1681,6 +1720,7 @@ "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" @@ -1717,6 +1757,7 @@ "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" @@ -1753,6 +1794,7 @@ "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" @@ -1820,6 +1862,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:57:04.883Z", "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" @@ -1856,6 +1899,7 @@ "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" @@ -1892,6 +1936,7 @@ "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" @@ -1928,6 +1973,7 @@ "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" @@ -1963,6 +2009,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:57:32.929Z", "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" @@ -1999,6 +2046,7 @@ "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" @@ -2035,6 +2083,7 @@ "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" @@ -2071,6 +2120,7 @@ "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" @@ -2107,6 +2157,7 @@ "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" @@ -2142,6 +2193,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:58:32.126Z", "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" @@ -2177,6 +2229,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:58:37.603Z", "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" @@ -2212,6 +2265,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:58:37.643Z", "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" @@ -2247,6 +2301,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:58:39.465Z", "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" @@ -2315,6 +2370,7 @@ "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" @@ -2382,6 +2438,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:59:50.233Z", "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" @@ -2418,6 +2475,7 @@ "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" @@ -2453,6 +2511,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:59:52.536Z", "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" @@ -2488,6 +2547,7 @@ "threatintel.anomali.valid_from": "2020-01-24T02:59:54.784Z", "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" @@ -2588,6 +2648,7 @@ "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" @@ -2623,6 +2684,7 @@ "threatintel.anomali.valid_from": "2020-01-24T03:00:10.928Z", "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" @@ -2659,6 +2721,7 @@ "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" @@ -2694,6 +2757,7 @@ "threatintel.anomali.valid_from": "2020-01-24T03:00:24.048Z", "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" @@ -2730,6 +2794,7 @@ "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" @@ -2765,6 +2830,7 @@ "threatintel.anomali.valid_from": "2020-01-24T03:01:10.501Z", "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" @@ -2800,6 +2866,7 @@ "threatintel.anomali.valid_from": "2020-01-24T03:01:10.518Z", "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" @@ -2867,6 +2934,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:12.699Z", "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" @@ -2902,6 +2970,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:28.034Z", "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" @@ -2938,6 +3007,7 @@ "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" @@ -2973,6 +3043,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:38.214Z", "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" @@ -3008,6 +3079,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:47.281Z", "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, @@ -3044,6 +3116,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:51.296Z", "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" @@ -3080,6 +3153,7 @@ "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" @@ -3115,6 +3189,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:57:56.044Z", "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" @@ -3151,6 +3226,7 @@ "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" @@ -3186,6 +3262,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:58:20.420Z", "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" @@ -3222,6 +3299,7 @@ "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" @@ -3258,6 +3336,7 @@ "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" @@ -3293,6 +3372,7 @@ "threatintel.anomali.valid_from": "2020-01-25T02:58:49.056Z", "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" @@ -3329,6 +3409,7 @@ "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" @@ -3365,6 +3446,7 @@ "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" @@ -3401,6 +3483,7 @@ "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" @@ -3437,6 +3520,7 @@ "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" @@ -3505,6 +3589,7 @@ "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" diff --git a/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml index 6d4658c0504..75854beaecc 100644 --- a/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/anomalithreatstream/ingest/pipeline.yml @@ -263,6 +263,11 @@ processors: field: error.message value: 'Cannot parse url field `{{{ json.url }}}`: {{{ _ingest.on_failure_message }}}' +- set: + field: threatintel.indicator.url.full + copy_from: threatintel.indicator.url.original + ignore_empty_value: true + - rename: field: json.country target_field: threatintel.indicator.geo.country_iso_code 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 feab4d23952..fa19350c1b2 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 @@ -380,6 +380,7 @@ "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", @@ -426,6 +427,7 @@ "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", @@ -550,6 +552,7 @@ "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", @@ -989,6 +992,7 @@ "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", @@ -1191,6 +1195,7 @@ "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", @@ -1236,6 +1241,7 @@ "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", @@ -1596,6 +1602,7 @@ "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", @@ -1757,6 +1764,7 @@ "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", @@ -1841,6 +1849,7 @@ "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", @@ -1885,6 +1894,7 @@ "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-", @@ -2089,6 +2099,7 @@ "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", @@ -2252,6 +2263,7 @@ "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", @@ -2491,6 +2503,7 @@ "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", @@ -2811,6 +2824,7 @@ "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", @@ -2970,6 +2984,7 @@ "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", @@ -3130,6 +3145,7 @@ "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", @@ -3258,6 +3274,7 @@ "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", @@ -3304,6 +3321,7 @@ "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", @@ -3434,6 +3452,7 @@ "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", @@ -3480,6 +3499,7 @@ "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", @@ -3531,6 +3551,7 @@ "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", @@ -3577,6 +3598,7 @@ "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", @@ -3714,6 +3736,7 @@ "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", @@ -3758,6 +3781,7 @@ "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", @@ -3804,6 +3828,7 @@ "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", diff --git a/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml index 14868f968d3..365b63d9397 100644 --- a/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/misp/ingest/pipeline.yml @@ -110,13 +110,13 @@ processors: if: "ctx?.threatintel?.indicator?.type == 'file' && ctx?.threatintel?.misp?.attribute?.type == 'filename'" - grok: field: threatintel.misp.attribute.type - patterns: + patterns: - "%{WORD}\\|%{WORD:_tmp.hashtype}" ignore_missing: true if: ctx?.threatintel?.misp?.attribute?.type.startsWith('filename|') - grok: field: threatintel.misp.attribute.value - patterns: + patterns: - "%{DATA:threatintel.indicator.file.name}\\|%{GREEDYDATA:_tmp.hashvalue}" ignore_missing: true if: ctx?.threatintel?.misp?.attribute?.type.startsWith('filename|') @@ -136,11 +136,12 @@ processors: keep_original: true remove_if_successful: true if: ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.misp?.attribute?.type != 'uri' -- rename: - field: threatintel.misp.attribute.value - target_field: threatintel.indicator.url.full - ignore_missing: true - if: "ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.indicator?.url?.original == null && ctx?.threatintel?.misp?.attribute?.type != 'uri'" + +- set: + field: threatintel.indicator.url.full + copy_from: threatintel.indicator.url.original + ignore_empty_value: true + if: "ctx?.threatintel?.indicator?.type == 'url' && ctx?.threatintel?.misp?.attribute?.type != 'uri'" ## Regkey indicator operations - set: @@ -154,7 +155,7 @@ processors: if: "ctx?.threatintel?.indicator?.type == 'windows-registry-key' && ctx?.threatintel?.misp?.attribute?.type == 'regkey'" - grok: field: threatintel.misp.attribute.value - patterns: + patterns: - "%{DATA:threatintel.indicator.registry.key}\\|%{DATA:threatintel.indicator.registry.value}" ignore_missing: true if: "ctx?.threatintel?.misp?.attribute?.type == 'regkey|value'" @@ -192,13 +193,13 @@ processors: 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)" - grok: field: threatintel.misp.attribute.value - patterns: + patterns: - "%{DATA:threatintel.indicator.domain}\\|%{IP:threatintel.indicator.ip}" ignore_missing: true if: ctx.threatintel?.misp?.attribute?.type == 'domain|ip' - grok: field: threatintel.misp.attribute.value - patterns: + patterns: - "%{IP:threatintel.indicator.ip}\\|%{NUMBER:threatintel.indicator.port}" ignore_missing: true if: "['ip-src|port', 'ip-dst|port'].contains(ctx.threatintel?.misp?.attribute?.type)" @@ -245,7 +246,7 @@ processors: .filter(t -> t.startsWith('tlp:')) .map(t -> t.replace('tlp:', '')) .collect(Collectors.toList()); - + ctx.tags = tags; ctx.threatintel.indicator.marking = [ 'tlp': tlpTags ]; 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 06d0b79dc22..45edea74815 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 @@ -138,6 +138,7 @@ "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", @@ -527,6 +528,7 @@ "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=", diff --git a/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml b/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml index a4a16035111..234d01bae62 100644 --- a/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml +++ b/x-pack/filebeat/module/threatintel/otx/ingest/pipeline.yml @@ -85,16 +85,11 @@ processors: keep_original: true remove_if_successful: true if: ctx?.threatintel?.indicator?.type == 'url' -- rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.url.full - ignore_missing: true - if: "ctx?.threatintel?.otx?.type == 'URL' && ctx?.threatintel?.indicator?.url?.original == null" -- rename: - field: threatintel.otx.indicator - target_field: threatintel.indicator.url.path - ignore_missing: true - if: "ctx?.threatintel?.otx?.type == 'URI'" +- set: + field: threatintel.indicator.url.full + copy_from: threatintel.indicator.url.original + ignore_empty_value: true + if: "ctx?.threatintel?.otx?.type == 'URL'" ## Email indicator operations - set: diff --git a/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log b/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log index cec2590a82b..22ed47e12f4 100644 --- a/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log +++ b/x-pack/filebeat/module/threatintel/otx/test/otx_sample.ndjson.log @@ -78,3 +78,6 @@ {"indicator":"36.89.106.69","description":null,"title":null,"content":"","type":"IPv4","id":2189036446} {"indicator":"96.9.73.73","description":null,"title":null,"content":"","type":"IPv4","id":2190596263} {"indicator":"10ec3571596c30b9993b89f12d29d23c","description":"MD5 of 9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6","title":"xor_0x20_xord_javascript","content":"","type":"FileHash-MD5","id":2192837907} +{"id":73,"indicator":"http://www.playboysplus.com","type":"URL","title":null,"description":null,"content":""} +{"id":74,"indicator":"http://join.playboysplus.com/signup/","type":"URL","title":null,"description":null,"content":""} +{"id":970,"indicator":"http://api.vk.com/method/wall.get?count=1&owner_id=-81972386","type":"URL","title":null,"description":null,"content":""} 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 0b8ce8ddb19..8a8564626d5 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 @@ -1409,5 +1409,70 @@ "threatintel.indicator.type": "file", "threatintel.otx.description": "MD5 of 9af8a93519d22ed04ffb9ccf6861c9df1b77dc5d22e0aeaff4a582dbf8660ba6", "threatintel.otx.title": "xor_0x20_xord_javascript" + }, + { + "event.category": "threat", + "event.dataset": "threatintel.otx", + "event.kind": "enrichment", + "event.module": "threatintel", + "event.type": "indicator", + "fileset.name": "otx", + "input.type": "log", + "log.offset": 12786, + "service.type": "threatintel", + "tags": [ + "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" + }, + { + "event.category": "threat", + "event.dataset": "threatintel.otx", + "event.kind": "enrichment", + "event.module": "threatintel", + "event.type": "indicator", + "fileset.name": "otx", + "input.type": "log", + "log.offset": 12896, + "service.type": "threatintel", + "tags": [ + "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" + }, + { + "event.category": "threat", + "event.dataset": "threatintel.otx", + "event.kind": "enrichment", + "event.module": "threatintel", + "event.type": "indicator", + "fileset.name": "otx", + "input.type": "log", + "log.offset": 13015, + "service.type": "threatintel", + "tags": [ + "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" } ] \ No newline at end of file From 2a56cd7fe026c5b59e76e47e397041f765125700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 29 Jun 2021 16:40:26 +0200 Subject: [PATCH 09/25] Move parsers outside of filestream input so others can use them as well (#26541) ## What does this PR do? The object has its own `Unpack` function, so it is enough for you to add it as an attribute to your configuration. ```golang config parser.Config ``` Then create the parser based on the configuration ```golang p = inp.parserConfig.Create(r) ``` Example configuration accepted by the code above ```yaml parsers: - multiline: type: count lines_count: 3 ``` --- filebeat/input/filestream/config.go | 8 +- filebeat/input/filestream/input.go | 9 +- .../reader/parser}/parser.go | 81 +++++++++++----- libbeat/reader/parser/parser_example_test.go | 94 +++++++++++++++++++ .../reader/parser}/parser_test.go | 61 ++++++------ 5 files changed, 186 insertions(+), 67 deletions(-) rename {filebeat/input/filestream => libbeat/reader/parser}/parser.go (68%) create mode 100644 libbeat/reader/parser/parser_example_test.go rename {filebeat/input/filestream => libbeat/reader/parser}/parser_test.go (88%) diff --git a/filebeat/input/filestream/config.go b/filebeat/input/filestream/config.go index 007da10a045..9020093ba4a 100644 --- a/filebeat/input/filestream/config.go +++ b/filebeat/input/filestream/config.go @@ -25,6 +25,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/match" + "github.com/elastic/beats/v7/libbeat/reader/parser" "github.com/elastic/beats/v7/libbeat/reader/readfile" ) @@ -71,7 +72,7 @@ type readerConfig struct { MaxBytes int `config:"message_max_bytes" validate:"min=0,nonzero"` Tail bool `config:"seek_to_tail"` - Parsers []common.ConfigNamespace `config:"parsers"` + Parsers parser.Config `config:",inline"` } type backoffConfig struct { @@ -127,7 +128,6 @@ func defaultReaderConfig() readerConfig { LineTerminator: readfile.AutoLineTerminator, MaxBytes: 10 * humanize.MiByte, Tail: false, - Parsers: make([]common.ConfigNamespace, 0), } } @@ -136,9 +136,5 @@ func (c *config) Validate() error { return fmt.Errorf("no path is configured") } - if err := validateParserConfig(parserConfig{maxBytes: c.Reader.MaxBytes, lineTerminator: c.Reader.LineTerminator}, c.Reader.Parsers); err != nil { - return fmt.Errorf("cannot parse parser configuration: %+v", err) - } - return nil } diff --git a/filebeat/input/filestream/input.go b/filebeat/input/filestream/input.go index e143280e5b9..48d5f6dca77 100644 --- a/filebeat/input/filestream/input.go +++ b/filebeat/input/filestream/input.go @@ -35,6 +35,7 @@ import ( "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/reader" "github.com/elastic/beats/v7/libbeat/reader/debug" + "github.com/elastic/beats/v7/libbeat/reader/parser" "github.com/elastic/beats/v7/libbeat/reader/readfile" "github.com/elastic/beats/v7/libbeat/reader/readfile/encoding" ) @@ -57,7 +58,7 @@ type filestream struct { encodingFactory encoding.EncodingFactory encoding encoding.Encoding closerConfig closerConfig - parserConfig []common.ConfigNamespace + parsers parser.Config } // Plugin creates a new filestream input plugin for creating a stateful input. @@ -97,6 +98,7 @@ func configure(cfg *common.Config) (loginp.Prospector, loginp.Harvester, error) readerConfig: config.Reader, encodingFactory: encodingFactory, closerConfig: config.Close, + parsers: config.Reader.Parsers, } return prospector, filestream, nil @@ -219,10 +221,7 @@ func (inp *filestream) open(log *logp.Logger, canceler input.Canceler, fs fileSo r = readfile.NewFilemeta(r, fs.newPath) - r, err = newParsers(r, parserConfig{maxBytes: inp.readerConfig.MaxBytes, lineTerminator: inp.readerConfig.LineTerminator}, inp.readerConfig.Parsers) - if err != nil { - return nil, err - } + r = inp.parsers.Create(r) r = readfile.NewLimitReader(r, inp.readerConfig.MaxBytes) diff --git a/filebeat/input/filestream/parser.go b/libbeat/reader/parser/parser.go similarity index 68% rename from filebeat/input/filestream/parser.go rename to libbeat/reader/parser/parser.go index c64b8981ae4..fa01181c2aa 100644 --- a/filebeat/input/filestream/parser.go +++ b/libbeat/reader/parser/parser.go @@ -15,13 +15,15 @@ // specific language governing permissions and limitations // under the License. -package filestream +package parser import ( "errors" "fmt" "io" + "github.com/dustin/go-humanize" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/reader" "github.com/elastic/beats/v7/libbeat/reader/multiline" @@ -35,20 +37,48 @@ var ( // parser transforms or translates the Content attribute of a Message. // They are able to aggregate two or more Messages into a single one. -type parser interface { +type Parser interface { io.Closer Next() (reader.Message, error) } -type parserConfig struct { - maxBytes int - lineTerminator readfile.LineTerminator +type CommonConfig struct { + MaxBytes int `config:"max_bytes"` + LineTerminator readfile.LineTerminator `config:"line_terminator"` } -func newParsers(in reader.Reader, pCfg parserConfig, c []common.ConfigNamespace) (parser, error) { - p := in +type Config struct { + pCfg CommonConfig + parsers []common.ConfigNamespace +} + +func (c *Config) Unpack(cc *common.Config) error { + tmp := struct { + Common CommonConfig `config:",inline"` + Parsers []common.ConfigNamespace `config:"parsers"` + }{ + CommonConfig{ + MaxBytes: 10 * humanize.MiByte, + LineTerminator: readfile.AutoLineTerminator, + }, + nil, + } + err := cc.Unpack(&tmp) + if err != nil { + return err + } - for _, ns := range c { + newC, err := NewConfig(tmp.Common, tmp.Parsers) + if err != nil { + return err + } + *c = *newC + + return nil +} + +func NewConfig(pCfg CommonConfig, parsers []common.ConfigNamespace) (*Config, error) { + for _, ns := range parsers { name := ns.Name() switch name { case "multiline": @@ -58,10 +88,6 @@ func newParsers(in reader.Reader, pCfg parserConfig, c []common.ConfigNamespace) if err != nil { return nil, fmt.Errorf("error while parsing multiline parser config: %+v", err) } - p, err = multiline.New(p, "\n", pCfg.maxBytes, &config) - if err != nil { - return nil, fmt.Errorf("error while creating multiline parser: %+v", err) - } case "ndjson": var config readjson.ParserConfig cfg := ns.Config() @@ -69,7 +95,6 @@ func newParsers(in reader.Reader, pCfg parserConfig, c []common.ConfigNamespace) if err != nil { return nil, fmt.Errorf("error while parsing ndjson parser config: %+v", err) } - p = readjson.NewJSONParser(p, &config) case "container": config := readjson.DefaultContainerConfig() cfg := ns.Config() @@ -77,17 +102,21 @@ func newParsers(in reader.Reader, pCfg parserConfig, c []common.ConfigNamespace) if err != nil { return nil, fmt.Errorf("error while parsing container parser config: %+v", err) } - p = readjson.NewContainerParser(p, &config) default: return nil, fmt.Errorf("%s: %s", ErrNoSuchParser, name) } } - return p, nil + return &Config{ + pCfg: pCfg, + parsers: parsers, + }, nil + } -func validateParserConfig(pCfg parserConfig, c []common.ConfigNamespace) error { - for _, ns := range c { +func (c *Config) Create(in reader.Reader) Parser { + p := in + for _, ns := range c.parsers { name := ns.Name() switch name { case "multiline": @@ -95,26 +124,32 @@ func validateParserConfig(pCfg parserConfig, c []common.ConfigNamespace) error { cfg := ns.Config() err := cfg.Unpack(&config) if err != nil { - return fmt.Errorf("error while parsing multiline parser config: %+v", err) + return p + } + p, err = multiline.New(p, "\n", c.pCfg.MaxBytes, &config) + if err != nil { + return p } case "ndjson": - var config readjson.Config + var config readjson.ParserConfig cfg := ns.Config() err := cfg.Unpack(&config) if err != nil { - return fmt.Errorf("error while parsing ndjson parser config: %+v", err) + return p } + p = readjson.NewJSONParser(p, &config) case "container": config := readjson.DefaultContainerConfig() cfg := ns.Config() err := cfg.Unpack(&config) if err != nil { - return fmt.Errorf("error while parsing container parser config: %+v", err) + return p } + p = readjson.NewContainerParser(p, &config) default: - return fmt.Errorf("%s: %s", ErrNoSuchParser, name) + return p } } - return nil + return p } diff --git a/libbeat/reader/parser/parser_example_test.go b/libbeat/reader/parser/parser_example_test.go new file mode 100644 index 00000000000..ed8c12e2146 --- /dev/null +++ b/libbeat/reader/parser/parser_example_test.go @@ -0,0 +1,94 @@ +// 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 parser + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/reader/readfile" +) + +type inputParsersConfig struct { + MaxBytes int `config:"max_bytes"` + LineTerminator readfile.LineTerminator `config:"line_terminator"` + Parsers Config `config:",inline"` +} + +func TestParsersExampleInline(t *testing.T) { + tests := map[string]struct { + lines string + parsers map[string]interface{} + expectedMessages []string + }{ + "multiline docker logs parser": { + lines: `{"log":"[log] The following are log messages\n","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} +{"log":"[log] This one is\n","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} +{"log":" on multiple\n","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} +{"log":" lines","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} +{"log":"[log] In total there should be 3 events\n","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} +`, + parsers: map[string]interface{}{ + "max_bytes": 1024, + "line_terminator": "auto", + "parsers": []map[string]interface{}{ + map[string]interface{}{ + "ndjson": map[string]interface{}{ + "keys_under_root": true, + "message_key": "log", + }, + }, + map[string]interface{}{ + "multiline": map[string]interface{}{ + "match": "after", + "negate": true, + "pattern": "^\\[log\\]", + }, + }, + }, + }, + expectedMessages: []string{ + "[log] The following are log messages\n", + "[log] This one is\n\n on multiple\n\n lines", + "[log] In total there should be 3 events\n", + }, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + cfg := common.MustNewConfigFrom(test.parsers) + var c inputParsersConfig + err := cfg.Unpack(&c) + require.NoError(t, err) + + p := c.Parsers.Create(testReader(test.lines)) + + i := 0 + msg, err := p.Next() + for err == nil { + require.Equal(t, test.expectedMessages[i], string(msg.Content)) + i++ + msg, err = p.Next() + } + }) + } +} diff --git a/filebeat/input/filestream/parser_test.go b/libbeat/reader/parser/parser_test.go similarity index 88% rename from filebeat/input/filestream/parser_test.go rename to libbeat/reader/parser/parser_test.go index 696729d1e31..37eba5d15f9 100644 --- a/filebeat/input/filestream/parser_test.go +++ b/libbeat/reader/parser/parser_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package filestream +package parser import ( "io" @@ -40,16 +40,13 @@ func TestParsersConfigAndReading(t *testing.T) { expectedError string }{ "no parser, no error": { - lines: "line 1\nline 2\n", - parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, - }, + lines: "line 1\nline 2\n", + parsers: map[string]interface{}{}, expectedMessages: []string{"line 1\n", "line 2\n"}, }, "correct multiline parser": { lines: "line 1.1\nline 1.2\nline 1.3\nline 2.1\nline 2.2\nline 2.3\n", parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "multiline": map[string]interface{}{ @@ -72,7 +69,6 @@ func TestParsersConfigAndReading(t *testing.T) { {"log":"[log] In total there should be 3 events\n","stream":"stdout","time":"2016-03-02T22:58:51.338462311Z"} `, parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "ndjson": map[string]interface{}{ @@ -97,7 +93,6 @@ func TestParsersConfigAndReading(t *testing.T) { }, "non existent parser configuration": { parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "no_such_parser": nil, @@ -108,7 +103,6 @@ func TestParsersConfigAndReading(t *testing.T) { }, "invalid multiline parser configuration is caught before parser creation": { parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "multiline": map[string]interface{}{ @@ -124,9 +118,11 @@ func TestParsersConfigAndReading(t *testing.T) { for name, test := range tests { test := test t.Run(name, func(t *testing.T) { - cfg := defaultConfig() - parsersConfig := common.MustNewConfigFrom(test.parsers) - err := parsersConfig.Unpack(&cfg) + cfg := common.MustNewConfigFrom(test.parsers) + var parsersConfig testParsersConfig + err := cfg.Unpack(&parsersConfig) + require.NoError(t, err) + c, err := NewConfig(CommonConfig{MaxBytes: 1024, LineTerminator: readfile.AutoLineTerminator}, parsersConfig.Parsers) if test.expectedError == "" { require.NoError(t, err) } else { @@ -134,7 +130,7 @@ func TestParsersConfigAndReading(t *testing.T) { return } - p, err := newParsers(testReader(test.lines), parserConfig{lineTerminator: readfile.AutoLineTerminator, maxBytes: 64}, cfg.Reader.Parsers) + p := c.Create(testReader(test.lines)) i := 0 msg, err := p.Next() @@ -157,9 +153,7 @@ func TestJSONParsersWithFields(t *testing.T) { message: reader.Message{ Content: []byte("line 1"), }, - config: map[string]interface{}{ - "paths": []string{"dummy_path"}, - }, + config: map[string]interface{}{}, expectedMessage: reader.Message{ Content: []byte("line 1"), }, @@ -170,7 +164,6 @@ func TestJSONParsersWithFields(t *testing.T) { Fields: common.MapStr{}, }, config: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "ndjson": map[string]interface{}{ @@ -192,7 +185,6 @@ func TestJSONParsersWithFields(t *testing.T) { Fields: common.MapStr{}, }, config: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "ndjson": map[string]interface{}{ @@ -221,7 +213,6 @@ func TestJSONParsersWithFields(t *testing.T) { }, }, config: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "ndjson": map[string]interface{}{ @@ -244,12 +235,13 @@ func TestJSONParsersWithFields(t *testing.T) { for name, test := range tests { test := test t.Run(name, func(t *testing.T) { - cfg := defaultConfig() - common.MustNewConfigFrom(test.config).Unpack(&cfg) - p, err := newParsers(msgReader(test.message), parserConfig{lineTerminator: readfile.AutoLineTerminator, maxBytes: 64}, cfg.Reader.Parsers) - if err != nil { - t.Fatalf("failed to init parser: %+v", err) - } + cfg := common.MustNewConfigFrom(test.config) + var parsersConfig testParsersConfig + err := cfg.Unpack(&parsersConfig) + require.NoError(t, err) + c, err := NewConfig(CommonConfig{MaxBytes: 1024, LineTerminator: readfile.AutoLineTerminator}, parsersConfig.Parsers) + require.NoError(t, err) + p := c.Create(msgReader(test.message)) msg, _ := p.Next() require.Equal(t, test.expectedMessage, msg) @@ -271,7 +263,6 @@ func TestContainerParser(t *testing.T) { {"log":"patching file vendor/github.com/tsg/gopacket/pcap/pcap.go\n","stream":"stdout","time":"2016-03-02T22:59:04.626534779Z"} `, parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "container": map[string]interface{}{}, @@ -309,7 +300,6 @@ func TestContainerParser(t *testing.T) { lines: `2017-09-12T22:32:21.212861448Z stdout F 2017-09-12 22:32:21.212 [INFO][88] table.go 710: Invalidating dataplane cache `, parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "container": map[string]interface{}{ @@ -333,7 +323,6 @@ func TestContainerParser(t *testing.T) { {"log":"Execute /scripts/packetbeat_before_build.sh\n","stream":"stdout","time":"2016-03-02T22:59:04.617434682Z"} `, parsers: map[string]interface{}{ - "paths": []string{"dummy_path"}, "parsers": []map[string]interface{}{ map[string]interface{}{ "container": map[string]interface{}{}, @@ -360,12 +349,13 @@ func TestContainerParser(t *testing.T) { for name, test := range tests { test := test t.Run(name, func(t *testing.T) { - cfg := defaultConfig() - parsersConfig := common.MustNewConfigFrom(test.parsers) - err := parsersConfig.Unpack(&cfg) + cfg := common.MustNewConfigFrom(test.parsers) + var parsersConfig testParsersConfig + err := cfg.Unpack(&parsersConfig) require.NoError(t, err) - - p, err := newParsers(testReader(test.lines), parserConfig{lineTerminator: readfile.AutoLineTerminator, maxBytes: 1024}, cfg.Reader.Parsers) + c, err := NewConfig(CommonConfig{MaxBytes: 1024, LineTerminator: readfile.AutoLineTerminator}, parsersConfig.Parsers) + require.NoError(t, err) + p := c.Create(testReader(test.lines)) i := 0 msg, err := p.Next() @@ -378,6 +368,11 @@ func TestContainerParser(t *testing.T) { }) } } + +type testParsersConfig struct { + Parsers []common.ConfigNamespace `struct:"parsers"` +} + func testReader(lines string) reader.Reader { encF, _ := encoding.FindEncoding("") reader := strings.NewReader(lines) From 890e473d041942542dd2958503d9a5d68fd52ed4 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Tue, 29 Jun 2021 10:44:33 -0500 Subject: [PATCH 10/25] [Filebeat] Update Fortinet Ingest Pipeline (#24816) * 22136: Update Fortinet Ingest Pipeline * Update Pipelines * Additional updates * Set virus/ips subtypes to event.kind: alert * update fields * Consolidate processors to script * Update event.outcome logic * replace hashmap * update event.outcome * cleanup * Added Changes for #25254 * regenerate data * update changelog * remove extra items in changelog --- CHANGELOG.next.asciidoc | 2 + filebeat/docs/fields.asciidoc | 20 + x-pack/filebeat/module/fortinet/fields.go | 2 +- .../module/fortinet/firewall/_meta/fields.yml | 10 + .../module/fortinet/firewall/ingest/event.yml | 39 +- .../fortinet/firewall/ingest/pipeline.yml | 132 +- .../fortinet/firewall/ingest/traffic.yml | 46 +- .../module/fortinet/firewall/ingest/utm.yml | 70 +- .../module/fortinet/firewall/test/event.log | 27 + .../firewall/test/event.log-expected.json | 1179 +++++++++ .../fortinet/firewall/test/fortinet.log | 40 - .../firewall/test/fortinet.log-expected.json | 2274 ----------------- .../module/fortinet/firewall/test/traffic.log | 13 + .../firewall/test/traffic.log-expected.json | 1079 ++++++++ .../module/fortinet/firewall/test/utm.log | 28 + .../firewall/test/utm.log-expected.json | 1894 ++++++++++++++ .../fortinet/fortimail/ingest/pipeline.yml | 5 + .../test/generated.log-expected.json | 100 + .../fortinet/fortimanager/ingest/pipeline.yml | 5 + .../test/generated.log-expected.json | 100 + 20 files changed, 4630 insertions(+), 2435 deletions(-) create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/event.log create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/event.log-expected.json delete mode 100644 x-pack/filebeat/module/fortinet/firewall/test/fortinet.log delete mode 100644 x-pack/filebeat/module/fortinet/firewall/test/fortinet.log-expected.json create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/traffic.log create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/traffic.log-expected.json create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/utm.log create mode 100644 x-pack/filebeat/module/fortinet/firewall/test/utm.log-expected.json diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index c535654c921..7c5ca82d7dd 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -104,6 +104,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix parsing issues with nested JSON payloads in Elasticsearch audit log fileset. {pull}22975[22975] - Rename `network.direction` values in crowdstrike/falcon to `ingress`/`egress`. {pull}23041[23041] - Change logging in logs input to structure logging. Some log message formats have changed. {pull}25299[25299] +- Change source field for `event.action` in `fortinet.firewall` module to `fortinet.firewall.action` instead of `fortinet.firewall.eventtype`. {pull}24816[24816] *Heartbeat* - Add support for screenshot blocks and use newer synthetics flags that only works in newer synthetics betas. {pull}25808[25808] @@ -839,6 +840,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add support for `copytruncate` method when rotating input logs with an external tool in `filestream` input. {pull}23457[23457] - Add `uri_parts` and `user_agent` ingest processors to `aws.elb` module. {issue}26435[26435] {pull}26441[26441] - Added dataset `recordedfuture` to the `threatintel` module to ingest indicators from Recorded Future Connect API {pull}26481[26481] +- Update `fortinet` ingest pipelines. {issue}22136[22136] {issue}25254[25254] {pull}24816[24816] *Heartbeat* diff --git a/filebeat/docs/fields.asciidoc b/filebeat/docs/fields.asciidoc index 099296a099e..8dd67520d2d 100644 --- a/filebeat/docs/fields.asciidoc +++ b/filebeat/docs/fields.asciidoc @@ -62883,6 +62883,16 @@ type: keyword ESP Transform +type: keyword + +-- + +*`fortinet.firewall.eventtype`*:: ++ +-- +UTM Event Type + + type: keyword -- @@ -65363,6 +65373,16 @@ type: integer Security action performed by UTM +type: keyword + +-- + +*`fortinet.firewall.utmref`*:: ++ +-- +Reference to UTM + + type: keyword -- diff --git a/x-pack/filebeat/module/fortinet/fields.go b/x-pack/filebeat/module/fortinet/fields.go index 60f2d21f39d..6220d292baf 100644 --- a/x-pack/filebeat/module/fortinet/fields.go +++ b/x-pack/filebeat/module/fortinet/fields.go @@ -19,5 +19,5 @@ func init() { // AssetFortinet returns asset data. // This is the base64 encoded gzipped contents of module/fortinet. func AssetFortinet() string { - return "eJzsvetzG7eWL/p9/grcfDhxUra84zxmds7M3NJI9rbOyDK35cfUrV3FArsXSURooA2gSTF//S08utlvtSgsSp45+ZBKRHLhh9fCeq8X5AZ2v5OlVIYJMP9EiGGGw+/kzf4vKehEsdwwKX4n//5PhJDq++SdTAsO/0TIkgFP9e/uU/vPCyJoBr8TAWYr1c0JEwbUkiZwYv9efY0QuQG1VczA78Soov6J2eXwu8W3lSqt/T2FJS24mbshfydLyjU0Pu7ALf+5ohkQuSRmDSUwUgEj2zUocJ8ZRZdLlpA11WQBIIhcaFAbSE8681Oa3mMyKyWLfPpU2ou6H9ahFpQ3pjc8+tD4fUPsB8n0qvH38RGGN6yzKx/XTNvvEaZJoSElRpKE5qYI66/olmSgNV3Z/6eGJDIDbSct7ect0oRcyhU5h0SmoPon4mmxNqhDp1PShQ0IM7dTi0w4AEZe/bDk2q15IoUBYbS9H0xoQ4UpYehejIZlhwBMqWl/0EXHPCY7BKGGbNcsWRNKNGjNpCBrZjSh5ArMF2YEaF3u/knnaFST1WtZ8JQI2IAiC6jOXU6VBvIODLXQKFkqmdWGenYpV/rljCY3YPQPHfLnTEFi+O45MQE3JR/AMwt/wkUN5knvQnLYAD9gJbkU7fvZWMlzyBUk1AQkKSyZgJRIwR0sQxccSEbzflSZXs2jXZiRPX4X7vnF+U9kQ3kRbjxLQRi2ZOF0wi1NDOFy5fdLdTbCzY5Z8uG0uO/Z7cipMiwpOFXu92FjTwZPRof0QSel72R0KA+flMEt2Rx3T1793z0Z3xM7Ks6GPOz6ysUfczeR9rY8GXQbegjTQ4emQMtCJUhv78OXDev+PwyZNtRABsI8RXC0SJmZJ5y27vATgQfCqN1TBLa2MtVTBMbEYcBwJaaSczzdk5YCPYR74C7bEiCNqUMNyDV9embti6VZwKLpyCEdIeFhWkRLDulQv0OLGF7FlmnlSKsoalaV3uXzy9WZZqTlIz0reO/lS44hVheCfS1gL0arav7hT7umUnsmRWIfB2rkU9dsB9jNhuGyw/rqntlh2JIltH6fL+WKvN6AMOTaMWdSiBSUVUEUBEbVmfqS3UJKNBhLpPHj5hh6WGEpN6FD+8EKS7UJHdL32pSuJTC+femwg9mZ1z3W5H5rsJYaSV6tn8u3Ups6i+TtE6lBpEysyg9137Gp2ZC+nfVlhxywzo8GF/ZitvmF0DRVllcOXff24nZmb+S3urib37CX97f/uctrVwufN7T5gjek1a1lKaFkxTYgKiPZtysI2CU6zH6Bq4GkT1H4+zY8GoMGDZnv5gq+Iux13XnoNtjNe7Fzq/zaD01m7iI9D9ZsQ8nHXQ4koV0OsgACzKxBkU8Xwvz0G5GKvOGSmp9fkQXV7hSVDrIlWxXKiX53zPsQcfcbnrdzg+IpnxHsC/bXK4llZhvTjsuRv3kDg1RbqlI0oa7G0WrTrq/kxexzQ96jRAGn7S0lRO+0gSw8ogG2pbYGf1K1Xzz7/1KxFROUl79pSit3rAOW/DUSGHEx+/xbzxIE+J2VePgSVIi6qxzj9dkf1K7geOjrswaagjqK7/qtG4pcnD/ES+rx1p2ljsxhvtInbWTjyRzdzkZLQetiL2i5i2JVlzPJOSRGqm+RAdvVe4SYG3vmmCaJXzpILdKGoHop22ILGVnoJ6jxZcniqYiqmdQu2C2Tgix2nU0jRMHXArSxBDXLcr4L+2S/bBk9AZqsiWYpkGd/IWatCvLq119/IFuqiQYQ1SgjK/EkhNcJK6FzKTTgLUXyzZyKRBbCVDaFIlt4pmevsu6lQJ7RhdxAbTGY6I2sLNmbNgpoNnh/km/m2DzyUkHKiracFmOhvuuTHCvDAlsSZv5RvPrLT3/VnqW/zB0DLUH/ozObf1h98JLuQJFX5LVIaK4L7j0rVqW8F1/vo/5A50dPbGXfKD+/Iv9mp/uc/Pwz+TeSSGXlZTeLMOhz8r+4+d/2i0yT5qJ817uFQqbwZHVdsYV5Qjlf0OQGVwL24IQ07tpQ4/UKu4gg0lwyYZxqYqA/wNkdjjkoJZHi0/byoM4hYZQ7xA6pNlJZyVrsvNRhP9hQzlJ/MPpAEbKUhUjtC8PBgWdiFYSjO4MXmzeiQzmGLzBchxG30cAu7Lik6VN55wIcotmfQDIwiiU9WkdQhetfdrqwf+5LJmyffWr2Eq1cltt2Qt7Krd2ars7JBJHKKmNGkhuA/I5FexIv3jeyaEomoPV8w9J5iuV1fV1ynhUIUNS4S57aFazphRumTEG5VdobtnfRY+JgGbNqt/OVu8XwswhX/eKcKMuttTOouEWjagWm+tqdK6EVUtDTo6+Ej4QbXwmF4grqMv6L89L2+gEyaYBch/OeKHAP7WI3xCjtP6Uj5htwvISR5jrnDDOy4Umr85p1xP4nIZtZnot43t2ts29AOOvlqSu1lvCE/PfwMHr2smT8EXz0dlSrHM3OTmdB9k2osMvDslyqtsRL3BP5zYVBFE/D/PHJP1VOEXeqe58ptanKF/uf7BV2L+c4zfyEvPr1N7J1654BFYRy3m8rcEZ9Jybt7UdkCwo8WWoIB6oNkaKVLtJcxEcXE7/tRey5qxhu27B2X6RK3cK5qCZI1kJyudq1HXFLpjpSLCG/kmRNFU2MX0R7qXcOvzOaC1KIENPDGzbzwYza2And3lGP6UQY8V06jSKzQqYUpRtB0e0gT3OctSVW0sRJrN5HIYLNQSZJoUqK2lCRUpUSIVVGOfuzL75Xqqx3fdIQ5XDwEsli0XmS7rVIe9QVmJecLcHNuEfB15BIkQ4I2PvtnmuDaWcZmRATicxyDqb3AAwaUakT4I1iLTZYyzdT5pEO8rUdu/c4Dx3l5skcPH6ZFGYdaZv2+amxYl72UU7pIy38a5FiLLsl+acU2NUWRtiiHb0UMX147cf2CndYFNqNPiUGbk24fGQDStfSKdKxOLCe/X3oYdsBjTXNfZpeIlUKKd47GIJswjOlqxFLGaOMtKm+WPevd18rJbMTR7VwSfk6AUEVk16szwpu2AvDQBGa57zMftnXssmooKu+1FxCuHPvlPqiB+WxasLM95rIrfCeMUOzvG0ZDIjtaBZi9/YZTZI1s9qNTEGfkHeFNk5NqhO1t5KagbhcauDATRplYMulxb2BY0hCbpPLAf3aKViCApH4A0GtaJ2yDUutZOPOQz8juy4Z2cfW4vVP8jZn6mgz3O+n9wXd2pPIDN/5yWrL9Ky8ZkG5AzpuG4246YMmnOeWG1f87KQzZBVOJovYHCjrCHIPpVitf+yr4iTIrwUURztK9nT7U7Tnj1uqiQORDpwbB+6n2IsaUShoLCgCT1tlBuH1XWUYWPM5AtR8jiE95zFZUZPoq+hUEWSl2ivyOCpkS33sfWM6z+W93pxD2eZdfO0QZ8H+gWhVQ4htCKJJR4iPIVjrgmO7nQa0KFmYRGbw0mOolBcXlS2XnRNCRViChgI5cEBgA4oZzNSRkYmVo4ckwJpnZ8zkg5u82Kkd6F/pKtPFUnN+pxwStmR7xadfuvXOnKGaKkFWxo9m6tmAysTI0n3CRGmiSoOTpRd3UJuPtQmfm1p6XROUiry/DqGxTJcBAW27mhu/3KGhLEmdS80iMo5JZ8up0yL1FaZcKH95dwer8BTczPFKF92TFYkiA8WS+/Ki3rkdIYttZGL1TLbqZni25O93Z2obEKlUIWB2dGZy8ccjVK8pXbty8Qck/Xq0BYafC95ZbstBx4F5To9Zq+677oUMWf+BzQQr15pWscVCGkLJOlS86A+g5XI1LwNVHoWplwfx3kz9GDVTGrzvby7cylWtduyjX/CXnCU77NszwhdmDkAori34boAvFxwzbrp/AT8UHBywfnYqhYFbbIm1AnQhvL1uXw+Vpqm2/3KPKuUloL4CMHc8zsmaihXMBWyxecGQ4xK2NVe/E0KMUWxRGKhxiG6MvvbQrbRef/76WYfOaTRmV60cZ2hlK8cWzSmC7fgiD6Yuv/Uoty4DzC5YWXBQ72O+1AbUCbkGvymFBnVCV+BKeYdI96VUJYYO7ZKMl9sT93vif1+rWyEVWSi5tZ+Vfw2yple7ButJX6QzqkxsM11FOLZFJdwp2ckOPdadkjytxEasKyVzCA5FrLf4VBDKQZkqukjtBw1/8+6twD5qRQBcEFKPwJwSIcULBTk4TWYs+sGpDcd8cpJCKXthKn3F7aST414y72Er3T+dmW2ZWQdh2fN6cu4GXLhsE0GkeLGS9r9HXgInpMx7BEfEedOaM/ClA2BByiWx3MEw0Cfkes9T2o0N6plVOIjPfDpfoa0S41NGfbBNGthvWHhKEl5oUx7I8D+dbXI/YdruZMiJDvYNK/i6T4dFoKNLP/6G9Wv0viwTnlD2/V2Kl0V57lAQqrVMmLOX2t3o1Sfdhl2yG/idUJKvd5ollJOU6ZvnJFeuJ8pzAib5vl9Qpooeknt5z4fe59komoEBpUlOtavipV0hB1+LIJFZZrmYbDjtu6k1YJJRcc+/B48l8dX2EOFh8uw7kVledO8gwrZRsmUildsQT5tIkUBunleRFIOL0ZnmsuB8R74WlHvjZyozykTgGqI2EJcDT1fd6hlLXBqZuhUJL5m4gTTkApWB6FQ761RQUOwn31XQTlg6tnG8UxUCldXVOzt5s0QbQAnv/fVj4XqfB8srue6W66mczqAy1m7shG1iDWM6tP78j0vaP0eWtJeM49/xaspv3GjVNVaQFgmQ0nME/eY2DYpRPu95TdEekWs3ZCk2t9/H2gNoX5hBuwAkN/qgkgMxLMZhdPvQraleVzfUioU9WYZFsvaRv2WOTZVmeFZSapUIsxOphjnRKrG/qv6/m2lKLD8XhLmYu0IkHKiyf3KF8PbQQgJhsHaqMrHzbu+DZ35Ft87Tk36xEpktmKjqZtcfrJA2qu7xem2YKvSxLX11acQBGLb4HcdB2nMlzvzovibjsKXUa3DopvFq+byV+eKcXHlO8ywUbiC+215I+rXYfuiXq70B+jFs+TXz88W5W9KQ8laxia71oOmR82GAfgon/hBZXrBlul9J3egdZi37plc3JGh7cWHUji288n3EU2OX/qwamFyc3ynJxrLP3SHJWmCvRLqXaE/Imc/PDPVOuf9gXJp1AFXzGz99F8xxi8JUmZvSVI9RIThovzLSPyhbSTZUMbrgnSxAX5SBCZJzOsAINAiNWh+lsaF1UdWPfGI5lZUwyvxCZvf5+uXFrC1Dk1Ay1lsUhvKyD2woODkXcu9p8SDJhTDkmq0Edcxi4IjmUmEWr/2+w7/sIZ2Vspt0VR3df1ogtbvsTlkqew7O1fuPhImEFylYdhYa2dqfn5Bnr29plnP4ncy8QcSTddz7pN8u4jxzR/dtOuPU/mnpR8b0jRW5D8B1j1S8mhnzKjwNH5i+GXG5GsVWK1B4Lez6l+xz3RcQMDjpdK1AryVP7enxuvpAp9GG6/0IloWu7z1w5WcfvIzxQ1WM4+K8P41ksnc+kVk+P3LclduVEHvl2rh6+54uFi8sHClcfurStZuRaZEMaWlBLH2kqLE68opbSuUqD1i+XuIb6BJHVbql6nEi9LpV9S13peEhspMYKI38zDJRSt7RpKyn3C/cWhZ0VD1GihelgKrGuZDXNaM3tVZAdfTYYG2oKWIJzpU9ijL+aGqHHXwhbwlLXw6/X/ZlLY6B0CL61Cl87O+CRdF/dct3DLn7XueQn3f77h3ynDEhi1g+zloeiV5Fv1OWk8Y0OnQssr9EJoxdmbFxJE45t3yP6CJJQOtlwclrOz5JZAraHomy2G+/ZsFECreRF4AzbQ6TPB/IW9zAThVTJYgFKOffzKhi3EXw9FjwvP9drAh1i/jC/rZ3ZgLhHMqFLy70SBJxGJ08q+I5c1A6D0m3nsN0liyICPuA+LLC0w8DSYbezNV9j7EDSrzwVQV5BVuV/7b9kDKhSQqGMt5jZFjIwtR+NzA1yY8em1labGkVx+ZwDD+kBrKco0XznJIUljS4gELly9KHH6I1rVS8AcXpziVyGRkeV/Ks50baD5zWHX4NyzIL3NvqtWGmcIUZSe/E9rpBt2DTQ69rVC9Wzb6T0NhIEXhVIrPM3iecY3TmqRNWC/bNldyw1NvPyipyGejBQKhUJoc7Gu9vLXvD+F5qTOpxef2iwW3ugp4eh9eXo+Py+j/k4kC708HT+z9yERww/bcrZ3iFc89dQLHf+evZBbnoCFR1GGhVa0N2yTiCiIldVTbsKqoifR97WIit7hfuPYuYL2SKnfHVybhrCx0BC7FYBsSjdfxqCd5lcITM85oJOKQO+wDayh/CViytXDkDRrwsttbYSQOP8PLHE/KqeecF5jNVdveeffLVc0pHlAvWuIWkqFsRfOjXAvrSW8sqTGOBG0cwhPRaxdOmQaTKrqQbyjjtOjJIZQonLr9yCUoNdFrwd+gQW388v1tQVrJQAMo7YDtTCuEGmq1OBjgiy+aLIk130e0zLJtHzQOq0S00HFbofNRKFZ+iYjJilYNWit1cF8dISGC6Hr3qa67SImWmyqzb10ULiPoa2+0zNjwr2bsXxifpo8Rir+DmaFr52efX5FnIlfhccCsrLxh3CRwuDuz1bS61/eYP5EXX0CDaXpgbIbeioQhpSApXzGLTpD7QaTOhRzDBtcNCz8os96uQmnQJK5rsyKdBdY2zhaKPkZQfBm4sMRMko0wsFc1gNBwjp8p17cWvk9AQLmduWHIlUx8cvS8LWIs66wFF7pC+XKiAXQgsDalZN+4KtuRtIZwq+U6mwMkzJjYnPz4nTCbPycL+C+y/qKB8p5k++bHfv2iSfL7ktNM5P7YM1ZTwz2bEDepsXY5P7srmV3I5WqjBSFSk/q+LgLMsg6BB2YPcC2iTxeW7LWSf332hCshHHwD844+f3305/fD6xx99zO2GKsoGz+RWqpuYKct3XrAv5YB1D9ugEYyK2EJEyNmJW6Wkeg5oYp+LHYIKs5QKhGZJTAZSMyUhIM7iW0F6/AOxiM63lHWbEz/YOuBqn8cmaq9P7BR1XSyQLoVZpNqo2JnvLl8bzSBWf0ujvaNlzgeekfTQZJd9Y7COSBOSTfZ5LyHfxZJYskFDUzlVNEPsoVPtrUbUM812ek8/Uz64nuD9DRcWfJD/P3RH3YvMvvPfoxyxtGajD0BGQT7K4Sj9uGP4pDxC0FZjZ2t66TNTRbSXUXauTuYPzuzWObl3e6bLktXsGP4wl/S1pIzbtS6LucwCz7g4r+e2uUpcVh00sOopYTAcVVjGXM+tiHjAfA4JvHbh1iH76ExmWSHalqgOOnFY4aaHoruCW/M36JepK2z6MMn6odiuqUj/Q/Z7zfbYDDXsEM7wYHTdgRvgdKFzljAZLUr0WBq8Q7+lSnSdDk8duhZZPpdYzPj66t2MvPd21H1Qaj+Qr0cNJbj++yX5WoAaqN1acDFX0K7UiRvcUDOI7siHMumsN6yrktKTiA9pnaiM3UbAEs0PMhzdRdX0OMceTDeN36CBcqoyhN2yZBHMCzSPmIBcES3SaF1pGzTjVrtqkE6paUuFD6W7AJGsM6pipZVUdHc57bQvfrD3iSadcKooNOfr6GchgWXcBKqK8HLlSi0hkJWLPxCo5jR6JwxfcSr68XJO9zmL/eCEym0ZWNEzOmgxp4lrjBI//cTS1iKi8l4jvFjlm1/ErVlHf98TMU+Mmqc6at31GnVL+TDP0wTCG06jcwwxB7FiImJSZJc0Rmy0mC/nestMEp1/iPmSy62mWfzYlTptYTZ41BG8LomYM4HJTpjIQWWLXbSA9w7tPLnBIb6hHOOssHyeK2nkPL5LylHf/DJ3Fsf4tDna3eRyNU8xFtsSjh//loh5Rm/nxsQyGzQJ2xPNAeFRyJhAAs0EHuic6zlf8Hlst2iD9l8QiUevDF6jHbsWYp127KzeOu1fEWn/hkj7nxFp/wsi7b/i0DYy53QBGCyloh5fPRPzrOBO+F7sEN7Jknh+gyCXZAVnqyzHkb6tlEn5KnYQUqDMMIQSDV+T+LYRMdc+IBFhB7VKcLRJSxhHm9Q7XeQIvUgTUaVVo6iqRhqresAtAgsx0ljFDIu2U2tQiBeC3QoqpIYE4RBufrOrgvQobH6TuVkDTRHMajLL5wlHsGFbwghOEkdXLXYmvlnUUtYolPNijuDTSBQzLKEcIYFIz+kKRLKLGHVVpy0o3/0J6QID92buyoCiUPblYHBQ+8BaFOqLVb75DccGrecLZv6KUmgs0fO4veJahJWMzqo1yjV3VCFR8bPctLfxR+u1VSMMZu3t/PGNI564E/tQiPtq8vEqyNVoLxkHDB1Gz5cYm8iWMZOzm4QxZAM9Z7kLUpyjsDqWb35Jtck7xfwj0dYqQaHN2RIw1BjtDM0ZpCxawmiTNhM4pySTacFBJxJjtQNxtkLgTTLXW2qi9vyvUe+LII9CWMGKaaNofEvInjaCxKcgx1pqhbbW2lUiV0j81Ufm+yOOQN0ooBmCIOlTgbBg4wnX27Vkeu47zManvqOKohzwdCARNgblje9vH5su04aK6H2OU20WhYrVLLCkCr5XEAbVIjrW+HJ0mZMcm6zr3LCM3+z60EoDYzRXNE1j3wGWxnarlqWDEN4ils0TJWWGUpXIEkZQ01g2xwmODBWPMJY5v4leninX8UuWslznikUmyqlhpogefcaZgHgldvZUddSOOhVdl3wb36zFpa96Ol9yGf05r4gjhPxbnTc617FEETiO1aERoEaPTeByhXJ0xQrlAudSxWZg2aJYYVyzjOkEgy1kGuXAYvSBEGBccaXodKPzcF8AOnbEn6caOxxPbLexNRCUjDLpG0BH10RlfMlIKraa9/TjejDdrQAV/83K574pb3SyUTtT78n6Fq8ohwwhcTP0xInNDALZ2Nwgn3tDUnS4VGv74TxZx8rz75CG25xFdwTkoLKVosJ0au7GoLxFIRz/6fWVyD59anUBjUBYydWc6jxiw4A6aUVjU1VAOYZ8pyBx6+CrjiIRj7/IlnLcEq41ylKlCIjjGzI1gm1Ye9swQjyAhtiBAL7hMYJyouFr/APQV6A1GlUEVUqzFQLj1XlsK5tWCcY9UEkaXZDWKumrihuBsInXYqtOs9DRq2puEhE7UaK3W+xDifoinbGnb1Ym/rHyRON79KqenrHp7vLo1VqLdIESh14ojvAWFhrUPGWxs95R2laUniGMZTCJNjSLbQ3ezJnQhi4RJIMNUwZDDN/kAqF0k5GqEDHNrH1l0Xoqip4WRpIPhSCdoavoEcRmeZ8pZyk5U5AyQ86oSkM1Q+3Kv/fD8Z2zEFdpqEOoI+Oa6BNX3yCRnPSl6lTxEEzgrdzrLOdyB53Ggneu31IW0Yp6Tzxjdg29zcj1O1OwgluS0Xahhb0vVqyKdjMQdJCcadecoRw9bL0roER0kedSGdItPErIdk0NYYbkCpZDR+EBYbn3aULRt/BB66ggECZCZfeButCcCeyO/DWodrQ6Tk2MXIFZgzrZf1+vZdF50QgRsAFVtSMykuRUaSDvwFDXEdzfVVotwbNLudIvZz7t9QdyHlp8PSdm3dOlyBUD/gCh9bGDLcgVmC/MCND9+9w91CiLt3Qtu6tb5Ab3k9VAVbI+YYL14nM9d49QX7vFPl0vDBcM8ZLTQrhev6vC9XEti7j3F3Bv1WsfmRN+Oe5qTlUR7tC/eEDZtxsxj5jTNK3yqhuWfIRb427FkLngGN2oBxjSvnHdletQLfhAx0tXPRexHbirn6vBEAVfC9BmpGj34dHK96+V70UG15bHj+o5dtsiVcWdNs0pY5g8Iucba/zdVWjXv/fOPGbv/7v7G9rBLs5LpuDG7j8bTmuIF8R7zyNsH5cF1UB8uHaFhnRuVbVL4RePg1dUreAr5FL58vW9y0gI1UQDuHZndLxflaJC0+QI7X07Fab90MKJvftDkxTKdUAbA52DypgXN44Fej+kb8zBNozDCgiHDXBCtWYr4Tdu36+//+i7ksyPyL/d+CMnffEonZ4tskKwrwW02yTS/stXw3tYxcTDuqCUEg1L/YVMpBDgYivIlpn1EKMgpCczpJLYFRyUXnRv1cIup+Mn1RPF5YollBOLYED1cSgeF50baqBN4+OtXb7e6X54tXC2rWxFtcZ+4ClnVM/XEl0n8Epcpa65Xir7pkaWK9Zb8PTXAyD+0li07k0LjVgSDlSdnHItrSLeuG/nzllO3oZfnJBTsav+r0PdOF1eC0NoepLILC8MqH42jGLGtxPDU8++a++F67HY2BBm/lG8+stPf7W673ltO8oV+64Xdjin87ges6mGG7oDRf65ssnplwGGA9d/62Pn/+CfebHH3Dj1o/txYPDyXbzt+3bDFDvOCbl6//G1nTso8MYTZy9NmU4U5FQkOytVBvGMt2NBiFuh5+Tju9/JhTA/v3pOLq7OX//X7+TThTC//UKebdc7IoCZNSiSrKUOrdKkUpAY962ffvt//58fvu9dETBrRB7XXg/HU08y2t+ORyOfvnte82t/Fi9KUP1XPH1aoOu86Q7kBxaMm/zA9+FtCaZ77eQzU6agnFyeXvWC/VMKwLNlHXYy/j8p4KR/bS3cb4aFuonczTzdFjzFN3hkH1bUwJY+Qot0d7pn5DRNlbPT+lPeB6d6epMsP9TP+VBfyMXZu5l/lQbdYxnVR/R+NIxKXlINbze5mFkoA9Yvu4YHdoKIsoZ27OE1LCWxue+udVwGUYNL05TZL1O+d9jWevn3v3NHPABWJXQXXIYbft48Ah0o+1hrFLlu6pNGyVVAOJPKVCy5w3RT52BzG8DM7m7Oq4+89n4+TKzKx6Sc1ruhhRfQpzcey4ob0DnNl2otE2ZFTm836sg4xPJlRcUKTirVKZFiyVaFgpQsdo4miNRFDfXzmfzA0gOdpNEBabl30CVCvQMeUfavp3BFNwAoyKSBeYjsjh9nFH9pU6HndO5D8RFI50bhEF8iHIklQrYwx7gOWPVPcoRFpem8tMThieVtDd7O46Q9Wt2Y8AgS7GuzBiXAkI+7HJ6TT+UzdukMYD+TWWkA67wE74cktbJVzxGEiQHVuAQd7OLPCeW8V5jI9190AW5UucC8DSj7BjJhJNHGPeZMkE8XgwwlcQGyaPwqOsu2RGWO0PbNElagY0f0WrIIKS7+RYwdiu7s7QhofWuFOQexit4p0mG2wgeiFDoggXqRh/KaA0aQxIUTLAklb6TaUpV2+3QTcrpywV6KUHvjb10s3QLMFkD0i56Rqybe18ctDeV1V50HQ1zJeBcZ0ZkhEyHO1YUlZMxYthRabPRPccOpOIYff4KBsgwQqZkoOxNsmiz3npSN1WBXToFtvjyxPZWQuCoEm3j14KZ57KkyLCk4VcTViyYliGevb3+/lCu5XPZ3f4dkbtaAvr0NsB/tgP421nC/trgt3NPCrEGYECw+CFsXMSsnTAvo8UMOQ/+kQQ0CloVJ5HFXOgw5DPi6SBLQegCzqzx+WHG0wwJPHC5iRdyVVDvSk5jQwXYM5tTACC2Mlis5B5/OpbDviuVbfcJh9UPSEZSas9rEq0c38G5S4quWupwBziCt5hPsMC15mAmimSl6+CdxyQUQWHSguqaa0FTm9nUxa2CKyK3Yb5lfOENvpZDZQFyt68mhmS9Rf1whwgr3TKSW/0ilqwWg5A3jQE4DsJPOMkwx9opqYv5ODgaMV/N/lHCFwSW4DlELcVehb449CxEz3/0BC+Hj9a5DvkbslRgOCF1IzOyBnskvYE03TBZOukxkliuZsYEIRTg2uNeCLrhLIluSs3FsTGwqtoMIso2wIXWSXgANhFGbyxwAsGf8Ch/27tZe2f19Gzx2+zTLQph2OltsiT51aeDz5BC1fpIU5N7jFQhQLCmn5BbEBfq1QwuYWbuntq+3GwlgT5KfTrRRw87Pck6HlN16tDm9Gp9TEC/8WIjz6lVNKyXcsAy05ete2lOQw6ATKexCtKIQd26EKzz4wG1QE4/WIbW7H+1o/TxtTj/NdbQmp5OnFgzGd82wMzc34z1DmMAMvt3Zvbpzduqoe+cvWpS5qbt3Llot1eMwkDv4eMVAvt3j+PPdWxartcFxtmwaf1RH5SAx79gE/nHU4xhzbp3DWAn1LgWtZaeOnrlTmPU8A7OWj+AloQ1LMvEwwtcGN9zVUlIS1eo04tX5IHmw11ogI+cSyRLyXye//uUv5Nnl+ensB3LOtGFiVTC9htSlwvdi4XIl0esCjXnCXLTs0uMI2+y+OBAxpiSyVXEs/9Puah+C6sY4i3y0ps/3uS6JC/uv8n5rhj+Hqc9nSkVfmfR9pBjlsarTtSbygaas0H4EIhXRLGOcKs+eLNu0dyhx73p/epW755qlx6w0Uo+U/2QPQmlFbNXF3F9yvDyLUzF2151bI2Qa1uy/wUjkPumchWC4gVpaRtpvypQKMzCg47JxSy3Vigr250hUtcA7ClMX+4CVrp+pgeVeMtWbS4pU9eeNHc69Fr7El69d1IhqfguUm3VCFZBcQSozJmhvwl2NPc2oYSCMvjM8ntNjzvaSPupkfelHyJEOrr0631vGlVNlXDGk/VTH2eoRix0FZjOFoy4hBUUNpPNoQWUj58MynzfliJXzbKbkhqVV8bDwPZrnPEiqnYMRiv/YZ60p0/YLOPtJsvRIs6yGDLX+zG5gmr3NQ13k5IZ57/m6LbgPlICrhM6YTcHvK3nCrZOZaj+qZUKveibqZVQnsVJNtJHKc3xLLQND3Wjfu2+d2G993z/7jKUph+NxuXduvKl8rmd7a3zvID5Xtsc4znRnYbRahSGxK72zz0nOqd0y+z5LRUAkapcPWfldKOQR9MkJEXSq0i3fSm3IO5qsmRhQ6VKKxDm+a6/1J+Ei/XMFln1Y+cgXOdMn5DKlOfns/sfLR6kUPu/0H93Hk6zpBqzkxIEq8rUAtSOuBqHOpdBQSlT9yal2vnP3m+Pwy1ADL7GUFSurQAo/fV+XbxhnOaUjQN0foA+hOOpUpK7LE67BrH3Gy9LSjSJGVjcMDy/TRBVC9Oqx+nn18njPsy8jNZBjFyjOg4aJvxGUbJlI5VYTnUPCliyxnzzvyxMMcbLdC2Kn5/HuY27IM1cRFkSyf4ac6/KH2mqRQrh3/BJWNNmRT7pZ+LbywGbtRNro0bV2hCMo7AOvfV3VclBcrpo7ZPZF7Kx4VQegJ/u/kWnq0nm6y9ecNr5APVSd14vXPTN2M+w9aOE3B0z2OHG9Q1MNEb7B9F7yutdu6sNVQLuzOY7BrnIYNPdmH5Dpt6GzQ/0FKe5OfnZpAzFbAg5muLkpp7BkItjqHXNyVf0ymg8UHXToDkoUQ8K2N8C0xL/YjLGy2WLPPdRSGqhNWdmwjaHJOjtyCfz9qG7BSUc7qm8HSpOXBRPxOohFvRt2yi6pEPfx7GFS9bQdty2+jPY+vb+na2cHNe7bdwfqnKryTNk/P99PZbtmnVLqxN4Oq8v64PdJ0zPRe5b4shZS7fA2/F91TsW/31kxpgTSrKJeiud9T5Ndln996ajfMbdHE4k6syrrrY/PavAUzEEYJfNDWEcqi0XHuDDpjIcxrbYNd6QjOIw+u+O49/BMZjkVu+o+umvn2ul7fWUDyj5DcyaWsl8ooPoGO0foDv7R0iJLZFvArYq+/IoVI/Cm4HxH/l5QzpYMUnLu8p69cbAXyhYW80TKG/ZITvcvsCB+/L3+TPmQNB+92uzeHZ4XxoncB7Ywvfuuf6iGCF12gjna2+RPyMdd7qe+txzYxfE7OLx5CpbzqMVkW7AtBm+IUN/rvrK1bTDHMNVVwmUTnbcs5lKV1n7nYv5wObDltVo5kY9TuRY5bh+ikaWwI99puS9hKimRJJEmKDuO3Q+SU9NvmkzEnOqY3v4aYRXS6SNTLhSPuM01qhF3pVJG54WKZQ2p0dSg5nQVT6fck47+PDVJRw1/bJIOpx6BscCtAeFEq/jKiaUf7TRXgt5aQStUJrZE5Yc4Ri5hg+d+dMM68epl+O+zAOFl+I8Q19Rn9qccVH90XpjOI3rP/WTqznNnca21WutMJw0N0axKxcQSlBrwu3bnfZR51QX/O5e+1zx7BJBlXeJlbRt6rpRza0vUK9UzxNGO32vvt7fH7qOLIFb1P/0ndAO0hht+snwN6jj2CCuzh4inZ2eu9eMP5MyN3w8NlDlSsZSBdT4DFZp/QiMKc6Q4L6C6jmsLWdtwO+j3ulYpenSn2Z+HWiXvXxqlf7fJNfuz31rDbpB4ysV/viYCVtIwv4H5muqBDlA6OXZZodpW+sGHmwvarUbrANUJcGmdsbJwepl/0x+QotnqGBkVzfpGVdfDj4ONli03YVoX0YVOR9kFS+FZ6x7mQ3EIQSlUG2hnU+rc87UdnFw75/QYdzpKhERVGTx4kZ9du9DO8ceoxj0PA3l/7jmCcZiFas3nG8wXve1SDYbsXjDp3B49WkQv06ixCLMbCBo1UnGD7/btSuoPkuOtvxDt/HVSkYvr0/98NyMz+06R92Kg+8oeLVIm9SFoP25lP1rHhpI1JDf6ICPyNCaMW4Osr+lcVa+zKhHmwkBDC8I9FxyRckGxTlHIRxByPY6qKsig0uAwG2qKo3X4rKPcUM5SfxB7QLQZ4dGqWo8xQrdiN7DTbbYd6eSXAaSRaa+NyfWcuR60KKTdVmIsSEKfwG1iK1FmvkjFzO6OG5XILEOtEzcRt8cRDEL9KfhbpoC3Nc3YJpYtp2Ku9WM1vLUjex7+Jcy2zNHqRetTjee5ZMcIq+4D7BEQh8CB6tcG3LImaypEp3AGdrmpMKoDMuCzPVLZ5uphCT0Pv1yeXoV372Vr+OpBMVK1bf/Ra7YxfTPfSF5gLcBp2cdZhD43VWfssp1vIZjR5JkHoX9w1TpcYm/ZUbdFnjjQvbPhBRI3uwxYPwlmQrjASTPpYAPKRQosC04SKRLIjVWUr/0eDpRX2G4xua9feKuwly20LdBcKkOkXd+3/3HaF4Lbu+yxz51Uq+MHWLYTDBom1gX1xU56C8X87fX72cWMvKO3GRNp1da7f1vt3I4ehtloojgwrTCNzuzGplWJT/0pi9HDs32W43x5vITNx07CL6eMLnY0jGWBK1+chyq9AcUoQn68TXnkWgHljLP/9nnDVWKOSLuSZOzb7ewlVoV+pOjG0K7aafGVUzfzyb3PiS56QtSpJv+qjZJi9e8LTpMbzrSB9F9fhr89rz5lYglJ/0dLpmBLea8gQxe89htCRUq0JAPHUsGKaaN2VrM/JrPIqVmHYv0VBtLG0AHpjFLHgukToX2+ViJVrQp5JU9WyEGYWkxKFQUslWEC6jeg/4w3kDQD79+4w+9jM0p65I39j/fXtS+270jvOi4Zh5M11euTRCU/t+2tk5fq3zun7uzD2c+vyFuq12Wc+F1Aeo/vEAMgxCqvVMPvZAGmbRZJYUkLbuZuCX4nS8o72dl3wH8n04KD44c5VZqJlV9hu9R6p7lctSvM97Ek0tSkPVvqfGN8nSeAtf+c+lRi15nUMZ5nH07PLz5d/9C/7E1kN4Z1XqBYuDhVGTlNboTcckhXQD7WxxoBhbZQjcdpDEBfwFMUDNfOwFslq7TsL6OQeloZRQL19rQagGSgG1nlw5C6nSb3cDo9XSci6Yn5GAXQ55knkU5LyOFteOBHwaxU36wjQvlbgxmOYOnjmrGwnHsYzSKUI1iyTrh9LCSWtKs1NQFGJ8Z1D2KoQNAkEJalua48kEiRavLCFZ53RXIgJZqJBFwZtGYbuDGcHWsribNcriiXo09eEFid+P/+t+/eyT8Z5/Tlryd/+W4CQMvUO6okibOY/sWoFQwbgdGNKSWxnq066WEEgvKdYYnu8/5GgvLRmZi9f7mRuauLRegZ6LTrEso9UHsKeLCXnK6a4Dzoqe8dFvfyLoVZQxUdQZG/eDIPTJ6jCUYfnSiSFM6n56WfUHEjz11NCiX5JIRojGFfkm8ae7Df75h/SaR9q4E584vTqSM8hky13QsoyD4wfUMuYQOTdk4nFOmV/thqGHo6e+6z9YkdU0DqbBIpGGfdCNXRVoX94iTgWMLFPRlFb/QIApZ2hMgIJETOVQdkprGv4JmLrjGcli6/e6kO7ke9Qz4GmqEiLQThPQ4FityQ0BhzHB8Wy3K0pyoT7sv9/dki4bFrZRRbrUCRnBoDSmjHobydMrkBk1JDfc+HBdXw2y8ERCIbfaynTWDksYyxpFUtqZS89C2qp+JDe8U9sEkPeJGysQXqCdqYCsJSno5BJ7LHGxLtqHk0141BxgGN2usOXxZ37lktY86ONQWSWeOZPXycWfA0TzV+FGaNdrOabUymHSKzzpXsZNZFQvTR19c0MpE8dAkQzDBailLN+s3T4A4UhsZYwdZQg7AWVKRblnai4yOh+o8O+TEkAtK5KjrVPyJhuTo9I18LqqgwTICFZsWJD0Xw3U5G2I0QQQUYMuMuJgjtCyoGRo+zlRZOg8AwEmkEmN6SILHguBHqdXmmokIQTgOY+4imi55wVRLJExLq3l7DtOc4oZx3g1gigTmjnIOaiEMpBmoOSK+eZenBpUvO/FgERPrCh8GWsXZTGXo3e4TEEebOr673+SHT1q23WANBeVg6gw3DQmKTZ2ehWO3ku5akysnsWGrgWZf+MBYQRlEu6JgQ/qDzc+ZHIFenH6cdHzSD/1lPRtMoDESbcD1tYZphxQJaU40kGdXxNEYZxrNcUdNp0BgLjhRLtiqUv+R2HLYoJm3bciUXfxwDVKsJ2xiiTlksJEiNccYAoZkkmnhceejgZph09Zcrc5vL7YhS8jBW1ED38b9Ic6xhXL05J5FAVTk6Z61R7oKDx5yur99WGS8TmdOaas3GRMiHbZwnP+0Q9efpEjxPbenfmOYYStarNdAUFJIT4e3HjzPytjXCMBqeysUfiOxAuKq9gVtO20BXc2U+Gnb0IFRf2JKFUcoC/lNQySLFDBg7swNMDl1zcAqNZb7xYKaF3CSSF9nwojzo4n9+fzEjZ80BRoBkGRVYR/nygpy1BhhFUgi0ML7rq3czB6Y5xggc++654FEstaz5tLaHGkNmGQTrb2YcCZtTsn0lp5IjlRXIJiF0xkskaKW3rhyGZDKdiMoo2s3YjYTry+kbl+i+tzkr0EYxt3JTuKXXP1OmqcpGnMEPAunV7vL1na7y+i8i6nZ+AF/izoXXuDfZv/pT8Lmy2TjYPs+uyFmz8OoIkG6jLRJLEi+E0b5jtFcVJl7GQhiaj1hMHwJqX777NM/JmVGccLnShGotE+9qcd7gewV0e8gbdMSfY2FN2HL47EVCe3bx5joW3pSjH4fzy1k0tAJ9cc+voq1tX5et6Hh9oEokxMtuOd7IcJfLWFhZjn4WLmbRzoIeMT1GQnt9/TYeWvRze319GQvtlqIfWyvRxULbaqOCgRYWZMm4ARUDdF4gSTGzT63WnMMY1B22g4cB8cpNrRXJZDuCYoYllCPKevtdLQcjVk0Uqyl6RKetAYll4Giv2MQQ6kTxxhefCqrx+LUHbeC1zKD+vQlwNoBmUvz8epIVMaXQrUkWCcO5o03EpCiPlBqqqBjJS3sgFkOJo+/sCApyqcyEm5V2iyfEQzRlWVKh7whAOzT85dxKwFMjztJuLwYSaR3uc2N8XgSTord1STREYRDSGmUE1gY3nOMcXGzQ9DCOFDZMmL6yPpEQvT11YyRALoQBtaTJ1IC8FDZ4RqWwUNPsJOk6yeeZ7gsRjgHl7dmMvJuaPp7a7UK7YVUNLlZu1hREaHlZWksd5NTGKKNYuFypMW58eLD3OdM3VoBeMbEiahpf5jncGtUut0Ei7djljDjyvVWEhkHJZKCvdjRUSyZWoHLFhLHDFa6pcWvQEXwZZSIxiru46p7CRCSSoH/x5jqM5kK4SXOsiQBHuVRcfBP5VQUPM0a3A6412AR4CMG6DlWIG54SVb0Hg/cG1jFNlHIrVKXHCPmQBXR7B2LlqroP2IHy0yT+MnZGugOdt36w9BZnDQOqYGOZpFDVYOHlXDdxTVwwJF/ZuWt8Zo+WszmlTPswRJfQ0mxmP4LNzNG8tIfKP/ZXZqkkVmpLLy7SGG8MHGqgQh3b5DCFVJsjaEJ7YOm9tSIHEFP76ICb+LJrs6QZ6ymnGR3X+2vSGmoM1Xrb21wdAdfbL6Q11F24uu0Y8ICpaTZ0xzPA6A2esaSHZWifOjQJntR4D3nrmE19lozUR9vM99f32sy7TG8Pki1qsCab4bTBy0CrA7q+niTsaKOPdxG1XJotVd1OLGP4CmF1GCtWoqrGNZh+xJB8Bel07VibosDa20+f9p2e6mAvZtNje1M0dM5U9mnKiQOaS55g+eBen87eX4ayFq24rnFEeCJFA9I0YQJ8W0ecJfqyBtdQY1//gzBdDgkpkYoIOWXZqt6TSOu272051YoPueypSB3nYFnS+8LiXCbOtTsxFwJ03tMKj0RaqOtZK1t0EiCXtLSUCimBxKL62BliGNDtyM49CMg7yjh5fZusqVhBKDV9fnVNFOhcCg2ECr0FRTRMDCWAQOubgZu7SmS6bMGKtN9hGBcu1B1rDB7DUjVdQPzfCqpSV0ddsRTCeK40jDY0m1CAZUkzPc9p0am7TeKwlqoY96mgfKeZL8/0jgq6cvWsqsICswaGEbx/4nlaHFgH9E9Q5DK4XD5MMs4vEwOZxipwV89+eB2aM5Dr66tJuNAEozqqSfKRq72Og+Xq4yxU22uNMgKGgzdR4iD66Ou/GlBV+4lQD2Lnq/0sfY+Iic+s/daa6jVaqZg3YYDJKoGf3FjNiggOPbd+021o2Bb3PaZp591+FdGkcTkjquAw0Zjh4SAaGPerM00XcF0xVvYNsxIADqhTYZjOaeaEtmYXkjFcW6pSSJdYtkWf9hSU2/14E6B9TbHemL+fT3lPFM0A7whVifTdcUYgAaRM3/S1SKwDe5ggowBcoEeHzAguiaR/vLGCM9SP0DQ0803CCz324j0wxtSVFdswZQrKSRgrNLacgFDTDaiUYRXOfnN9StoDDIPZeqtnXzvQSHi+wILkSt7ugoF1IhdfUQNbOqxVHBrD8DdPl7C8zpfIbDaTr0vRykemTsCo6g0U2ggfpkNCJtVucmVl11wDq6SF69LgG2xMEQfW9EWu2HBxyQdheXtKZoq5Ts9TkMwRu468PZ1a/3NN53ge7Len5MMkd/WailSv6Q1aJZZL8rYzxAgarPpQrsuXE4GIXJJUbgWXNJ2sgawXqZgroBrLKvoWqDILoMZhI62hhnGx1Rox9eVtSZ4s6UKxhOgiy+gUZWQtsSJs3kptpr0WjGK6RTa/ETZBaGVJlif1mghxgdQ8RjPX0Nh7ki7O3s2md8iyGNGqZ3rBKH8QODyh25WT3uWOK9wTV9lMGkmivAKzleqGGEWXS5b0jTeMTcx1znBW7GJ2/fqMMLGQhUjJ9exiCpzEodegGOUCSQq4CKMQP8xk2btsWIqFKpi63r27no7FvkrjeXoPtuWUQ/lGTXxanl4t6h3Ta3+xH2aySY4JrDZR5YlnrqnJJN7ga5tjWVDeK7ZigrqiAyE01w3s23hXhqXKOTIFcDv6MirgD8BdxMU9gjzxsm4OArOhnKUZRbI/21fo3elZpXy6eN0wKHn/aQqLjR/YX67TlKB+hvhE73FMNK0OjxYBzX/6H+9DBjRQlUwoW3rDsEq7uSJzDfKDIDgVI9kph7sPL0+v7CsvMyZWe4lFkMXOwARLBadCFsPc+2G4ZGG8rHIALqBY3mEXWdWkPwyDJSA0zDlDa4X4jt6yrMhqxQ5qHk5vDbOi+6VHMgXyGNSH1VQMNtaQavEBvIRALhtDjiATSIzK3cMG+REQIxX5YvZ5nQBFJnREzDzw8bi0VC3Ldq01yWw2O6/VLpyCCin591Kuput4Tr7CwRFqBU1J3+Nyi2jjeeMtO51BBuGgSUGOJWY0me7YySi3isI8pZ3++iQSs7F3OgwDKWkMdDcstNoMPbDuV+Eko6JAkq/fWdI0MYWa7NfJqDagUm3QztY7N0L9dAXOtJbaeHk7K7hhOQciguWlUhAmnURLX6sEVUfwozRUhdosXFutNdUPnAmkrMjwGY4fZ2owdwbD/uQHoQk+tcI+CCEr0jnYmJ7WqDoDvc7Q7LtVTIAdZmJt3fC6IRYk9tzHDzNRJ8MsC+Oq006NJc9WmUFLU3A9hCsJ2uebSMX+hLSs177k0rXgtAzYxYEaH+4x5aShnTJv4Jp4umSK1lJudnbx4vz6uj3GCBbBjFQv8OIU3gLlZk3e+YEm1tEpYeFdwBasaZXAsxyrbEzFpd7Nrv9zAhC9Quw0GQr7kFlZ+ftqoh8gM0hlFt/RW58ykTFX8ZF8EsyQz9Pi8fDO9rTDLLBiXF0/rXt0+BOA2fUntPm4AjMlmkXAdo7ZSP0KtmXYkQz2/VZuyii0ZqhndGQtA8zEcwRb1DZEFljoQDT5xntMmI1/AqrJzX8EbDWXWIVMYUuuuTT3WJ9bY48hkrDkLVUG1IbymsmqMjba4Wuy+MkEwEtEqfdK7vtZTnxyhWRY9mPXBOiqQX8QhuQpKruq/JHXEyMTLSBEJlXhaXGqacYIyVNUTlWha49yByJMPlVhKpnVVBYheYrHsPbn6j5cy0JCMtq+5ym5vl90ieTpNlcSydZmAX2BBXnjU09mSk6LZ5Riy7AyRk/JktOVy/kSqe/IyXzg1+mMMB3GnpyPLnNQqBWV3ufg63n7ri5TohstJtROj3tM07s8YhaQ2eO59iayiawUt35MB9Xk+iOyMHgRcu8LMy0uThYGL8zForhHiEtOtYYU3+zrx5lq9rXf3mJpfU6jSr165QaSKr1fXVe8xrgzatZELgmXMvfNwWrt6XzYSVIoZnYhMnsCVsDK9v1yekVkbljG/gx9fGEKv7LfmgsrVOPA+jy7cmMQIe/TiD5fUw2vEHOfHC43yEQumq8lasjCrEF/GAaW8DlTMgE9TUHOJWfJDk/Jmzn6E9W7XErEIrZ2Z6TkUw+JHGk7/6DtuZQrUuRc0pSAUlKRaXlw9lsLGIufeFhcdVgdl1gQfC5GkuaIo+BgJB4PAxpMCdDLlVwAonX8kombym8ws4NVhvJJ4JK6rTYqsk8fLks1pj3OXYAMG7mDUViTHeF+/UnylirWhvUwLuWJTzS9BijzDVb86SH24AAKMRWzXCSfpHovVIjvSwA17YH5akfcjIXnPSgE9eqafC1Am7KB6dQaEV8LqvTNSMj5g5bo7wVVVBgmgNhBCNzmnIqJ0tvXQhoKtwlAitW292LpR3GhNgsAQTrjjcPL6HCJlsNDncsIXo+Nci63kJIXdcM6WzpG9mJBdfmRC4R2H/jgaP/ZxIngXZO/u0lMCy1xUAo9st2HL6rHUegDVtJ99MPd8BVNmVyg9X3/YMmTxaS27w4KlpTvgUyR8QOMhEsNI1nEUdAQy/q8aTKM5/5XyVVh/zgZrO9/hZVE2IN2u2bJmpTD3hs0VvO0KhTEg7EDTX1VFN2OxvE+8BpsfZTs/cBgRRxUcCbdh2STpsDRlgYSYBtIAwdrjjQMCrEYwikHZSbXQFABP87Vu/b1aW5gVxUI7Y54JzbkIp1jIO9TtFNhyUwhyrZmXLVPppq2hEtQivICq5VqrVdv31gjwDI51ifr4LRLS5bMZrN71QD3aLYmH1WGH8goHDIXeWBfpEIT2qhPTBpjj0C1OjRmwqizvEyTHhV8xUTi9KvpUOy3MU3P7y9m5TAT7YoKdMGRQgArS3h7lGE0aBWTLJaZw/JqYqcfpfWwA/Fh4l6DdXOijQKxcinhzqE+pRWL0lrObwDJZ/7h9Pzi0zW5vn5PqPFdpabLeQUHREGv4DAxTcsCQbz7Fsi0i68TKgSWAFNr+O+HIe/eXU94UCyo0bfkcK26BDLtudCJxNqjWiHx92Uh8evGcMOogv/1KGpUZ7ARWEIzwzZoyK73AziDeNVrtNaAdBpMrOooV6dnDuXkfA0NwiDqV9d2de6lW2n4igXlawEigcnRa76UEtIZr8IGdNVrqT7YHaBGykg9VJe6T3zfHY2oHqYHn5flUd/8/fyKSDWpFosGl2UyR6vo5ulPMl0ELFg2xS+n5/eEY4ocqYNCiePajjGxc4KGDeA9Itdt6sM41jQHlSqZq2STWl6FLNgGdqhknrv/Cwjug9RybTykdaZ9KMocFMvtr/FgnlfYLNIcLIc4ECie1vkx1N3xg7mRyTOPdYJ/xP/KnsvjIvTe/nBeg09nKlp7No+P1o56P6RMrHxAFRaDbkH1g01j1U71RXo2mtL16eyiPdwIrD8xHg/fE8ESv0d1KrzEC5dvMVkCwqqQ04xwvW9ZTy3uciA+DN1VWc627jqU93TEaXGn4zAeyge5DLXIQK9zqgCrG/geqyt20RpqGBhuodtJgfxaJXhd0kMF5XvE8muV4DZIb0OaaDHVKkHN5AmwJrdF1yrBbO4d4Ext6q1VgtvUO+BZU5WGbr3TunoHYIiJPF1kE/N43ElHbOvdOeiTO3prleBJgAHWNA+OVglmt+yAZWqjbIsGrVF2wDKtR7ZFcpRjff/22FoleB2nA6pPk9oWao15jK/Ppp5htCPzH1RD1YnzGsw05URz2ixkGRXT9fUlOZ1YKFNrPl7B84E22nOHpjnEGJg7oiKioGmNMQzHUMSExr1jzdWokEK/9EW+pqhuZqxbWwSxdWKhem0oWsHCf/nLq5OfbsvFaZQNHcODdXhO04yJUDG/OcwoGqyaGVNLZWjDDFYL7dPCyLLLghuGGMVWK5gUl6WLxR+A1a8u2ENaQ4xhwaxLd9bIvr0uFi/eudGm+heLRVtsjArv9HPfEGNw8KIeLuWqM8AIEp2zhMmROxYr9KEaaWr0w9beB8REvKo8XQjXvFfeud6JBLWiz8c1uEHKKmSuQK6pKtBORIh3zCp8Lm3pAHS6QAyUDNUoWkMMokF8g02rsYhclpUIjQH1nLAlEVLAc/tFUbrnJiygWSugiCGcXy7Or8MgE2Oo8HbT1SkLlknYTLJJYjEN/ywaObXPu5HIbW/TWv+5Q3vfGmmwHD0fLWmSueDziUBCxAImntqz5Aeb8B4ZRRNAD+lIONVrP9YkPdgoKlKG1b786vSjG0FzWqWoTsOEVifNlZp2I3j9f/IqhTmgNaS8uq7azzt0/B7onMh/ZA1jCq4CEi4MQmerN4zDfrkKKItzT4muMoUQwLHOl1fe/RjTds/Dib9GTSSTFwZPJGgAmsgK0MAE/W8ajALJQektGq0UnE8XU1G56vSFBoXZyfGTqOEri21NbelYjLV0fFhdD7m1OIo857vmMMNgFPcsg6XD6fsPa6n+4bLkSlOufgWIM6wghxqixiBjmFBP0x7P5DOkEHlSDc/ESzdWpiCSreOTds0SJwiVFs18KdW4ov4gWPueX1VZ54krZTJUF0sZXBTkuBxU6KW02JFPH9/dDXBDkcTespzOlKicDc3x2oLsgUzsDYKra7b1yynd10tE8wwaymhUYJ9bwFpj3Q0O0evRxjbR8/GkSkVhRv4eBsgFzqAlpH8uuABFF4xbBqUTKsKIE53lqDENn6fGMGyw6kOVWzZFKdkwhWUi/2xJT90R+10sndEDuTgnzwrBvhbgRyOuFz5bMlATguw3kuVzRG+HSzzPJxca3ORYp3d2Vf/aJCRe5cTBczHTkJDPuSAfvWI7kQHlAte34twqweZt16y1BsPA1HAx34cd8g9vJhuUNwUXCVbboiZzPqMGVpOMyxYUGgdoYJqiO1o0iI9qA89EFrlFM6p9/nI5bVG2/GtBOVo+nsXRHmAMDGrQgAUzOWRgs803nOKd3y8z8vny9GrSLm2RWth/eVgL+y0VMjc0zxGdoqdX5H29zvppnvOq9M4krXqL1Wj/i2+0v5IHrh7Qmy3kbIO0ckBvyBfIyYVghvkF++w6vt0N7ZYWZo1Ypva/TguzvleR2tvScIsJ6JOGqfUTbtHSu8s8vf/q5Qzd/ygRhb7HJ1Xc/knrsZMbUFvFTPAz/VMbdncBU1jSgpu587z/TpaUNzp7jczGLmIpS3UaMpPtGhR4u1i4NVVZWeliuiA96cxPaXqPybQP7x1TcX/Wv9f+Ug7rULezModHHxq/b4j9IJlus6CxEcZPfGNXPq6ZdiXymPYVXY0kCc1NEdZf0e2+qfGaGpLIDLSdtMvq65zQS7ki55DItHW8q4l4Wp3Lceh0SrouBqWvt/xDCQfAyKsflly7NU+kMCCMC0xiQhsqTAlD92LsCfOZAjDtGti66JjH5Gq9UxPSJWlZw4KsmdGEkiswX5gRli2F3T/pHI1qsnotC54SARtQZAHVucup0kDegaG+DOhSyaw21LNLudIvZzS5AaN/6JA/ZwoSw3fPiQm4KfkAnln4Ey5qME96F5LDpqPUTlnJHhGhsZLnkCvwvj6LJIUlE5ASKbiDZeiCA8lo3o8q06tukEvMExj2uGwSfHH+ky9b5m98ZTPx34JbmhjC5crvV/cVc7NjTpzwp8V9z25HTpVhScGpcr8PG3syeDI6pA86KX0no0N5+KQMbsnmuHvy6v/uyfie9JTPi7QhD7u+cvHHvDfX8Mmg6zZTeBLQFPS6zZ8ENrtsWPf/YcicMyvrFiR4EuBokTIzTzjtNMx5EvCgJw3/SQBbJ12H9pMAxsRhwHAlppJzPN2TlgI9hHvgLtsSII2pQw3INX16Zu2LpVnAounIIR0h4WFaREsO6VC/Q4sYXsUeP8IRVlHUrCq9y+eXqzPNSMtHelbw3suXHEOsDk7hvTu4mn/4066p1J5JkdjHgRr51DXbAXazYbjssL66Z3aYqrtoeSAv5Yq83oAwZbGFQqSgrAqiIDCqztSX7BZSosFYIo0fN8fQwwpLuQkd2g9WWKpN6JC+16b0mdFj25cOO5ided1jTe63BmvZidZFOJdvpTZ1FsnbJ1KDSJ2vxn+o+45NzYb07axvJ+xoyup2fjS4sBezzS/1dMre695e3M7sjfxWF3fzG/by/vY/d3l7fMcIvKHNF7whrW4tSwklK7YBURnJvl1BwC7RYfYLXA0kfYrC37fh0Rg0aMh8N1ed4vkx9rruPHQb7Oa92LlVfu2HJjN3kZ4Ha7ahrssrSWiXgyyAADNrUOTThTA//UakIm+4pObnV8T3lAyd/hqN/++Y9yHi7jc8b+cGxVM+I9gXknZ0YFSAY9pxOfI3b2CQaktViibU1Thabdr1lbyYfW7Ie5Qo4LQbIah9zQ//iAbYociuO6naL579f6nYirm+Tv43TWnljnXAkr9GAiMuZp9/61mCAL+zEg9fggpRd5VjvD77g9oVHA99fdZAU1BH8V2/dUORi/OHeEk93rqz1JE5zFf6pI1sPJmj29loKWhd7AUtd1Gs6nImOXexht8iA7ar9wgxN/bMMU0Sv3SQWqQNQfVSdgNVhxf6CWp8WbJ4KqJqJrULdsukj9ftzL7sGMk00SzL+S7sk/2yS+sFmqyJZimQZ38hZq0K8urXX38gW6qJBhDVKCMr8SSE1wkroXMpNOAtRfLNnApXWrWyKVTp5/Yq614K5BldyA3UFoOJ3sjKkr1po4Bmg/cn+WaOzSMvFaSsaMtpMRbquz7JsTIssCVh5h/Fq7/89FftWfrL3DHQEvQ/OrP5h9UHL+kOFHlFXouE5roIxZ+sSnkvvt5H/YHOj57Yyr5Rfn5F/s1O9zn5+WfybySRysrLvgiSH/Q5+V/c/G/7RaZJc1G+691CIVN4srqu2MI8oZwvaHKDKwF7cEIad22o8XqFXUQQaS6ZME41abdTKYG6wzEHpTodFqLLgzqHhFHuEDuk2khlJWux81KH/WBDOUv9wegDRchSFiK1LwwHB56JVRCO7gxebN6IDuUYvsBwHUbcRgO7sOOSpk/lnQtwfPOlDIxiSY/WEVTh+pedLuyf+5IJ22efmr1EK5fltp2Qt3Jrt6arczJBpLLKmJHkBiC/Y9GexIv3jSyakgloPd+wdJ5ieV1fl5xnBQIUNe6Su0JXNb2wrF1ycd60vYseEwfLmFW7na/cLYafRbjqF+dEWW6tnUHFLRpVKzDV1+5cCa2Qgp4efSV8JNz4SigUV1CX8V+cl7bXD65bwb7GpgL30C52Q4zS/lM6Yr4Bx0vZb1bnvFOu7X9McIdmHbH/SchmPf0KY553d+vsGxDOennqSq0lPCH/PTyMnr0sWafNwBF89HZUqxzNzk5nQfZNqLDLw7Jcqr4Ggi5x8dsKgyiehvnjk3+qnCLe30Cmo8oX+5/sFXYv5zjN/IS8+vU3snXrngEVhHLebytwRn0nJu3tR2QLCjxZaggHqg2RopUu0lzERxcTv+1F7LmrGG7bsHZfpErdwrmoJkjWQnK52rUdcUumeip9/kqSNVU0MX4R7aXeOfzOaC5IIUJMD2/YzAczamMndHtHPaYTYcR36TSKzAqZUpRuBEW3gzzNcdaWWEkTJ7F6H4UINgeZJIUqKWpDRUpVSoRUGeXsz774Xqmy3vVJQ5TDwUski0XnSbrXIu1RV2BecrYEN+MeBV9DIkU6IGDvt3uuDaadZWRCro5LzsH0HoBBIyp1ArxRrMUGa/lmyjzSQb62Y/ce56Gj3DyZg8cvk8K0+0s9tJJA2gmQeHDRA5E+0sK/FinGsluSf0qBXW1hhC3a0UsR04fXfmyvcIdFod3oU2Lg1oTLV1awLNGlY3FgPfv70MO2Axprmvs0vUSqFFK8dzAE2YRnSlcjljJGGWlTfbHuX+++VkpmJ45q4ZLydQKCKia9WJ8V3LAXhoEitFaDal/LJqOCrvpScwnhzr1T6oselMeqCTPfayK3wnvGDM3ytmUwIHb1pJXsBh8xo0myZla7kSnoE/Ku0MapSXWivtXWQFwuNXDgJo0ysOXS4t7AMSQht8nlgH7tFCxBgUj8gaBWtE7ZhqVWsml2NaqW0jKy65KRfWwtXv8kb3OmjjbD/X56X9CtPYnM8J2frLZMz8prFpQ7oOO20YibPmjCeW65ccXPTjpDVuFksojNgbKOIPdQitX6x74qToL8WkBxtKPkeny5U7Tnj1uqiQORDpwbB+6n2IsaUShoLCgCT1tlBuH1XWUYWPM5AtR8jiE95zFZUZPoq+hUEWSl2ivyOCpkS33sfWM6z+W93pxD2eZdfO0QZ8H+gWhVQ4htCOrt5/FwwVoXHNvtNKBFycIkMoOXHkOlvLiobNkthE1F2W2krkAOHBDYgOpWIj7SxMrRQxJgzbMzZvLBTV7s1A70r3SV6eJKllPtHbBLtld8+qVb78wZqqkSZGX8aKaeDahMjCzdJ0yUJqo0OFl6cfc3fkDbhM9NLb2uCUpF3l+H0Fimy4CAtl3NjV/u0FCWpM6lZhEZx6Sz5dRpkfoKUy6Uv7y7g1V4Cm7meKWL7smKRJGBYsl9eVHv3I6QxTYysXomW3UzPFvy97sztdArhd3Nt+Tij0eoXlO6dmW3f34dGH4ueGe5Q9OHEWCe02PWqvuueyFD1n+9BbOTxsrYYiENoWQdKl70B9ByuZqXgSqPwtTLg3hvpn6MmikN3rcvRe7ZR7/gLzlLdti3Z4QvzByAUFxb8N0AXy44Ztx0/wJ+KDg0S6fXIbmSx7fYEmsF6EJ4e92+HipNU23/5R5VyktAfQVg7nickzUVK5gL2GLzgiHHJWxrrn4nhBij2KIwUOMQ3Rh97aFbab3+/PWzDp3TaMyuWjnXcPj4N8cpgu34otD9uCa/9Si3LgPMLlhZcFDvY77UBtQJuQa/KYUGdUJX4Ep5h0j3pVQlhg7tkoyX2xPfItb/vla3QiqyUHKrXeM//9ekbCxt1a7BetIX6YwqE9tMVxGObVEJd0p2skOPdackTyuxEetKyRyCQxHrLT4VhHJQpoouUvtBw9+8eyuwj1oRABeE1CMwp0RI8UJBDk6TGYt+6GvoiFtHv1DKXphKX3E76eS4l8x72Er3T2dmW2bWQVj2vJ6cuwEXLttEECle+LYuIy+BE1LmPYIj4rxpzRn40gGwIOWSWO5gGOgTcr3nKe3GBvXMKhzEZz6dr9BWifEpoz7YJg3sNyw8LZtz+gM51EPV/YRpu5MhJzrYN6zg6z4dFoGOLv20WrWRblkmPKHs+7sUL4vy3KEgVGuZMGcvtbvRq0+6DbtkN/A7oSRf7zRLKCcp0zfPSa5cT5TnBEzyfb+gTBU9JPfyng+9z7NRNAMDSpOcalfFS7tCDr4WQSKzzHIx2XDad1NrwCSj4p5/Dx5L4qvtIcLD5Nl3IrO86N5BhG2jZMtEKrchnjaRIoHcPK8iKQYXozPNZcH5zreXc8bP1De09VxD1AbicuDpqls9Y4lLI1O3IuElEzeQhlygMhCdamedCgqK/eS7CtoJS8c2jneqQqCyunpnJ2+WaAMo4b2/fixc7/NgeSXX3XI9ldMZVMbajZ2wTaxhTIfWn/9xSfvnyJK2b9x/rCm/caNV11hBWiRASs8R9JvbNChG+bznNUV7RK7dkKXY3H4faw+gfWEG7QKQ3OiDSg7EsBiH0e1Dt6Z6Xd1QKxb2ZBkWydpH/pY5NlWa4VlJqVUizE6kGuZEq8T+qvr/bqYpsfxcEOZi7gqRcKDK/skVwttDCwmEwdqpysTOu70Pnvn1dAR80i9WIrMFE1Xd7PqDFdJG1T1eL9f0+tiWvro00m013rD4HcdB2nMlzvzovibjsKXUa3DopvFq+byV+eKcXHlO8ywUbiC+215I+rXYfuiXq70B+jFs+TXz88W5W9KQ8laxia71oOmR82GAfgon/hBZXrBlul9J3egdZi37plc3JGh7cWHUji288n3EU2OX/qwauN4VlAxIsrHsc3dIshbYK5HuJdoTcubzM0O9U+4/GJdmHUDV/MZP3wVz3KIwVeamNNVjVAjXItUZfPyDspVkQxWjC97JAvRFGZggOacDjECD0Kj1URobWhdV/cgnllNZCaPML2R2n69fXszaMjQJJWO9RWEoL/vAhoKTcyH3nhYPklwIQ67ZSlDHLAaOaC4VZvHa7zv8yx7SWSm7SVfV0f2nBVK7y+6UpbLn4Fy9/0iYSHiRgmVnoZGt/fkJefb6lmY5h9/JzBtEPFnHvU/67SLOM3d036YzTu2fln5kTN9YkfsAXPdIxauZMa/C0/CB6ZsRl6tRbLUChdfCrn/JPtd9AQGDk07XCvRa8tSeHq+rD3Qabbjej2BZ6PreA1d+9sHLGD9UxTguzvvTSCZ75xOZ5fMjx125XQmxV66Nq7fv6WLxwsKRwuWnLl27GZkWyZCWFsTSR4oaqyOvuKVUrvKA5eslvoEucVSlW6oeJ0KvW1XfclcaHiI7iYHSyM8sE6XkHU3Kesr9wq1lQUfVY6R4UQqoapwLeV0zelNrBVRHjw3WhpoiluBc2aMo44+mdtjBF/KWsPTl8PtlX9biGAgtok+dwsf+LlgU/Ve3fMeQu+91Dvl5t+/eIc8ZE7KI5eOs5ZHoVfQ7ZTlpTKNDxyL7S2TC2JUZG0filHPL94gukgS0XhacvLbjk0SmoO2RKIv99msWTKRwG3kBONPmMMnzgbzFDexUMVWCWIBy/s2MKsZdBE+PBc/738WKULeIL+xve2cmEM6hXPjiQo8kEYfRybMqnjMHpfOQdOs5TGfJgoiwD4gvKzz9MJBk6M1c3fcYO6DEC19VkFewVflv2w8pE5qkYCjjPUaGhSxM7XcDU5P86LGZpcWWVnFsDsfwQ2ogyzlaNM8pSWFJgwsoVL4sffghWtNKxRtQnO5cIpeR4XElz3pupP3Aad3h17Ass8C9rV4bZgpXmJH0TmyvG3QLNj30ukb1YtXsOwmNjRSBVyUyy+x9wjlGZ546YbVg31zJDUu9/aysIpeBHgyESmVyuKPx/tayN4zvpcakHpfXLxrc5i7o6XF4fTk6Lq//Qy4OtDsdPL3/IxfBAdN/u3KGVzj33AUU+52/nl2Qi45AVYeBVrU2ZJeMI4iY2FVlw66iKtL3sYeF2Op+4d6ziPlCptgZX52Mu7bQEbAQi2VAPFrHr5bgXQZHyDyvmYBD6rAPoK38IWzF0sqVM2DEy2JrjZ008Agvfzwhr5p3XmA+U2V379knXz2ndES5YI1bSIq6FcGHfi2gL721rMI0FrhxBENIr1U8bRpEquxKuqGM064jg1SmcOLyK5eg1ECnBX+HDrH1x/O7BWUlCwWgvAO2M6UQbqDZ6mSAI7JsvijSdBfdPsOyedQ8oBrdQsNhhc5HrVTxKSomI1Y5aKXYzXVxjIQEpuvRq77mKi1SZqrMun1dtICor7HdPmPDs5K9e2F8kj5KLPYKbo6mlZ99fk2ehVyJzwW3svKCcZfA4eLAXt/mUttv/kBedA0Nou2FuRFyKxqKkIakcMUsNk3qA502E3oEE1w7LPSszHK/CqlJl7CiyY58GlTXOFso+hhJ+WHgxhIzQTLKxFLRDEbDMXKqXNde/DoJDeFy5oYlVzL1wdH7soC1qLMeUOQO6cuFCtiFwNKQmnXjrmBL3hbCqZLvZAqcPGNic/Ljc8Jk8pws7L/A/osKynea6ZMf+/2LJsnnS047nfNjy1BNCf9sRtygztbl+OSubH4ll6OFGoxERer/ugg4yzIIGpQ9yL2ANllcvttC9vndF6qAfPQBwD/++Pndl9MPr3/80cfcbqiibPBMbqW6iZmyfOcF+1IOWPewDRrBqIgtRIScnbhVSqrngCb2udghqDBLqUBolsRkIDVTEgLiLL4VpMc/EIvofEtZtznxg60DrvZ5bKL2+sROUdfFAulSmEWqjYqd+e7ytdEMYvW3NNo7WuZ84BlJD0122TcG64g0Idlkn/cS8l0siSUbNDSVU0UzxB461d5qRD3TbKf39DPlg+sJ3t9wYcEH+f9Dd9S9yOw7/z3KEUtrNvoAZBTkoxyO0o87hk/KIwRtNXa2ppc+M1VEexll5+pk/uDMbp2Te7dnuixZzY7hD3NJX0vKuF3rspjLLPCMi/N6bpurxGXVQQOrnhIGw1GFZcz13IqIB8znkMBrF24dso/OZJYVom2J6qAThxVueii6K7g1f4N+mbrCpg+TrB+K7ZqK9D9kv9dsj81Qww7hDA9G1x24AU4XOmcJk9GiRI+lwTv0W6pE1+nw1KFrkeVzicWMr6/ezch7b0fdB6X2A/l61FCC679fkq8FqIHarQUXcwXtSp24wQ01g+iOfCiTznrDuiopPYn4kNaJythtBCzR/CDD0V1UTY9z7MF00/gNGiinKkPYLUsWwbxA84gJyBXRIo3WlbZBM261qwbplJq2VPhQugsQyTqjKlZaSUV3l9NO++IHe59o0gmnikJzvo5+FhJYxk2gqggvV67UEgJZufgDgWpOo3fC8BWnoh8v53Sfs9gPTqjcloEVPaODFnOauMYo8dNPLG0tIirvNcKLVb75RdyadfT3PRHzxKh5qqPWXa9Rt5QP8zxNILzhNDrHEHMQKyYiJkV2SWPERov5cq63zCTR+YeYL7ncaprFj12p0xZmg0cdweuSiDkTmOyEiRxUtthFC3jv0M6TGxziG8oxzgrL57mSRs7ju6Qc9c0vc2dxjE+bo91NLlfzFGOxLeH48W+JmGf0dm5MLLNBk7A90RwQHoWMCSTQTOCBzrme8wWfx3aLNmj/BZF49MrgNdqxayHWacfO6q3T/hWR9m+ItP8Zkfa/INL+Kw5tI3NOF4DBUirq8dUzMc8K7oTvxQ7hnSyJ5zcIcklWcLbKchzp20qZlK9iByEFygxDKNHwNYlvGxFz7QMSEXZQqwRHm7SEcbRJvdNFjtCLNBFVWjWKqmqksaoH3CKwECONVcywaDu1BoV4IditoEJqSBAO4eY3uypIj8LmN5mbNdAUwawms3yecAQbtiWM4CRxdNViZ+KbRS1ljUI5L+YIPo1EMcMSyhESiPScrkAku4hRV3XagvLdn5AuMHBv5q4MKAplXw4GB7UPrEWhvljlm99wbNB6vmDmryiFxhI9j9srrkVYyeisWqNcc0cVEhU/y017G3+0Xls1wmDW3s4f3zjiiTuxD4W4ryYfr4JcjfaSccDQYfR8ibGJbBkzObtJGEM20HOWuyDFOQqrY/nml1SbvFPMPxJtrRIU2pwtAUON0c7QnEHKoiWMNmkzgXNKMpkWHHQiMVY7EGcrBN4kc72lJmrP/xr1vgjyKIQVrJg2isa3hOxpI0h8CnKspVZoa61dJXKFxF99ZL4/4gjUjQKaIQiSPhUICzaecL1dS6bnvsNsfOo7qijKAU8HEmFjUN74/vax6TJtqIje5zjVZlGoWM0CS6rgewVhUC2iY40vR5c5ybHJus4Ny/jNrg+tNDBGc0XTNPYdYGlst2pZOgjhLWLZPFFSZihViSxhBDWNZXOc4MhQ8QhjmfOb6OWZch2/ZCnLda5YZKKcGmaK6NFnnAmIV2JnT1VH7ahT0XXJt/HNWlz6qqfzJZfRn/OKOELIv9V5o3MdSxSB41gdGgFq9NgELlcoR1esUC5wLv9/9r7uyY0byfP9/gqsH07ShIayZY/3xuedjd7u9rhvWnKvWrInNiaiAqwCixihgBKAIpv+6y+QQH2jSDYbKEp7Nw8TVpNMJL4S+flLGVqAFcsqj3HNCqrSGGKhUFEObIw+EJxoAFcKTje4DLcA0KEz/izV0Ol4fLsNbYFEqSgTtgF0cEtUhNeMhKR54unH9WS6W05k+DerTGxT3uBkg3ambsnaFq9RDlmEwk3XEye0MHBkQ0uDMrGOpODsYqXMh0m6DlXnPyJNHkoaPBBQElnkEnM9wtwNQXkbhXD4p9cikX34MOgCGoCwFHmCVRmwYUCXtMShqUqCWQz9TpIU1sGijkYiHn6RDeWwEK4dykJmETgO78hUEXzDyvqGI+QDKBI6EcA2PI5gnCjyKfwB8AG0BqMawZRSNI8geFUZ2sumZBrjHsg0C65IK5n6UHEDENbhWmx1aVYqOKrmJuWhCyW83WKfStSCdIaevs51+GNliYaP6DU9PUPT3ZXB0VqrbBklD72SLMJbWCkik4yGrnqP0raijgzFWAadKo2L0N7gTUK50ngVQTPYUKljqOGbkkeAbtJCVjykm9UHi+ZBFL2otEDvKo5GQzfZIxGb5f2KGc3QpSQZ1egSy8yhGSqAf/ezYztnRVylqQ6hQAaa6CPAN0gFQ75SnSYfgvJ4K3ddlEzsyKix4MH1W4kqGKj3kWfMrKH1GUG/M0ly8oAKPARaaGOxPK+GzUCiM8moguYM9ehu6wFACamqLIXUaAw8itB2jTWiGpWSrKaOwhPSch/ThMK38M7qaFhAlDtk9wlcaEZ57I78HVbNaF0+FdIiJ3pN5KL9vlqLavSiIcTJhsimHZEWqMRSEfSGaAwdwe1dxc0SPL8VuXp1Z8teX6Ar1+LrJdJrT5ciAAN+R1zrY2Cbo7dE/0Y1J8q/z+NDHWXxVtCyu7lFMLidrCJYpusF5dTLH/TcnQFfeyA+oRcGJEO8Yrji0Os3r6CPaw3i7gdwH+C175lTfDjuZk4NCLfrXzxh7JuNSALWNB2HvArDovfkQcOtmHIXzNGNekIgtY3r3kKHas4mOl4Cem7EduCAn6uIRpJ8qojSe0C7T89WfjxWvlUZoC2PHdVK7KFHqsk77btT9vFkOYLYWO/vgNCufvDOPGTv/8P9Dc1gN1e1UICx/WcDrIZwSbyPPMLmcVliRZBN1264QaNb1eyS+8V5+OVNK/iGcyEtfL13GRHCCilCoN0Z3t+vSmKucDpDe98RwrQdmoPa2x6atJLQAW0f0yWRBbXqxlxMt0Paxhx0QxnJCWJkQxjCStGc241r+/X7jz5AMp9RfsP4e0768iydng1nFaefKjJsk4j9l6/D72mIiad1Qak1GprZC5kKzgnkVqAt1espQYGQpzKk0dglOam86NGmhVlOkCfNE8VETlPMkOFgwvQBLs7LHQw10abxfGtXrnfKz14nnW0rBlmtoR94zChWyVpEtwmsEdeYa9BLpW1qZKRitwWPHw8A2UtjuIU3zTViSRnBcnHBlDCGeO++XUGwHP3sfrFAF3zX/GtEXYMtr7hGOFukoigrTaRfDEdx45uJxTPPvhruBfRY7G0I1f+oXn/9zZ+N7XvV2Y56xb7ysu3OaRI2Ynas4wbviET/2vjk1CvHBjDnv/Wh63/in3ne8tw79Xv348Tk5UOy7dmwYYoZZ4He/vL+2sydSGKdJ+AvzahKJSkxT3dGq3TqGRvmgiBYoZfo/Zsf0A3X375+iW7eXl3//Qf04Ybr779Dz7frHeKE6jWRKF0L5VqlCSlJquFb33z/7//y4pl3RYheR5Rxw/UAmboosL8dj4p8+h55ze/tWbypmfJf8ezzYrormw5wfiJg3NEPvI/fgWLaWie/UqkrzNDtxVsvs78LTuL5sk47Gf8lOFn419aw+8WIUJjIYeEJW/A5vsF79iHHmmzxGVqkw+m+QxdZJsFPa0+5j53m6U2L8tQ451NjITeXb+7sqzQZHiuwmjH60XMqWU3Vvd3o5s6wMuH9Mmt4YieIIGtoxp5ew1oTS2x3rXkFRIddnGXUfBmzNmDb6eXvf+dmPADGJIQLLtwNv+ofgRErba51FL3u2CcNo7eOwzshdSOSR0I3gwAbbADVu8OSV8289nY+lOf1Y1JP683UwnPisxvn8uI67sDyxUqJlBqV0/qNRjoOMnJZYp6TRWM6pYKvaF5JkqHlDmgSnkHWkF/OlCdCD4yKRie0Ze+gqwh4Byyg7t8t4QruAJCkEJokLrM7fJ5R+KXNuEpwYlPxI5AutYxDfBXhSKwiVAuzGNchFv5JGWFRcZbUnrh4avnQgjfzWAxH6zoTzqDBXus1kZxo9H5XkpfoQ/2M3YID7Ft0VzvARi/BL1OaWt2qZwZlYsI0rpl2fvGXCDPmVSbK9ouQ4IYlJOZtiDRvIOVaIKXhMaccfbiZFCgpJMhGk1fBRbYhKsoIbd8MYUlU6IxeQzZCiYt9EUOnooO/PQK3trVCwgjPg3eKBJ6N8hFRC53QQK3Kg1knAMNRCukEK4TRT0JusczGfboRusgh2UsibG78A+TSLYneEsL9qmdg1MTHxriFxqwbqrPMIICMh8yI0Qwpd3mukJZQUG3Ekmux4Z/ihmE+Rxz/CAdlnSDScVGOJth3WbaRlI2xYHMwYPsvT+hIJUkBhWATDg/uuIg9lpqmFcMSAV40qpl4fv3ww63IxWrl7/5O0kSvSfTt7TH73gxob2OH72vDt2H3otJrwrVLFp9kW1UhkROOS+ixQ06z/kEROcmwqHQq5l1pN+Q0w/dVmhKlJngG5PHTwNFOSzwBvpBRcXMhd8hTmDDibQ7h1OORDHg0UgkCfKoU3LwrRm75lMPmh2ikKPVntQmHRzfxbmJkUUuhZoBRkjXzcX6YgT5MOVJUVx75iaC4gDgR7aiusUI4E6V5XfSaUInElrdbZhdO4wfBRTGRVws9ORS1EPXzKhFGuac8M/JHSNUsAEY/UUbQhWNsMVqGY5y9vJmYvZOTCePN/M+SrjC5BPcuayHsKvjm6FmIkPXuT1gIm6937+o1Qq/EdELoUsSsHvBMfknWeENFBdplKopSioJOZCiSuZm75njJoIhshS7380b5phE7EZkcctjTOpGXgR6HQZvLnMCgZ/yGv9i723ll2/s2eezaMsuK62E5W2iNPoMy8CQ9xaw/SguC9zgnnEia1lOCBYFEv2FqAdVreGp9vd2QY3aRfrNQWk4HP+s5nQK7dbY5vd4/J6de2LEizstrmjZGuKYFUUauW21PkpJMBpHcLgQDhTi4EQA8+MRtkEcerVOwu892tL49bk7fJCpYk9Ojp+YcxodmOJobzLgVCEcIgy93dq8Pzk7Ounf2ogWZmzy8c8GwVOcRIAfkeCNAvtzj+O3hLQvV2mCeLTtOPspZJUjIO3aE/Jj1OIac2+gwNko9lKAN/NTBK3cqvU4KotfiDFES3PMkI8uG+9rkhgOWkhRRvU57ojrvBHP+WsPInnMZyRPy98Wfvv4aPb+9urh7ga6o0pTnFVVrkkEpvJcXJnIRHRdoXyQMsmVXlg+3zfDFiYwxKSJ7FffVf5pd9XHQ3BjwyAdr+vyY65JC2n9T99tx/AFPvpgp5j6Y9DZTDLNQ6HSDibzDGa2UHQEJiRQtKMPSiicjNs0dSuFd95dXwT1XNJsTaaSbKf/BHITaizjAxWwvebw6iwu+765DWMNVGnb8v85JBJ+MzoJz3JBOWUbmd2UKGTMxYBSygaUWMsec/r4nq5rHOwrHLvYJK909UxPLvaLSW0saCfXnJzMcvBYW4stiF/Wymn8mmOl1iiVBpSSZKCjH3oK7jni6w5oSrtXB9HiG55ztLT7rZC30IykjHVxzdZ4ZwVViqQEMqZ3qfrE6I9iREzbHSNQVyYjEmmRJsKSyPefDCJ+f6hGb4NmdFBuaNeBh7nu4LJnTVEcHw4H/mGetr9P6FZx2kjSbaZbNkA7rT+8mpultHgqZkxtqo+froeI+AQHXKJ0hm4I/VvMkD6AzdX7UqYTOPRO1OiporFghpYW0Et9QK4jGMNoz+NbCfOuZf/YFzTJG5pNyb2C8Y+WcZ3s7cu8kOVe3x5hnundutA7CEN/V0dmXqGTYbJl5n4VEhKdyV055+SEVcgZ78ogMOtnYlj8LpdEbnK4pnzDpMhxJcnw1XOsPHDL9S0mM+DD6kQU5Uwt0m+ES/Qr/sPpRJritO/3H+PFEa7whRnNiBEv0qSJyhwCDUJWCK1JrVP7iVDPfBH4zj7x0GHipoSxpjQLJ7fQtLt80n/WUZmC1PUDvHDjqsZxCl6e4DrPhGa+hpXsgRsY2dA8vVUhWnHvtWPWyeXls5NnCSE3U2DmKibMw428ERlvKM7FVSJUkpSuamk9e+uoEXZ7s+IKY6Vl+25wb9BwQYQlP22cIQpcvOquFKg7v+C3JcbpDH1Qf+LaJwBbDQtrg2bVmhBkM9onXvmtqAStQqwaHzLyIoxVvcAA81f+9SlMo5xkvX3/a8RXqKXReq157Zgwz9B4095sTJjtPXu/UVF2Gr3O917LuGqY+jQI6ns08DrsmYNDfmzYh027DaIf8gBSHi5+hbCBkS8DJCjeYckZWlDtfPQgnQPUrcDkBOgjcnVQoFom31gEzUP9CC8bGZxt77g5LaQKbsvFha43TdTEzBH47Kiw4GllH3e2I0uRlSXm4DmJB74aZMhQVxn08PUKqW7YD22JhtNvyfk/XzhHXcd++A1yXWNZnyvz5ZTuV7ZqOoNSRuR3GlrXJ70dNTwfvWWJhLYTcxdvwH1WJ+V8OIsbUjPRR1Gv13Pc0mWX58RVQPzC3s6lEo1nVeOv7ZzV5ChLCtRTlKaIjE9Vy5Fw46oy7MY21TQ6UIwCPtrpj3nt4KYoS811zH+HaQTt9a69siDTPUEL5SviVAqw+xq4ROiA/BlZkzdmWxEVFX32KlSPwU8XYDv1nhRldUZKhK6h7ts5BLytbskxSIT7SMwXdfyNLZMdv7WfMprT54GizbTi8rDSo3Ce2MD181981Q7guO84dbX3yC/R+V9qpt54Dszh2B6c3T5JVEhRMdsC24cE6IuQz5YOtHTIzh6uuUS773FnPYilk7e2HEPO724kt72DlBD5O9VqUcfsQ7VkKM/JBz33NphQikibSZ8qMY/YDlVj7XZMpT7AKGe3vEJaunD4w5UqygNvcoRpwVxpjNKlkKG9Ih6YiMsF5OJuyJR38eeqTDpr+2CftTn0EwUIeNOGgWoU3Tgz9YKe5UfTWkgxSZUJrVHaIOWoJezL3PQwL6tUr99+XjoVX7j9cXpPP7Y8Zkf7sPDedM0bP7WS6wXPwuHZarY2mk7mGaMakonxFpJyIu47nPcu8uor/waX3umdnYLLGJV51tsFzpSCsLaJeKc8Qsx2/axu3N8fuPWQQy+6f/kbGCVrTDT9puSZyHn+E0dldxtPzS2j9+AJdwvh+1ojUM4GlTKzzJZGu+SfpZWHuAeclUUPHnYXsbLgZ9JnqIEXv3Wn6+6leycdDo/h3G93T3/3eGvoxkky5+ds14iQXmtoNLNdYTXSAUuncsEKdrbSDTzcXNFsdrQPUKMFlcMZq4PS6/safkKJoPkdFRR/fqOl6+H6y0bKRJlSpKrjSCZQhWSqet+5pMRTgkEgZ1Qc62pSu9Lw2g6N7CE7vk06zZEg0yOAuivz8HlI79z9GHel5GpOPl557eJwWoUqxZBPzRR+GVJ0j28tMlpijh6vgMI0qFmH6kTiLOhK4wVdtu5LugwSy9TukIF4nJLq5v/jbmzt0Z94p9Auf6L7SchupkvoUbt9vhZ9bEEPpmqQf1UlO5OOEcFwMMl/TuQavs4EIgzRQ14KwlYJ7tFwi6QgU8gxKruWjQQWZNBqAZ411NVuHzy6XG8xoZg+ih4mhIJwN1XqfIIQV+0h2aii2A538OoE0MO211qVKKPSgjUIatjLGgqT4M7hNNOd15YuQVO8O3KhUFEVUnLgj+bZ8OIeQvwR/SyVhQ0sztItlyzBPlDpXw1szspXhv7nZ1jVaXm5tqXFSCjpHWrWPYcsBAg6AKb81AMuarjHnI+CM2HBTblRgZCJmOxNsc/OwuJ6Hv91evHXv3qvB8M2DooUc+v6DY7ZR9THZCFbFWoCLuo8zd31ums7YdTvfilOt0HPLhHoBaB1Q2Ft31B2QR8C0dzasiiTNbh2vHzjVLl1g0S862BAJmQKriqFU8JSU2hjK93YPJ+AVttuY0tcuvDHY6xbahtFSSI2EWd+f/+PCl4LrXfbQ507IfP4Ey2GBQc/FusQW7MQLFPPX61/ubu7QG/xQUJ41bb3922rmNnsaZq+J4sS03DRGs9s3rUZ98pcsBk/PtlWOyWq+gs1zF+HXU46udvScZU4q31w5lF7HxV4O2XybcmasgHrGxX/7uuGmMIdnY00y9O0Gf4kxoc+U3ejaVYMV3wR1C1vc+xKpypOijhX6UWkpeP6XJcPpR0aVJtmPr9zfXjafUr4iqf+jFZVki5lXkcFL1vkNwjxDSqCJYylJTpWWO2PZzyksSqzXDqy/4QENeRgxCU6pudi0hdC2XisVsoNC3uiTDeeE605OSs23a8i4aLqpLQaXf5r3Kb4zssIV0wnciR/QCrNeKXJvSv0M/red5Ii6U2TbMr4tW9MSr1Y0hUYCS0I4EkvAjegAejX7ovAjJjO82AemMr71jcvYcM0jq5OFig2TNCFRJN6igiiFc4dLlAojv6GBmU+RvBU5uiKpyCbCPo5WcB+VxXwOmMA0YHhOaQRFmOZFEytEudKY65oNv42v6UmPeDZ+p7yqONxDaqxbbeuc2vYEaG1sW+iw+xvVnChV7/7hLgicbIjsAlSUWCqC3hCNQVN3NbfNUM9vRa5e3dmk2hcj8lcuHaxVKzB6R6ywsCecd9icQJIhmygunKdFmwuVx1We3R6/cff85uobF3CxsG+tdQ2YAA841YiJ3O7XGNcGZgedrN1pge+pft8h83u3sYvJkzEifdJJ8Z2MEeXpkzK5JZt59+T1/9+T/XtiRo2zIU+7vmL5z8SLdfXZcLeJFSp9GmuSxMyKffqyxbr/T+MMbL94BfdPYw5XGdUJ4FF/juz1DafPiLF1wI66QRmj/DTG4mpMteT4fE9aRk5qFht32VaEZLGLQKbDFl3YRAskSbKRHjJSEp5mRQz0kBH1A1bE9CrOX2c+bIzrXT67XKNpBlo+5FnBRy9fOoda7aIDjRotm/m7P+36Ru2l4Kl5HLAWn7tlOyFuAKQuojjsru6lGcYmv3Tu863IXVtXV8UAWHLGBJHECarR1Ff0gWRIEei02/txfww1bbDUmzCi/WSDpdmEEelHbcrYExjev3TawRzN6xFr8rg1CAixsOdc/lznlboTyYYnUhHeIA8zkSvfsen4kL6c9aWnHLDRjyYX9uZu812LBzhx3YeLO5q9Fl/q4m6+j7283/+/u7yRa5/cGg/lgnWkdb1lGcIopxvCGyfZl6sImCU6zX8R1wLJPkfl78uIaEw6NES5SyT5FGGvu8FD2GCYtwPzu3aYYndwkV46b7bGtsI6xWMJsiR18uiHG66/+R4JiX5iAutvX/fTvFLBVzSv5HR+SzvvU9TdL3jeEAb9XMsmwTKeATNjKjumrib60h0MQm6xzKIpdfs71VuF5NeevoeRJAyPU9MstKp7RB3bDgwTTqpqUT6EpDnlmNW/6WsrB9Yhlv61JzHi5u7X7z1LgLxosijAEjQcjVc5xOvTHtSx4njq67MmOItYXt8z7WAodHP1lCip5bcbLAUyp8VKP2snG0uT6H423OTgtooWXBRjulwKxgA39UsUwGb1zpBzY84cVSi1S1e3h+soqrdi3M5ieqE/Q4uvSJefi6paCKXrwr3lbrRpTScuQ1DRomQ7t0/my5DMTHC6RopmBD3/Gum1rNDrP/3pBdpi10qoHmXPSnwWyusRK+H66kRbivSLORW2qUrtU2hwV81VVl4K6Dleig3pLAb1l+jU4k1pSXAxeX/SL+bYnHmpSEZPAk04tFBf+TTHxrFAV4jqGvcHRPorCxNaMz1uZ/UPBPUiOyLRa3TNU1yqiuEGrOxRct1H/YnBD09upW+Ub1+jfzPTfYm+/Rb9G0qFNPqyxRyom6n9T6b/t/kiVai/KH74Cy4y8tnaunxLkhQztsTpx/ilTxnhQtet0cCuMItY17yAaTLVlQ4OR3QwIzgyALiNGXBs+9hrIY1mzXdW6zAfdMAofEwhtBIVz8wLw6AhgwJEgOOSF/s3YkQ5RCzQXYc9YaOJXdgxgbPP5Z1z7CBFf4dmlJKmHqvDmcLdL4MtbJ/7WgibZx/rVqMVq3rbFuhnsTVbM7Y5KUdCGmNMC/SRkPLAon0WL94Xsmi2MUWyidnw/LqWPNCWyvan5tCJv2MXbqiElqk3V33fO/e4OLo93WEx7CzcVb+5QtJIawUOlXFvkcnu/81KRKtnPvtK9PuRTOTLRQkFjQV/C371DtDwmx7NqSTYNQKaEJTmf3Ug5gsIvLiRElUyGhu95LM15xWNVQj7xBTp00Cjjj3vcOvMG1B3BHKnrrZa3BPy3yPCaMXLqF3QLDF6aAEkJLq7vLhzum+KuVkeWpRCDjVeBE/kF5cGUX0e7o8P9qkCQ9zX6haNTfmq/UlrsFs9ByzzBXr9p+/RFta9IJgjzJjfV1BXP69Q6z9CWyKJJYs1YgQrjQQflIv0F/HsauKXvYieuxojbOvW7jchM1g4yGoi6ZoLJvLdMBC3onKkxSL0J5SuscSptotIAL7IcGE7uKOKu5we1vOZT1bUhi7otoH6mEGEfd0WjEVRGCVT8DqMIPF2UqaBZB2olTgFjdXGKLjzOYg0rWRNUWnMMywzxIUsMKO/+/J7hSy865O5LIeTl+i4Xnh7FqnlumHmFaMrAjP2GPiKpIJnEwp2u92J0jMA2vsmRHkqipIR7T0Ak05UDAr8NNC00ljqMx3kezO29zhPHeX+yZw8foXgwZGQs1GCxJNBD3h2poW/5lmMZTckfxf8TOg59ei1imnTa98PV3gkoqLd6AsEzbhdC3IHh1tzl+3LA/Ps71MP227YCvzpJCVJhcxIFu8ddEk27plSzYi1jlFn2jRf7MbXx6+VFMUCqFZQlK9SwrGkwqr1RcU0/aOmRCJclqyufmmxbArMce4rzUWIQXinthctU5ZXhah+ppDYchsZ07goh55Bx3HdNWl8+7RC6Zoa60ZkRC3Qm0ppMJO6RC161kReLtbkxE3aK8BWK8P3hsyhCcEm1wPatbNN03hqDwQ2qnVGNzQzmg2cB78gu68F2fvB4vkn+VBSOdsM2/20saAHcxKpZjs7WWWEntHXDFNwQPf7RgNu+gG071qeLUZDtuhqVWgJVARvxdmsf+irAhrkp4pUsx0lc7rtKWrl4xZD29OqC8DVZbME5kK1emgWNaBS0FvQCDItL3SE1zcvYvBaJhFYLZMY2nMZUhT1iYZq9dFSjaArdV6R85iQA/PR+8aMnstHvTmnis1Dcu2UYEH7QAzQEEI7gnA6UuJDKNaqYmcCzReVTkVBXlkeGuPFNXAZnRDM3RL0DMiJA0I2RFIdGxp0Cn3aje6KAKdakw5cPjM3brOvdFPpYqhB3Mm2um8NH792a4M5U5gqTleOn83k2YDGxUizUWfYphOsl29fF5mIm/Br30rvWoJCol/uXWosVXVCwNCvBuPXOzRVJalKoWhAwXHU2QJzmmctunBzdydReCqmk3jQRY8URbwqiKTpY2WRd24zdX4+opKtuRlWLNn7PZrahvAM+iQflFti+c8zoNfUoV0x7k7bZSx+LfhouaEf8F7GrKSPiVX31WQnWCdmnJdrjZvcYi40wk0nNX8CLRN5UieqnEWo1wfx0UJ9DsyUnuz7K6RbAWr1GPa7UfwFo+lujm47E3LhDhhw4Nqc7SbkcsVi5k37F/Bd5cD//eJUcE0eYmusDUM3bauAuroqy5T5P3hUMasZ8gHAHHic0zXmOUk42caWBVOBS7LthPpBCdFa0mWlSUdCjHP0lWXdaOvd52+iKXGJgwm7ZuXYqEPHLDcHDMFhfpFlpqu/eYxbqAAzC1YDDqo250tuiFyge2I3pVJELnBOAMrbZbqvhKx5GNGuyVi9PYXfI/v7Dm6FkGgpxdZ8Vv81rfs4GrNrEk/6JrvDUod20zWEQ3tU3J0So+rQue6UYFnbgzTSlRIlcQHFWG/xBUeYEamb7CLZDur+ZsNbTnx0QAAgCcmjMGeIC/5HSUoClsy+7Ic5+qL0cfR93VCsHveK2ghbHf4Zzcw11WhlPbqCAZdQbcKR4H/MhfnvPS8BKCmJR3GMOG/cCQa+AgYMk2KFoMM8JWqB7luZMmxs0K2sisPxpS3nq5QxYmzJqE22yZz4bbqZpKxSuj6Q7h+jbYKfUGV20tVEO/+GUXzh02kVaHbtx94wv0VvYZniKWXPDhlehssr4AJhpURKwV9qdsNrT8KG3dKP5IdOI0NoXPgSlRJ6orxERKfP/IoyljhUw+oDQSwYimgiFSqxAhQvBUAOrpu0KAojxUQvaD8urSE63avu2ffgXBpfZw8jPExWfKeiKKvxHYywbRhtKc/E1uXTum6TL5tMisnFGE1zVTG2Q58qzKzzMxMFpq4RL8y7HoiJiaer6/WM1MB+1BqO8o8kc7VAdSI6VuCdcgaK+eSrhrUFzfZtHBuhQkQVdd3OTtYtMWSgZu+X+3Px9UvpPK/ofgzX0wSdiSzosLFTbBerG7PTJm+/pv1tYE17RVn8O95M+ScYrbnGkmRVSlAdOSJ+d5vtqZ94XtNoj8h9r43/8H3sPIDmhZn0C5D0ozoJciCEx9iNbh66NVbr5oYatdBTZVila5v5W9fYNGWGlzWlAUSYmUgzzELJ1Pyq+fe40hQZec4RhZy7iqeMYGn+BEB4LWuugLDu/FoXdh6OPljhV41xnj7rFysVxbJp37vqPViubFQ+4vXaUFmpuT19XW0EGJj2+M0TIPVciUs7usVknPaUWgtuvsa11st8c+VacKPnDrih7k1pi34Nby/8erV1QJ+rwb9zP99cdfu7NmJi7D3oR+RsGqCdwsIeIiMLtlT5jdSN2sXEsu9HdV2BtlUX9vqxuTW+Z253fNkMjG6uDmqyofxzBzRZw9hrnrUa7QJd2vpMh3fK7Af7tVlgUPa/8c1Xzh23rHRTuSl08xhVnBFlV0bYB2Ur0AZLipdsVAVoQRkoRyXDE4JAEa6i4qP0NrSrqtqRF0ZSGQ2jri+kZp/vX93cDXVo5CBjrUdhqi77xIaCR9dCtpEWyyS64Rrd05xjEBYTR7QUMiZ47bOR/DKH9K7W3QSgOsJ/GkY6dxlOWSY8B+ftL+8R5SmrMmLEmWtka36+QM+vH3BRMvIDurMOEUsWpPfC7xeByNzssU1wTrVPi58zqj4alfsEvh5RitdxY751T8M7qj7uCblqSfOcyHgt7PxL9ms3FuB4AO10LYlaC5aZ02Nt9YlOo73Q+wyehXHs3Unl5++sjvGiAeO4ufKXkRwdnU9FUSYz513BrrjcK2jjav17qlr+0bAjONSnrqDdjMiqdMpKc2rpmbLGupw30lJIQB4wcr3mb6JLHJbZFsvzZOiNUfWNdMXuITKTmIBGfm6EKEZvcFrjKfuVWyOCZrVjBP9jraDK/VLI2prBm1pLglXw3GClsa5CKc6NPwpTdjazwwy+FA+IZq+m3y/zslZzcGg4+jACPrZ3wXDhv7r1Oxa5+97okF+N++6d8pxRLqpQMc5OHYnKg98pI0lDOh1GHtnvAhOOjczYOxIXjBm5h1SVpkSpVcXQtRkfpSIjyhyJGuzXb1lQnpGHwAvAqNKnaZ5PlC0wMJhismZiSSTENwssKYMMHo8Hz8bfeY4wLOIfzW+9M+MRzqFYWnChM2nEbnT0vMnnLIlUpSu6tRJmtGRORWgT4muEpxcTRYbWzTV+j2MnlFjlq0nycr4q+23zIaZcoYxoTJnHybAUle78bmJqgs2em1l7bHGTxwZ8TD+kmhQli5bNc4EyssIuBOSQL+sYvsvWNFrxhkiGd1DIpYV7XNFzz400H4DV7X5NVnUVuPXVK011BcCMyDux1jYYAzY99boGjWJ1/DspDs1pBFmViqIw9ynOMbq01BHtJPuWUmxoZv1nNYpcQdRkIlQm0tMDjY/3lv1EWas1pt28PL9q8FBC0tN5ZH09elxZ/0+xPNHvdPL0/o9YugCM/3aVNB5w7hUkFNudv7+7QTcjharLRjTUWlddsp+DgIVdTTVsHtSQfow/zOVW+5V7KyKSpchiV3yNKu6GSofjBRleJtSjdXi0BBsymKHyvOMCdqXDNoG2iYfQnGZNKGfCiVeEthpHZeABXv5wSl4z77KK+UzV3b3vPlj0nDoQBckaDyStul4Em/q1JL7y1hqFaV/ixgyOEK9XPOs7RJrqSrzBlOFxIAM1rnAE9ZUrIuVEpwV7h07x9YeLuzljpXAAUDYAO5qSSzdQNF9MSERaJMsqy3bB/TO0SILWAXXoVoqcBnS+10sVnqKkIiDKwaDELlHVHAUJVHWzVy3mKq4yqpvKuhYXzXHka2zXVmxYUdKGF/ZP0maJhV7BzWxW+eWv1+i5q5X4tWJGV15SBgUckAd2/VAKZb75Av1x7GjgwyjMRy62vGcIKZJWAGax6VOf6LSZ4hlccMO00Mu6yv2tK026JTlOd+jDpLnG6FLicxTlu4F7S0w5KjDlK4kLsjcdo8QSuvbGx0noKZd3MCx6KzKbHN3CAnayzjxMoQPaF6QKmIWIZSH1cePeki36ueJgSr4RGWHoOeWbxR9eIirSl2hp/o+Y/8Mcs52iavEHf3xRp2WyYnjUOT+0DtXX8C/vEAwKvi6Qk7u6+ZVY7QVq0CIqp/avS8dnDYOgiDQH2cvQpggrdwec/frmNywJem8TgP/wh1/f/Hbx7voPf7A5txssMZ08k1shP4YsWT54wX6rB+xG2CadYJiHViJczU5YlJLmOcCpeS52EUyYlZCEK5qGFCAdV1IEjovwXhBPfCAU0WSL6bg58ZO9A4B9HpqouT6hS9RVtYx0KfQyU1qGrnyHeu1oDrHuWxrsHa1rPuI5SU8tdmkbg41UGlds0ta9uHoXQ2JFJx1N9VSjOWJPnaoXjcgzzWF5j18on4wn+HjHhWHe6f/vxqO2KrPt/HeWI5Z1fPSOkb1MnuVw1HHcffwJMUPSVm9nO3bpc91ktNdZdoCT+QLcbqOTezgyXUNW0zniYVD0tcKUmbWuwVzunMy4uerWtgESlzEHNck9EAbTWYV1znViVMQT5nNK4jWkW7vqo0tRFBUfeqJG3PHTgJueyt1b8qD/Svw6dcObOk2zfipv95hn/yH8UbOWN401PUUyPJm78cA95lSlSppSESxLdC4LHrjfYsnHQYfPnXXFizIRsYTx/ds3d+gX60dtk1L9jHyaNZXg/j9v0aeKyAns1orxRJIhUmfc5IaOQ3SH3tVFZ960rkZLTwM+pF2iInQbAUO0PMlxdIiq9gTHnkw3C9+gATMsiwi7ZchGcC/gMmABckO0yoJ1pe3RDIt21SOdYT3UCp9Kd0l4ui6wDFVW0tDdlXjUvvjJ0SecjtKpgtBM1sHPQkpWYQuoGsKrHKCWIpAVy39GoFri4J0wLOJU8OMFQfeEhn5wHHJbQYzqGZxpnuAUGqOELz8xtBUPaLx3CC/zcvMdf9Dr4O97ypNUyyRTQXHXO9QN5dMiT0cQ3jAcXGLwhPCc8oBFkWPSMXKjebJK1JbqNLj84MmKia3CRfjclS5trjfxqEeIuqQ8oTymOKG8JLJY7oIlvI9ol+nHOMQ3mMU4K7RMSim0SMKHpID65rsEPI7habNod5OJPMliLLYhHD7/LeVJgR8SrUO5DfqEzYlmJMKjUFAeiWnK4zFdMpWwJUtCh0V7tL+OSDw4MniHdmgsxC7t0FW9Xdp/ikj7+4i0/zUi7f8Vkfaf49DWomR4SWKIlIZ6ePOMJ0XFQPle7iK8kzXx8mMEvaSoGM2LMo72bbRMzPLQSUiOMo2hlCjyKQ3vG+GJsgmJEXZQyTSONWkIx7Em1U5VZYRepClvyqqjmKpaaGN6kIcIIkQLbQyzWLTBrIlCvOL0gWMuFEkjHMLN92ZVIj0Km+9FqdcEZxHcaqIok5RF8GEbwhGCJEBXLnc6vFvUUFZRKJdVEiGmkUqqaYpZhAIileCc8HQXMOuqS5tjtvudZMsYfG8SgAGNQtnCwcTh2ibWRqG+zMvN93F80CpZUv3nKEBjqUrC9oobEJYiuKhWUa45UCWpDF/lpqyPP1ivrQ5hotfWzx/eOWKJg9oXhbhFkw+HINehvaKMxLBhVLKKsYl0FbI4u084hm6gElpCkmISRdTRcvNdpnQ5AvMPRFvJNAptRlckhhmjwNFckIwGKxjt06Y8zikpRFYxolIRY7UdcZpHkE2iVFusg/b871D3ZZAHISxJTpWWOLwnpKUdQeOTpIy11DLaWitAIpeR5KvNzLdHPAJ1LQkuIiiSthQoFtvxlOvtWlCV2A6z4anvsMRRDng2UQgbgvLG9rcPTZcqjXnwPseZ0stKhmoWWFMltldQDKpVcF7D69F1TXJostC5YRW+2fWpSAP7aOY4y0LfAZqFDqvW0EER3iJaJKkUooiCSmQIRzDTaJHESY50iEcxlrn8GByeqVThIUtpqUpJAxNlWFNdBc8+Y5STcBA7LVUVtKNOQxeKb8O7tZiwqKfJiongz3lDPELKv7F5g0sdQzSCxDE2dARWg+cmMJFHObo8j3KBSyFDC7BiWeUxrllBVRpDLBQqyoGN0QeCEw3gSsHpBpfhFgA6dMafpRo6HY9vt6EtkCgVZcI2gA5uiYrwmpGQNE88/bieTHfLiQz/ZpWJbcobnGzQztQtWdviNcohi1C46XrihBYGjmxoaVAm1pEUnF2slPkwSdeh6vxHpMlDSYMHAkoii1xirkeYuyEob6MQDv/0WiSyDx8GXUADEJYiT7AqAzYM6JKWODRVSTCLod9JksI6WNTRSMTDL7KhHBbCtUNZyCwCx+EdmSqCb1hZ33CEfABFQicC2IbHEYwTRT6FPwA+gNZgVCOYUormEQSvKkN72ZRMY9wDmWbBFWklUx8qbgDCOlyLrS7NSgVH1dykPHShhLdb7FOJWpDO0NPXuQ5/rCzR8BG9pqdnaLq7Mjhaa5Uto+ShV5JFeAsrRWSS0dBV71HaVtSRoRjLoFOlcRHaG7xJKFcaryJoBhsqdQw1fFPyCNBNWsiKh3Sz+mDRPIiiF5UW6F3F0WjoJnskYrO8XzGjGbqUJKMaXWKZOTRDBfDvfnZs56yIqzTVIRTIQBN9BPgGqWDIV6rT5ENQHm/lrouSiR0ZNRY8uH4rUQUD9T7yjJk1tD4j6HcmSU4eUIGHQAttLJbn1bAZSHQmGVXQnKEe3W09ACghVZWlkBqNgUcR2q6xRlSjUpLV1FF4QlruY5pQ+BbeWR0NC4hyh+w+gQvNKI/dkb/Dqhmty6dCWuREr4lctN9Xa1GNXjSEONkQ2bQj0gKVWCqC3hCNoSO4vau4WYLntyJXr+5s2esLdOVafL1Eeu3pUgRgwO+Ia30MbHP0lujfqOZE+fd5fKijLN4KWnY3twgGt5NVBMt0vaCcevmDnrsz4GsPxCf0woBkiFcMVxx6/eYV9HGtQdz9AO4DvPY9c4oPx93MqQHhdv2LJ4x9sxFJwJqm45BXYVj0njxouBVT7oI5ulFPCKS2cd1b6FDN2UTHS0DPjdgOHPBzFdFIkk8VUXoPaPfp2cqPx8q3KgO05bGjWok99Eg1ead9d8o+nixHEBvr/R0Q2tUP3pmH7P1/uL+hGezmqhYKMLb/bIDVEC6J95FH2DwuS6wIsunaDTdodKuaXXK/OA+/vGkF33AupIWv9y4jQlghRQi0O8P7+1VJzBVOZ2jvO0KYtkNzUHvbQ5NWEjqg7WO6JLKgVt2Yi+l2SNuYg24oIzlBjGwIQ1gpmnO7cW2/fv/RB0jmM8pvGH/PSV+epdOz4azi9FNFhm0Ssf/ydfg9DTHxtC4otUZDM3shU8E5gdwKtKV6PSUoEPJUhjQauyQnlRc92rQwywnypHmimMhpihkyHEyYPsDFebmDoSbaNJ5v7cr1TvnZ66SzbcUgqzX0A48ZxSpZi+g2gTXiGnMNeqm0TY2MVOy24PHjASB7aQy38Ka5RiwpI1guLpgSxhDv3bcrCJajn90vFuiC75p/jahrsOUV1whni1QUZaWJ9IvhKG58M7F45tlXw72AHou9DaH6H9Xrr7/5s7F9rzrbUa/YV1623TlNwkbMjnXc4B2R6F8bn5x65dgA5vy3PnT9T/wzz1uee6d+736cmLx8SLY9GzZMMeMs0Ntf3l+buRNJrPME/KUZVakkJebpzmiVTj1jw1wQBCv0Er1/8wO64frb1y/Rzdur67//gD7ccP39d+j5dr1DnFC9JhKla6FcqzQhJUk1fOub7//9X148864I0euIMm64HiBTFwX2t+NRkU/fI6/5vT2LNzVT/iuefV5Md2XTAc5PBIw7+oH38TtQTFvr5FcqdYUZur1462X2d8FJPF/WaSfjvwQnC//aGna/GBEKEzksPGELPsc3eM8+5FiTLT5Di3Q43XfoIssk+GntKfex0zy9aVGeGud8aizk5vLNnX2VJsNjBVYzRj96TiWrqbq3G93cGVYmvF9mDU/sBBFkDc3Y02tYa2KJ7a41r4DosIuzjJovY9YGbDu9/P3v3IwHwJiEcMGFu+FX/SMwYqXNtY6i1x37pGH01nF4J6RuRPJI6GYQYIMNoHp3WPKqmdfezofyvH5M6mm9mVp4Tnx241xeXMcdWL5YKZFSo3Jav9FIx0FGLkvMc7JoTKdU8BXNK0kytNwBTcIzyBryy5nyROiBUdHohLbsHXQVAe+ABdT9uyVcwR0AkhRCk8RldofPMwq/tBlXCU5sKn4E0qWWcYivIhyJVYRqYRbjOsTCPykjLCrOktoTF08tH1rwZh6L4WhdZ8IZNNhrvSaSE43e70ryEn2on7FbcIB9i+5qB9joJfhlSlOrW/XMoExMmMY1084v/hJhxrzKRNl+ERLcsITEvA2R5g2kXAukNDzmlKMPN5MCJYUE2WjyKrjINkRFGaHtmyEsiQqd0WvIRihxsS9i6FR08LdH4Na2VkgY4XnwTpHAs1E+ImqhExqoVXkw6wRgOEohnWCFMPpJyC2W2bhPN0IXOSR7SYTNjX+AXLol0VtCuF/1DIya+NgYt9CYdUN1lhkEkPGQGTGaIeUuzxXSEgqqjVhyLTb8U9wwzOeI4x/hoKwTRDouytEE+y7LNpKyMRZsDgZs/+UJHakkKaAQbMLhwR0XscdS07RiWCLAi0Y1E8+vH364FblYrfzd30ma6DWJvr09Zt+bAe1t7PB9bfg27F5Uek24dsnik2yrKiRywnEJPXbIadY/KCInGRaVTsW8K+2GnGb4vkpTotQEz4A8fho42mmJJ8AXMipuLuQOeQoTRrzNIZx6PJIBj0YqQYBPlYKbd8XILZ9y2PwQjRSl/qw24fDoJt5NjCxqKdQMMEqyZj7ODzPQhylHiurKIz8RFBcQJ6Id1TVWCGeiNK+LXhMqkdjydsvswmn8ILgoJvJqoSeHohaifl4lwij3lGdG/gipmgXA6CfKCLpwjC1Gy3CMs5c3E7N3cjJhvJn/WdIVJpfg3mUthF0F3xw9CxGy3v0JC2Hz9e5dvUbolZhOCF2KmNUDnskvyRpvqKhAu0xFUUpR0IkMRTI3c9ccLxkUka3Q5X7eKN80Yicik0MOe1on8jLQ4zBoc5kTGPSM3/AXe3c7r2x73yaPXVtmWXE9LGcLrdFnUAaepKeY9UdpQfAe54QTSdN6SrAgkOg3TC2geg1Pra+3G3LMLtJvFkrL6eBnPadTYLfONqfX++fk1As7VsR5eU3TxgjXtCDKyHWr7UlSkskgktuFYKAQBzcCgAefuA3yyKN1Cnb32Y7Wt8fN6ZtEBWtyevTUnMP40AxHc4MZtwLhCGHw5c7u9cHZyVn3zl60IHOTh3cuGJbqPALkgBxvBMiXexy/PbxloVobzLNlx8lHOasECXnHjpAfsx7HkHMbHcZGqYcStIGfOnjlTqXXSUH0WpwhSoJ7nmRk2XBfm9xwwFKSIqrXaU9U551gzl9rGNlzLiN5Qv6++NPXX6Pnt1cXdy/QFVWa8ryiak0yKIX38sJELqLjAu2LhEG27Mry4bYZvjiRMSZFZK/ivvpPs6s+DpobAx75YE2fH3NdUkj7b+p+O44/4MkXM8XcB5PeZophFgqdbjCRdzijlbIjICGRogVlWFrxZMSmuUMpvOv+8iq454pmcyKNdDPlP5iDUHsRB7iY7SWPV2dxwffddQhruErDjv/XOYngk9FZcI4b0inLyPyuTCFjJgaMQjaw1ELmmNPf92RV83hH4djFPmGlu2dqYrlXVHprSSOh/vxkhoPXwkJ8WeyiXlbzzwQzvU6xJKiUJBMF5dhbcNcRT3dYU8K1Opgez/Ccs73FZ52shX4kZaSDa67OMyO4Siw1gCG1U90vVmcEO3LC5hiJuiIZkViTLAmWVLbnfBjh81M9YhM8u5NiQ7MGPMx9D5clc5rq6GA48B/zrPV1Wr+C006SZjPNshnSYf3p3cQ0vc1DIXNyQ230fD1U3Ccg4BqlM2RT8MdqnuQBdKbOjzqV0LlnolZHBY0VK6S0kFbiG2oF0RhGewbfWphvPfPPvqBZxsh8Uu4NjHesnPNsb0funSTn6vYY80z3zo3WQRjiuzo6+xKVDJstM++zkIjwVO7KKS8/pELOYE8ekUEnG9vyZ6E0eoPTNeUTJl2GI0mOr4Zr/YFDpn8piREfRj+yIGdqgW4zXKJf4R9WP8oEt3Wn/xg/nmiNN8RoToxgiT5VRO4QYBCqUnBFao3KX5xq5pvAb+aRlw4DLzWUJa1RILmdvsXlm+azntIMrLYH6J0DRz2WU+jyFNdhNjzjNbR0D8TI2Ibu4aUKyYpzrx2rXjYvj408WxipiRo7RzFxFmb8jcBoS3kmtgqpkqR0RVPzyUtfnaDLkx1fEDM9y2+bc4OeAyIs4Wn7DEHo8kVntVDF4R2/JTlOd+iD6gPfNhHYYlhIGzy71owwg8E+8dp3TS1gBWrV4JCZF3G04g0OgKf6v1dpCuU84+XrTzu+Qj2FzmvVa8+MYYbeg+Z+c8Jk58nrnZqqy/B1rvda1l3D1KdRQMezmcdh1wQM+nvTJmTabRjtkB+Q4nDxM5QNhGwJOFnhBlPOyIpy56sH4QSofgUuJ0AHgbuTCsUi8dY6YAbqX2jB2PhsY8/dYSlNYFM2PmytcbouZobAb0eFBUcj66i7HVGavCwpD9dBLOjdMFOGosK4j6dHSHXLdmBbLIx2W97v6do54jru23eA6xLL+kyZP79sp7Jd0xGUOjK3w9iyNvn9qOnp4D1LLKyFkLt4G/6jKjH/y0HEmJqRPop6rZ77niazLD++AuoH5nY2lWg0qxpvff+sJk9BQriWojxFdGSiWo6cC0edcTemsbbJgXIE4NFWd8x7Dy9FUWK+a+4jXDtop2/tlQ2R5hlKKF8Jv1KA1cfYNUIH5MfAiqw525K4qOirT7FyBH6qGNuh/6wwoytKMnQFdc/WOehlZUuWSSrER3qmoPtvZIns+K39jNmUNh8cbbYNh5eVBpX7xBamh+/6u2YI12XHuaOtT36B3u9KO/XWc2AWx+7g9OZJskqCgskO2DY8WEeEfKZ8sLVDZuZw1TXKZZ8761kshay9/RBifnc7seUdrJzAx6leizJuH6I9S2FGPui5r9mUQkTSRPpMmXHMfqASa79rMuUJViGj/R3C0pXTB6ZcSRZwmztUA+5KY4wmlQzlDenQVEQmOA9nU7akgz9PfdJB0x/7pN2pjyBYyIMmHFSr8MaJoR/sNDeK3lqSQapMaI3KDjFHLWFP5r6HYUG9euX++9Kx8Mr9h8tr8rn9MSPSn53npnPG6LmdTDd4Dh7XTqu10XQy1xDNmFSUr4iUE3HX8bxnmVdX8T+49F737AxM1rjEq842eK4UhLVF1CvlGWK243dt4/bm2L2HDGLZ/dPfyDhBa7rhJy3XRM7jjzA6u8t4en4JrR9foEsY388akXomsJSJdb4k0jX/JL0szD3gvCRq6LizkJ0NN4M+Ux2k6L07TX8/1Sv5eGgU/26je/q731tDP0aSKTd/u0ac5EJTu4HlGquJDlAqnRtWqLOVdvDp5oJmq6N1gBoluAzOWA2cXtff+BNSFM3nqKjo4xs1XQ/fTzZaNtKEKlUFVzqBMiRLxfPWPS2GAhwSKaP6QEeb0pWe12ZwdA/B6X3SaZYMiQYZ3EWRn99Dauf+x6gjPU9j8vHScw+P0yJUKZZsYr7ow5Cqc2R7mckSc/RwFRymUcUiTD8SZ1FHAjf4qm1X0n2QQLZ+hxTE64REN/cXf3tzh+7MO4V+4RPdV1puI1VSn8Lt+63wcwtiKF2T9KM6yYl8nBCOi0HmazrX4HU2EGGQBupaELZScI+WSyQdgUKeQcm1fDSoIJNGA/Cssa5m6/DZ5XKDGc3sQfQwMRSEs6Fa7xOEsGIfyU4NxXagk18nkAamvda6VAmFHrRRSMNWxliQFH8Gt4nmvK58EZLq3YEblYqiiIoTdyTflg/nEPKX4G+pJGxoaYZ2sWwZ5olS52p4a0a2Mvw3N9u6RsvLrS01TkpB50ir9jFsOUDAATDltwZgWdM15nwEnBEbbsqNCoxMxGxngm1uHhbX8/C324u37t17NRi+eVC0kEPff3DMNqo+JhvBqlgLcFH3ceauz03TGbtu51txqhV6bplQLwCtAwp76466A/IImPbOhlWRpNmt4/UDp9qlCyz6RQcbIiFTYFUxlAqeklIbQ/ne7uEEvMJ2G1P62oU3BnvdQtswWgqpkTDr+/N/XPhScL3LHvrcCZnPn2A5LDDouViX2IKdeIFi/nr9y93NHXqDHwrKs6att39bzdxmT8PsNVGcmJabxmh2+6bVqE/+ksXg6dm2yjFZzVewee4i/HrK0dWOnrPMSeWbK4fS67jYyyGbb1POjBVQz7j4b1833BTm8GysSYa+3eAvMSb0mbIbXbtqsOKboG5hi3tfIlV5UtSxQj8qLQXP/7JkOP3IqNIk+/GV+9vL5lPKVyT1f7Sikmwx8yoyeMk6v0GYZ0gJNHEsJcmp0nJnLPs5hUWJ9dqB9Tc8oCEPIybBKTUXm7YQ2tZrpUJ2UMgbfbLhnHAtd//j/wYAAP//M4fDsw==" + return "eJzsvetzG7eWL/p9/grcfDhxUra84zxmds7M3NJI9rbOyDK35cfUrV3FArsXSURooA2gSTF//S08utlvtSgsSp45+ZBKRHLhh9fCeq8X5AZ2v5OlVIYJMP9EiGGGw+/kzf4vKehEsdwwKX4n//5PhJDq++SdTAsO/0TIkgFP9e/uU/vPCyJoBr8TAWYr1c0JEwbUkiZwYv9efY0QuQG1VczA78Soov6J2eXwu8W3lSqt/T2FJS24mbshfydLyjU0Pu7ALf+5ohkQuSRmDSUwUgEj2zUocJ8ZRZdLlpA11WQBIIhcaFAbSE8681Oa3mMyKyWLfPpU2ou6H9ahFpQ3pjc8+tD4fUPsB8n0qvH38RGGN6yzKx/XTNvvEaZJoSElRpKE5qYI66/olmSgNV3Z/6eGJDIDbSct7ect0oRcyhU5h0SmoPon4mmxNqhDp1PShQ0IM7dTi0w4AEZe/bDk2q15IoUBYbS9H0xoQ4UpYehejIZlhwBMqWl/0EXHPCY7BKGGbNcsWRNKNGjNpCBrZjSh5ArMF2YEaF3u/knnaFST1WtZ8JQI2IAiC6jOXU6VBvIODLXQKFkqmdWGenYpV/rljCY3YPQPHfLnTEFi+O45MQE3JR/AMwt/wkUN5knvQnLYAD9gJbkU7fvZWMlzyBUk1AQkKSyZgJRIwR0sQxccSEbzflSZXs2jXZiRPX4X7vnF+U9kQ3kRbjxLQRi2ZOF0wi1NDOFy5fdLdTbCzY5Z8uG0uO/Z7cipMiwpOFXu92FjTwZPRof0QSel72R0KA+flMEt2Rx3T1793z0Z3xM7Ks6GPOz6ysUfczeR9rY8GXQbegjTQ4emQMtCJUhv78OXDev+PwyZNtRABsI8RXC0SJmZJ5y27vATgQfCqN1TBLa2MtVTBMbEYcBwJaaSczzdk5YCPYR74C7bEiCNqUMNyDV9embti6VZwKLpyCEdIeFhWkRLDulQv0OLGF7FlmnlSKsoalaV3uXzy9WZZqTlIz0reO/lS44hVheCfS1gL0arav7hT7umUnsmRWIfB2rkU9dsB9jNhuGyw/rqntlh2JIltH6fL+WKvN6AMOTaMWdSiBSUVUEUBEbVmfqS3UJKNBhLpPHj5hh6WGEpN6FD+8EKS7UJHdL32pSuJTC+femwg9mZ1z3W5H5rsJYaSV6tn8u3Ups6i+TtE6lBpEysyg9137Gp2ZC+nfVlhxywzo8GF/ZitvmF0DRVllcOXff24nZmb+S3urib37CX97f/uctrVwufN7T5gjek1a1lKaFkxTYgKiPZtysI2CU6zH6Bq4GkT1H4+zY8GoMGDZnv5gq+Iux13XnoNtjNe7Fzq/zaD01m7iI9D9ZsQ8nHXQ4koV0OsgACzKxBkU8Xwvz0G5GKvOGSmp9fkQXV7hSVDrIlWxXKiX53zPsQcfcbnrdzg+IpnxHsC/bXK4llZhvTjsuRv3kDg1RbqlI0oa7G0WrTrq/kxexzQ96jRAGn7S0lRO+0gSw8ogG2pbYGf1K1Xzz7/1KxFROUl79pSit3rAOW/DUSGHEx+/xbzxIE+J2VePgSVIi6qxzj9dkf1K7geOjrswaagjqK7/qtG4pcnD/ES+rx1p2ljsxhvtInbWTjyRzdzkZLQetiL2i5i2JVlzPJOSRGqm+RAdvVe4SYG3vmmCaJXzpILdKGoHop22ILGVnoJ6jxZcniqYiqmdQu2C2Tgix2nU0jRMHXArSxBDXLcr4L+2S/bBk9AZqsiWYpkGd/IWatCvLq119/IFuqiQYQ1SgjK/EkhNcJK6FzKTTgLUXyzZyKRBbCVDaFIlt4pmevsu6lQJ7RhdxAbTGY6I2sLNmbNgpoNnh/km/m2DzyUkHKiracFmOhvuuTHCvDAlsSZv5RvPrLT3/VnqW/zB0DLUH/ozObf1h98JLuQJFX5LVIaK4L7j0rVqW8F1/vo/5A50dPbGXfKD+/Iv9mp/uc/Pwz+TeSSGXlZTeLMOhz8r+4+d/2i0yT5qJ817uFQqbwZHVdsYV5Qjlf0OQGVwL24IQ07tpQ4/UKu4gg0lwyYZxqYqA/wNkdjjkoJZHi0/byoM4hYZQ7xA6pNlJZyVrsvNRhP9hQzlJ/MPpAEbKUhUjtC8PBgWdiFYSjO4MXmzeiQzmGLzBchxG30cAu7Lik6VN55wIcotmfQDIwiiU9WkdQhetfdrqwf+5LJmyffWr2Eq1cltt2Qt7Krd2ars7JBJHKKmNGkhuA/I5FexIv3jeyaEomoPV8w9J5iuV1fV1ynhUIUNS4S57aFazphRumTEG5VdobtnfRY+JgGbNqt/OVu8XwswhX/eKcKMuttTOouEWjagWm+tqdK6EVUtDTo6+Ej4QbXwmF4grqMv6L89L2+gEyaYBch/OeKHAP7WI3xCjtP6Uj5htwvISR5jrnDDOy4Umr85p1xP4nIZtZnot43t2ts29AOOvlqSu1lvCE/PfwMHr2smT8EXz0dlSrHM3OTmdB9k2osMvDslyqtsRL3BP5zYVBFE/D/PHJP1VOEXeqe58ptanKF/uf7BV2L+c4zfyEvPr1N7J1654BFYRy3m8rcEZ9Jybt7UdkCwo8WWoIB6oNkaKVLtJcxEcXE7/tRey5qxhu27B2X6RK3cK5qCZI1kJyudq1HXFLpjpSLCG/kmRNFU2MX0R7qXcOvzOaC1KIENPDGzbzwYza2And3lGP6UQY8V06jSKzQqYUpRtB0e0gT3OctSVW0sRJrN5HIYLNQSZJoUqK2lCRUpUSIVVGOfuzL75Xqqx3fdIQ5XDwEsli0XmS7rVIe9QVmJecLcHNuEfB15BIkQ4I2PvtnmuDaWcZmRATicxyDqb3AAwaUakT4I1iLTZYyzdT5pEO8rUdu/c4Dx3l5skcPH6ZFGYdaZv2+amxYl72UU7pIy38a5FiLLsl+acU2NUWRtiiHb0UMX147cf2CndYFNqNPiUGbk24fGQDStfSKdKxOLCe/X3oYdsBjTXNfZpeIlUKKd47GIJswjOlqxFLGaOMtKm+WPevd18rJbMTR7VwSfk6AUEVk16szwpu2AvDQBGa57zMftnXssmooKu+1FxCuHPvlPqiB+WxasLM95rIrfCeMUOzvG0ZDIjtaBZi9/YZTZI1s9qNTEGfkHeFNk5NqhO1t5KagbhcauDATRplYMulxb2BY0hCbpPLAf3aKViCApH4A0GtaJ2yDUutZOPOQz8juy4Z2cfW4vVP8jZn6mgz3O+n9wXd2pPIDN/5yWrL9Ky8ZkG5AzpuG4246YMmnOeWG1f87KQzZBVOJovYHCjrCHIPpVitf+yr4iTIrwUURztK9nT7U7Tnj1uqiQORDpwbB+6n2IsaUShoLCgCT1tlBuH1XWUYWPM5AtR8jiE95zFZUZPoq+hUEWSl2ivyOCpkS33sfWM6z+W93pxD2eZdfO0QZ8H+gWhVQ4htCKJJR4iPIVjrgmO7nQa0KFmYRGbw0mOolBcXlS2XnRNCRViChgI5cEBgA4oZzNSRkYmVo4ckwJpnZ8zkg5u82Kkd6F/pKtPFUnN+pxwStmR7xadfuvXOnKGaKkFWxo9m6tmAysTI0n3CRGmiSoOTpRd3UJuPtQmfm1p6XROUiry/DqGxTJcBAW27mhu/3KGhLEmdS80iMo5JZ8up0yL1FaZcKH95dwer8BTczPFKF92TFYkiA8WS+/Ki3rkdIYttZGL1TLbqZni25O93Z2obEKlUIWB2dGZy8ccjVK8pXbty8Qck/Xq0BYafC95ZbstBx4F5To9Zq+677oUMWf+BzQQr15pWscVCGkLJOlS86A+g5XI1LwNVHoWplwfx3kz9GDVTGrzvby7cylWtduyjX/CXnCU77NszwhdmDkAori34boAvFxwzbrp/AT8UHBywfnYqhYFbbIm1AnQhvL1uXw+Vpqm2/3KPKuUloL4CMHc8zsmaihXMBWyxecGQ4xK2NVe/E0KMUWxRGKhxiG6MvvbQrbRef/76WYfOaTRmV60cZ2hlK8cWzSmC7fgiD6Yuv/Uoty4DzC5YWXBQ72O+1AbUCbkGvymFBnVCV+BKeYdI96VUJYYO7ZKMl9sT93vif1+rWyEVWSi5tZ+Vfw2yple7ButJX6QzqkxsM11FOLZFJdwp2ckOPdadkjytxEasKyVzCA5FrLf4VBDKQZkqukjtBw1/8+6twD5qRQBcEFKPwJwSIcULBTk4TWYs+sGpDcd8cpJCKXthKn3F7aST414y72Er3T+dmW2ZWQdh2fN6cu4GXLhsE0GkeLGS9r9HXgInpMx7BEfEedOaM/ClA2BByiWx3MEw0Cfkes9T2o0N6plVOIjPfDpfoa0S41NGfbBNGthvWHhKEl5oUx7I8D+dbXI/YdruZMiJDvYNK/i6T4dFoKNLP/6G9Wv0viwTnlD2/V2Kl0V57lAQqrVMmLOX2t3o1Sfdhl2yG/idUJKvd5ollJOU6ZvnJFeuJ8pzAib5vl9Qpooeknt5z4fe59komoEBpUlOtavipV0hB1+LIJFZZrmYbDjtu6k1YJJRcc+/B48l8dX2EOFh8uw7kVledO8gwrZRsmUildsQT5tIkUBunleRFIOL0ZnmsuB8R74WlHvjZyozykTgGqI2EJcDT1fd6hlLXBqZuhUJL5m4gTTkApWB6FQ761RQUOwn31XQTlg6tnG8UxUCldXVOzt5s0QbQAnv/fVj4XqfB8srue6W66mczqAy1m7shG1iDWM6tP78j0vaP0eWtJeM49/xaspv3GjVNVaQFgmQ0nME/eY2DYpRPu95TdEekWs3ZCk2t9/H2gNoX5hBuwAkN/qgkgMxLMZhdPvQraleVzfUioU9WYZFsvaRv2WOTZVmeFZSapUIsxOphjnRKrG/qv6/m2lKLD8XhLmYu0IkHKiyf3KF8PbQQgJhsHaqMrHzbu+DZ35Ft87Tk36xEpktmKjqZtcfrJA2qu7xem2YKvSxLX11acQBGLb4HcdB2nMlzvzovibjsKXUa3DopvFq+byV+eKcXHlO8ywUbiC+215I+rXYfuiXq70B+jFs+TXz88W5W9KQ8laxia71oOmR82GAfgon/hBZXrBlul9J3egdZi37plc3JGh7cWHUji288n3EU2OX/qwamFyc3ynJxrLP3SHJWmCvRLqXaE/Imc/PDPVOuf9gXJp1AFXzGz99F8xxi8JUmZvSVI9RIThovzLSPyhbSTZUMbrgnSxAX5SBCZJzOsAINAiNWh+lsaF1UdWPfGI5lZUwyvxCZvf5+uXFrC1Dk1Ay1lsUhvKyD2woODkXcu9p8SDJhTDkmq0Edcxi4IjmUmEWr/2+w7/sIZ2Vspt0VR3df1ogtbvsTlkqew7O1fuPhImEFylYdhYa2dqfn5Bnr29plnP4ncy8QcSTddz7pN8u4jxzR/dtOuPU/mnpR8b0jRW5D8B1j1S8mhnzKjwNH5i+GXG5GsVWK1B4Lez6l+xz3RcQMDjpdK1AryVP7enxuvpAp9GG6/0IloWu7z1w5WcfvIzxQ1WM4+K8P41ksnc+kVk+P3LclduVEHvl2rh6+54uFi8sHClcfurStZuRaZEMaWlBLH2kqLE68opbSuUqD1i+XuIb6BJHVbql6nEi9LpV9S13peEhspMYKI38zDJRSt7RpKyn3C/cWhZ0VD1GihelgKrGuZDXNaM3tVZAdfTYYG2oKWIJzpU9ijL+aGqHHXwhbwlLXw6/X/ZlLY6B0CL61Cl87O+CRdF/dct3DLn7XueQn3f77h3ynDEhi1g+zloeiV5Fv1OWk8Y0OnQssr9EJoxdmbFxJE45t3yP6CJJQOtlwclrOz5JZAraHomy2G+/ZsFECreRF4AzbQ6TPB/IW9zAThVTJYgFKOffzKhi3EXw9FjwvP9drAh1i/jC/rZ3ZgLhHMqFLy70SBJxGJ08q+I5c1A6D0m3nsN0liyICPuA+LLC0w8DSYbezNV9j7EDSrzwVQV5BVuV/7b9kDKhSQqGMt5jZFjIwtR+NzA1yY8em1labGkVx+ZwDD+kBrKco0XznJIUljS4gELly9KHH6I1rVS8AcXpziVyGRkeV/Ks50baD5zWHX4NyzIL3NvqtWGmcIUZSe/E9rpBt2DTQ69rVC9Wzb6T0NhIEXhVIrPM3iecY3TmqRNWC/bNldyw1NvPyipyGejBQKhUJoc7Gu9vLXvD+F5qTOpxef2iwW3ugp4eh9eXo+Py+j/k4kC708HT+z9yERww/bcrZ3iFc89dQLHf+evZBbnoCFR1GGhVa0N2yTiCiIldVTbsKqoifR97WIit7hfuPYuYL2SKnfHVybhrCx0BC7FYBsSjdfxqCd5lcITM85oJOKQO+wDayh/CViytXDkDRrwsttbYSQOP8PLHE/KqeecF5jNVdveeffLVc0pHlAvWuIWkqFsRfOjXAvrSW8sqTGOBG0cwhPRaxdOmQaTKrqQbyjjtOjJIZQonLr9yCUoNdFrwd+gQW388v1tQVrJQAMo7YDtTCuEGmq1OBjgiy+aLIk130e0zLJtHzQOq0S00HFbofNRKFZ+iYjJilYNWit1cF8dISGC6Hr3qa67SImWmyqzb10ULiPoa2+0zNjwr2bsXxifpo8Rir+DmaFr52efX5FnIlfhccCsrLxh3CRwuDuz1bS61/eYP5EXX0CDaXpgbIbeioQhpSApXzGLTpD7QaTOhRzDBtcNCz8os96uQmnQJK5rsyKdBdY2zhaKPkZQfBm4sMRMko0wsFc1gNBwjp8p17cWvk9AQLmduWHIlUx8cvS8LWIs66wFF7pC+XKiAXQgsDalZN+4KtuRtIZwq+U6mwMkzJjYnPz4nTCbPycL+C+y/qKB8p5k++bHfv2iSfL7ktNM5P7YM1ZTwz2bEDepsXY5P7srmV3I5WqjBSFSk/q+LgLMsg6BB2YPcC2iTxeW7LWSf332hCshHHwD844+f3305/fD6xx99zO2GKsoGz+RWqpuYKct3XrAv5YB1D9ugEYyK2EJEyNmJW6Wkeg5oYp+LHYIKs5QKhGZJTAZSMyUhIM7iW0F6/AOxiM63lHWbEz/YOuBqn8cmaq9P7BR1XSyQLoVZpNqo2JnvLl8bzSBWf0ujvaNlzgeekfTQZJd9Y7COSBOSTfZ5LyHfxZJYskFDUzlVNEPsoVPtrUbUM812ek8/Uz64nuD9DRcWfJD/P3RH3YvMvvPfoxyxtGajD0BGQT7K4Sj9uGP4pDxC0FZjZ2t66TNTRbSXUXauTuYPzuzWObl3e6bLktXsGP4wl/S1pIzbtS6LucwCz7g4r+e2uUpcVh00sOopYTAcVVjGXM+tiHjAfA4JvHbh1iH76ExmWSHalqgOOnFY4aaHoruCW/M36JepK2z6MMn6odiuqUj/Q/Z7zfbYDDXsEM7wYHTdgRvgdKFzljAZLUr0WBq8Q7+lSnSdDk8duhZZPpdYzPj66t2MvPd21H1Qaj+Qr0cNJbj++yX5WoAaqN1acDFX0K7UiRvcUDOI7siHMumsN6yrktKTiA9pnaiM3UbAEs0PMhzdRdX0OMceTDeN36CBcqoyhN2yZBHMCzSPmIBcES3SaF1pGzTjVrtqkE6paUuFD6W7AJGsM6pipZVUdHc57bQvfrD3iSadcKooNOfr6GchgWXcBKqK8HLlSi0hkJWLPxCo5jR6JwxfcSr68XJO9zmL/eCEym0ZWNEzOmgxp4lrjBI//cTS1iKi8l4jvFjlm1/ErVlHf98TMU+Mmqc6at31GnVL+TDP0wTCG06jcwwxB7FiImJSZJc0Rmy0mC/nestMEp1/iPmSy62mWfzYlTptYTZ41BG8LomYM4HJTpjIQWWLXbSA9w7tPLnBIb6hHOOssHyeK2nkPL5LylHf/DJ3Fsf4tDna3eRyNU8xFtsSjh//loh5Rm/nxsQyGzQJ2xPNAeFRyJhAAs0EHuic6zlf8Hlst2iD9l8QiUevDF6jHbsWYp127KzeOu1fEWn/hkj7nxFp/wsi7b/i0DYy53QBGCyloh5fPRPzrOBO+F7sEN7Jknh+gyCXZAVnqyzHkb6tlEn5KnYQUqDMMIQSDV+T+LYRMdc+IBFhB7VKcLRJSxhHm9Q7XeQIvUgTUaVVo6iqRhqresAtAgsx0ljFDIu2U2tQiBeC3QoqpIYE4RBufrOrgvQobH6TuVkDTRHMajLL5wlHsGFbwghOEkdXLXYmvlnUUtYolPNijuDTSBQzLKEcIYFIz+kKRLKLGHVVpy0o3/0J6QID92buyoCiUPblYHBQ+8BaFOqLVb75DccGrecLZv6KUmgs0fO4veJahJWMzqo1yjV3VCFR8bPctLfxR+u1VSMMZu3t/PGNI564E/tQiPtq8vEqyNVoLxkHDB1Gz5cYm8iWMZOzm4QxZAM9Z7kLUpyjsDqWb35Jtck7xfwj0dYqQaHN2RIw1BjtDM0ZpCxawmiTNhM4pySTacFBJxJjtQNxtkLgTTLXW2qi9vyvUe+LII9CWMGKaaNofEvInjaCxKcgx1pqhbbW2lUiV0j81Ufm+yOOQN0ooBmCIOlTgbBg4wnX27Vkeu47zManvqOKohzwdCARNgblje9vH5su04aK6H2OU20WhYrVLLCkCr5XEAbVIjrW+HJ0mZMcm6zr3LCM3+z60EoDYzRXNE1j3wGWxnarlqWDEN4ils0TJWWGUpXIEkZQ01g2xwmODBWPMJY5v4leninX8UuWslznikUmyqlhpogefcaZgHgldvZUddSOOhVdl3wb36zFpa96Ol9yGf05r4gjhPxbnTc617FEETiO1aERoEaPTeByhXJ0xQrlAudSxWZg2aJYYVyzjOkEgy1kGuXAYvSBEGBccaXodKPzcF8AOnbEn6caOxxPbLexNRCUjDLpG0BH10RlfMlIKraa9/TjejDdrQAV/83K574pb3SyUTtT78n6Fq8ohwwhcTP0xInNDALZ2Nwgn3tDUnS4VGv74TxZx8rz75CG25xFdwTkoLKVosJ0au7GoLxFIRz/6fWVyD59anUBjUBYydWc6jxiw4A6aUVjU1VAOYZ8pyBx6+CrjiIRj7/IlnLcEq41ylKlCIjjGzI1gm1Ye9swQjyAhtiBAL7hMYJyouFr/APQV6A1GlUEVUqzFQLj1XlsK5tWCcY9UEkaXZDWKumrihuBsInXYqtOs9DRq2puEhE7UaK3W+xDifoinbGnb1Ym/rHyRON79KqenrHp7vLo1VqLdIESh14ojvAWFhrUPGWxs95R2laUniGMZTCJNjSLbQ3ezJnQhi4RJIMNUwZDDN/kAqF0k5GqEDHNrH1l0Xoqip4WRpIPhSCdoavoEcRmeZ8pZyk5U5AyQ86oSkM1Q+3Kv/fD8Z2zEFdpqEOoI+Oa6BNX3yCRnPSl6lTxEEzgrdzrLOdyB53Ggneu31IW0Yp6Tzxjdg29zcj1O1OwgluS0Xahhb0vVqyKdjMQdJCcadecoRw9bL0roER0kedSGdItPErIdk0NYYbkCpZDR+EBYbn3aULRt/BB66ggECZCZfeButCcCeyO/DWodrQ6Tk2MXIFZgzrZf1+vZdF50QgRsAFVtSMykuRUaSDvwFDXEdzfVVotwbNLudIvZz7t9QdyHlp8PSdm3dOlyBUD/gCh9bGDLcgVmC/MCND9+9w91CiLt3Qtu6tb5Ab3k9VAVbI+YYL14nM9d49QX7vFPl0vDBcM8ZLTQrhev6vC9XEti7j3F3Bv1WsfmRN+Oe5qTlUR7tC/eEDZtxsxj5jTNK3yqhuWfIRb427FkLngGN2oBxjSvnHdletQLfhAx0tXPRexHbirn6vBEAVfC9BmpGj34dHK96+V70UG15bHj+o5dtsiVcWdNs0pY5g8Iucba/zdVWjXv/fOPGbv/7v7G9rBLs5LpuDG7j8bTmuIF8R7zyNsH5cF1UB8uHaFhnRuVbVL4RePg1dUreAr5FL58vW9y0gI1UQDuHZndLxflaJC0+QI7X07Fab90MKJvftDkxTKdUAbA52DypgXN44Fej+kb8zBNozDCgiHDXBCtWYr4Tdu36+//+i7ksyPyL/d+CMnffEonZ4tskKwrwW02yTS/stXw3tYxcTDuqCUEg1L/YVMpBDgYivIlpn1EKMgpCczpJLYFRyUXnRv1cIup+Mn1RPF5YollBOLYED1cSgeF50baqBN4+OtXb7e6X54tXC2rWxFtcZ+4ClnVM/XEl0n8Epcpa65Xir7pkaWK9Zb8PTXAyD+0li07k0LjVgSDlSdnHItrSLeuG/nzllO3oZfnJBTsav+r0PdOF1eC0NoepLILC8MqH42jGLGtxPDU8++a++F67HY2BBm/lG8+stPf7W673ltO8oV+64Xdjin87ges6mGG7oDRf65ssnplwGGA9d/62Pn/+CfebHH3Dj1o/txYPDyXbzt+3bDFDvOCbl6//G1nTso8MYTZy9NmU4U5FQkOytVBvGMt2NBiFuh5+Tju9/JhTA/v3pOLq7OX//X7+TThTC//UKebdc7IoCZNSiSrKUOrdKkUpAY962ffvt//58fvu9dETBrRB7XXg/HU08y2t+ORyOfvnte82t/Fi9KUP1XPH1aoOu86Q7kBxaMm/zA9+FtCaZ77eQzU6agnFyeXvWC/VMKwLNlHXYy/j8p4KR/bS3cb4aFuonczTzdFjzFN3hkH1bUwJY+Qot0d7pn5DRNlbPT+lPeB6d6epMsP9TP+VBfyMXZu5l/lQbdYxnVR/R+NIxKXlINbze5mFkoA9Yvu4YHdoKIsoZ27OE1LCWxue+udVwGUYNL05TZL1O+d9jWevn3v3NHPABWJXQXXIYbft48Ah0o+1hrFLlu6pNGyVVAOJPKVCy5w3RT52BzG8DM7m7Oq4+89n4+TKzKx6Sc1ruhhRfQpzcey4ob0DnNl2otE2ZFTm836sg4xPJlRcUKTirVKZFiyVaFgpQsdo4miNRFDfXzmfzA0gOdpNEBabl30CVCvQMeUfavp3BFNwAoyKSBeYjsjh9nFH9pU6HndO5D8RFI50bhEF8iHIklQrYwx7gOWPVPcoRFpem8tMThieVtDd7O46Q9Wt2Y8AgS7GuzBiXAkI+7HJ6TT+UzdukMYD+TWWkA67wE74cktbJVzxGEiQHVuAQd7OLPCeW8V5jI9190AW5UucC8DSj7BjJhJNHGPeZMkE8XgwwlcQGyaPwqOsu2RGWO0PbNElagY0f0WrIIKS7+RYwdiu7s7QhofWuFOQexit4p0mG2wgeiFDoggXqRh/KaA0aQxIUTLAklb6TaUpV2+3QTcrpywV6KUHvjb10s3QLMFkD0i56Rqybe18ctDeV1V50HQ1zJeBcZ0ZkhEyHO1YUlZMxYthRabPRPccOpOIYff4KBsgwQqZkoOxNsmiz3npSN1WBXToFtvjyxPZWQuCoEm3j14KZ57KkyLCk4VcTViyYliGevb3+/lCu5XPZ3f4dkbtaAvr0NsB/tgP421nC/trgt3NPCrEGYECw+CFsXMSsnTAvo8UMOQ/+kQQ0CloVJ5HFXOgw5DPi6SBLQegCzqzx+WHG0wwJPHC5iRdyVVDvSk5jQwXYM5tTACC2Mlis5B5/OpbDviuVbfcJh9UPSEZSas9rEq0c38G5S4quWupwBziCt5hPsMC15mAmimSl6+CdxyQUQWHSguqaa0FTm9nUxa2CKyK3Yb5lfOENvpZDZQFyt68mhmS9Rf1whwgr3TKSW/0ilqwWg5A3jQE4DsJPOMkwx9opqYv5ODgaMV/N/lHCFwSW4DlELcVehb449CxEz3/0BC+Hj9a5DvkbslRgOCF1IzOyBnskvYE03TBZOukxkliuZsYEIRTg2uNeCLrhLIluSs3FsTGwqtoMIso2wIXWSXgANhFGbyxwAsGf8Ch/27tZe2f19Gzx2+zTLQph2OltsiT51aeDz5BC1fpIU5N7jFQhQLCmn5BbEBfq1QwuYWbuntq+3GwlgT5KfTrRRw87Pck6HlN16tDm9Gp9TEC/8WIjz6lVNKyXcsAy05ete2lOQw6ATKexCtKIQd26EKzz4wG1QE4/WIbW7H+1o/TxtTj/NdbQmp5OnFgzGd82wMzc34z1DmMAMvt3Zvbpzduqoe+cvWpS5qbt3Llot1eMwkDv4eMVAvt3j+PPdWxartcFxtmwaf1RH5SAx79gE/nHU4xhzbp3DWAn1LgWtZaeOnrlTmPU8A7OWj+AloQ1LMvEwwtcGN9zVUlIS1eo04tX5IHmw11ogI+cSyRLyXye//uUv5Nnl+ensB3LOtGFiVTC9htSlwvdi4XIl0esCjXnCXLTs0uMI2+y+OBAxpiSyVXEs/9Puah+C6sY4i3y0ps/3uS6JC/uv8n5rhj+Hqc9nSkVfmfR9pBjlsarTtSbygaas0H4EIhXRLGOcKs+eLNu0dyhx73p/epW755qlx6w0Uo+U/2QPQmlFbNXF3F9yvDyLUzF2151bI2Qa1uy/wUjkPumchWC4gVpaRtpvypQKMzCg47JxSy3Vigr250hUtcA7ClMX+4CVrp+pgeVeMtWbS4pU9eeNHc69Fr7El69d1IhqfguUm3VCFZBcQSozJmhvwl2NPc2oYSCMvjM8ntNjzvaSPupkfelHyJEOrr0631vGlVNlXDGk/VTH2eoRix0FZjOFoy4hBUUNpPNoQWUj58MynzfliJXzbKbkhqVV8bDwPZrnPEiqnYMRiv/YZ60p0/YLOPtJsvRIs6yGDLX+zG5gmr3NQ13k5IZ57/m6LbgPlICrhM6YTcHvK3nCrZOZaj+qZUKveibqZVQnsVJNtJHKc3xLLQND3Wjfu2+d2G993z/7jKUph+NxuXduvKl8rmd7a3zvID5Xtsc4znRnYbRahSGxK72zz0nOqd0y+z5LRUAkapcPWfldKOQR9MkJEXSq0i3fSm3IO5qsmRhQ6VKKxDm+a6/1J+Ei/XMFln1Y+cgXOdMn5DKlOfns/sfLR6kUPu/0H93Hk6zpBqzkxIEq8rUAtSOuBqHOpdBQSlT9yal2vnP3m+Pwy1ADL7GUFSurQAo/fV+XbxhnOaUjQN0foA+hOOpUpK7LE67BrH3Gy9LSjSJGVjcMDy/TRBVC9Oqx+nn18njPsy8jNZBjFyjOg4aJvxGUbJlI5VYTnUPCliyxnzzvyxMMcbLdC2Kn5/HuY27IM1cRFkSyf4ac6/KH2mqRQrh3/BJWNNmRT7pZ+LbywGbtRNro0bV2hCMo7AOvfV3VclBcrpo7ZPZF7Kx4VQegJ/u/kWnq0nm6y9ecNr5APVSd14vXPTN2M+w9aOE3B0z2OHG9Q1MNEb7B9F7yutdu6sNVQLuzOY7BrnIYNPdmH5Dpt6GzQ/0FKe5OfnZpAzFbAg5muLkpp7BkItjqHXNyVf0ymg8UHXToDkoUQ8K2N8C0xL/YjLGy2WLPPdRSGqhNWdmwjaHJOjtyCfz9qG7BSUc7qm8HSpOXBRPxOohFvRt2yi6pEPfx7GFS9bQdty2+jPY+vb+na2cHNe7bdwfqnKryTNk/P99PZbtmnVLqxN4Oq8v64PdJ0zPRe5b4shZS7fA2/F91TsW/31kxpgTSrKJeiud9T5Ndln996ajfMbdHE4k6syrrrY/PavAUzEEYJfNDWEcqi0XHuDDpjIcxrbYNd6QjOIw+u+O49/BMZjkVu+o+umvn2ul7fWUDyj5DcyaWsl8ooPoGO0foDv7R0iJLZFvArYq+/IoVI/Cm4HxH/l5QzpYMUnLu8p69cbAXyhYW80TKG/ZITvcvsCB+/L3+TPmQNB+92uzeHZ4XxoncB7Ywvfuuf6iGCF12gjna2+RPyMdd7qe+txzYxfE7OLx5CpbzqMVkW7AtBm+IUN/rvrK1bTDHMNVVwmUTnbcs5lKV1n7nYv5wObDltVo5kY9TuRY5bh+ikaWwI99puS9hKimRJJEmKDuO3Q+SU9NvmkzEnOqY3v4aYRXS6SNTLhSPuM01qhF3pVJG54WKZQ2p0dSg5nQVT6fck47+PDVJRw1/bJIOpx6BscCtAeFEq/jKiaUf7TRXgt5aQStUJrZE5Yc4Ri5hg+d+dMM68epl+O+zAOFl+I8Q19Rn9qccVH90XpjOI3rP/WTqznNnca21WutMJw0N0axKxcQSlBrwu3bnfZR51QX/O5e+1zx7BJBlXeJlbRt6rpRza0vUK9UzxNGO32vvt7fH7qOLIFb1P/0ndAO0hht+snwN6jj2CCuzh4inZ2eu9eMP5MyN3w8NlDlSsZSBdT4DFZp/QiMKc6Q4L6C6jmsLWdtwO+j3ulYpenSn2Z+HWiXvXxqlf7fJNfuz31rDbpB4ysV/viYCVtIwv4H5muqBDlA6OXZZodpW+sGHmwvarUbrANUJcGmdsbJwepl/0x+QotnqGBkVzfpGVdfDj4ONli03YVoX0YVOR9kFS+FZ6x7mQ3EIQSlUG2hnU+rc87UdnFw75/QYdzpKhERVGTx4kZ9du9DO8ceoxj0PA3l/7jmCcZiFas3nG8wXve1SDYbsXjDp3B49WkQv06ixCLMbCBo1UnGD7/btSuoPkuOtvxDt/HVSkYvr0/98NyMz+06R92Kg+8oeLVIm9SFoP25lP1rHhpI1JDf6ICPyNCaMW4Osr+lcVa+zKhHmwkBDC8I9FxyRckGxTlHIRxByPY6qKsig0uAwG2qKo3X4rKPcUM5SfxB7QLQZ4dGqWo8xQrdiN7DTbbYd6eSXAaSRaa+NyfWcuR60KKTdVmIsSEKfwG1iK1FmvkjFzO6OG5XILEOtEzcRt8cRDEL9KfhbpoC3Nc3YJpYtp2Ku9WM1vLUjex7+Jcy2zNHqRetTjee5ZMcIq+4D7BEQh8CB6tcG3LImaypEp3AGdrmpMKoDMuCzPVLZ5uphCT0Pv1yeXoV372Vr+OpBMVK1bf/Ra7YxfTPfSF5gLcBp2cdZhD43VWfssp1vIZjR5JkHoX9w1TpcYm/ZUbdFnjjQvbPhBRI3uwxYPwlmQrjASTPpYAPKRQosC04SKRLIjVWUr/0eDpRX2G4xua9feKuwly20LdBcKkOkXd+3/3HaF4Lbu+yxz51Uq+MHWLYTDBom1gX1xU56C8X87fX72cWMvKO3GRNp1da7f1vt3I4ehtloojgwrTCNzuzGplWJT/0pi9HDs32W43x5vITNx07CL6eMLnY0jGWBK1+chyq9AcUoQn68TXnkWgHljLP/9nnDVWKOSLuSZOzb7ewlVoV+pOjG0K7aafGVUzfzyb3PiS56QtSpJv+qjZJi9e8LTpMbzrSB9F9fhr89rz5lYglJ/0dLpmBLea8gQxe89htCRUq0JAPHUsGKaaN2VrM/JrPIqVmHYv0VBtLG0AHpjFLHgukToX2+ViJVrQp5JU9WyEGYWkxKFQUslWEC6jeg/4w3kDQD79+4w+9jM0p65I39j/fXtS+270jvOi4Zh5M11euTRCU/t+2tk5fq3zun7uzD2c+vyFuq12Wc+F1Aeo/vEAMgxCqvVMPvZAGmbRZJYUkLbuZuCX4nS8o72dl3wH8n04KD44c5VZqJlV9hu9R6p7lctSvM97Ek0tSkPVvqfGN8nSeAtf+c+lRi15nUMZ5nH07PLz5d/9C/7E1kN4Z1XqBYuDhVGTlNboTcckhXQD7WxxoBhbZQjcdpDEBfwFMUDNfOwFslq7TsL6OQeloZRQL19rQagGSgG1nlw5C6nSb3cDo9XSci6Yn5GAXQ55knkU5LyOFteOBHwaxU36wjQvlbgxmOYOnjmrGwnHsYzSKUI1iyTrh9LCSWtKs1NQFGJ8Z1D2KoQNAkEJalua48kEiRavLCFZ53RXIgJZqJBFwZtGYbuDGcHWsribNcriiXo09eEFid+P/+t+/eyT8Z5/Tlryd/+W4CQMvUO6okibOY/sWoFQwbgdGNKSWxnq066WEEgvKdYYnu8/5GgvLRmZi9f7mRuauLRegZ6LTrEso9UHsKeLCXnK6a4Dzoqe8dFvfyLoVZQxUdQZG/eDIPTJ6jCUYfnSiSFM6n56WfUHEjz11NCiX5JIRojGFfkm8ae7Df75h/SaR9q4E584vTqSM8hky13QsoyD4wfUMuYQOTdk4nFOmV/thqGHo6e+6z9YkdU0DqbBIpGGfdCNXRVoX94iTgWMLFPRlFb/QIApZ2hMgIJETOVQdkprGv4JmLrjGcli6/e6kO7ke9Qz4GmqEiLQThPQ4FityQ0BhzHB8Wy3K0pyoT7sv9/dki4bFrZRRbrUCRnBoDSmjHobydMrkBk1JDfc+HBdXw2y8ERCIbfaynTWDksYyxpFUtqZS89C2qp+JDe8U9sEkPeJGysQXqCdqYCsJSno5BJ7LHGxLtqHk0141BxgGN2usOXxZ37lktY86ONQWSWeOZPXycWfA0TzV+FGaNdrOabUymHSKzzpXsZNZFQvTR19c0MpE8dAkQzDBailLN+s3T4A4UhsZYwdZQg7AWVKRblnai4yOh+o8O+TEkAtK5KjrVPyJhuTo9I18LqqgwTICFZsWJD0Xw3U5G2I0QQQUYMuMuJgjtCyoGRo+zlRZOg8AwEmkEmN6SILHguBHqdXmmokIQTgOY+4imi55wVRLJExLq3l7DtOc4oZx3g1gigTmjnIOaiEMpBmoOSK+eZenBpUvO/FgERPrCh8GWsXZTGXo3e4TEEebOr673+SHT1q23WANBeVg6gw3DQmKTZ2ehWO3ku5akysnsWGrgWZf+MBYQRlEu6JgQ/qDzc+ZHIFenH6cdHzSD/1lPRtMoDESbcD1tYZphxQJaU40kGdXxNEYZxrNcUdNp0BgLjhRLtiqUv+R2HLYoJm3bciUXfxwDVKsJ2xiiTlksJEiNccYAoZkkmnhceejgZph09Zcrc5vL7YhS8jBW1ED38b9Ic6xhXL05J5FAVTk6Z61R7oKDx5yur99WGS8TmdOaas3GRMiHbZwnP+0Q9efpEjxPbenfmOYYStarNdAUFJIT4e3HjzPytjXCMBqeysUfiOxAuKq9gVtO20BXc2U+Gnb0IFRf2JKFUcoC/lNQySLFDBg7swNMDl1zcAqNZb7xYKaF3CSSF9nwojzo4n9+fzEjZ80BRoBkGRVYR/nygpy1BhhFUgi0ML7rq3czB6Y5xggc++654FEstaz5tLaHGkNmGQTrb2YcCZtTsn0lp5IjlRXIJiF0xkskaKW3rhyGZDKdiMoo2s3YjYTry+kbl+i+tzkr0EYxt3JTuKXXP1OmqcpGnMEPAunV7vL1na7y+i8i6nZ+AF/izoXXuDfZv/pT8Lmy2TjYPs+uyFmz8OoIkG6jLRJLEi+E0b5jtFcVJl7GQhiaj1hMHwJqX777NM/JmVGccLnShGotE+9qcd7gewV0e8gbdMSfY2FN2HL47EVCe3bx5joW3pSjH4fzy1k0tAJ9cc+voq1tX5et6Hh9oEokxMtuOd7IcJfLWFhZjn4WLmbRzoIeMT1GQnt9/TYeWvRze319GQvtlqIfWyvRxULbaqOCgRYWZMm4ARUDdF4gSTGzT63WnMMY1B22g4cB8cpNrRXJZDuCYoYllCPKevtdLQcjVk0Uqyl6RKetAYll4Giv2MQQ6kTxxhefCqrx+LUHbeC1zKD+vQlwNoBmUvz8epIVMaXQrUkWCcO5o03EpCiPlBqqqBjJS3sgFkOJo+/sCApyqcyEm5V2iyfEQzRlWVKh7whAOzT85dxKwFMjztJuLwYSaR3uc2N8XgSTord1STREYRDSGmUE1gY3nOMcXGzQ9DCOFDZMmL6yPpEQvT11YyRALoQBtaTJ1IC8FDZ4RqWwUNPsJOk6yeeZ7gsRjgHl7dmMvJuaPp7a7UK7YVUNLlZu1hREaHlZWksd5NTGKKNYuFypMW58eLD3OdM3VoBeMbEiahpf5jncGtUut0Ei7djljDjyvVWEhkHJZKCvdjRUSyZWoHLFhLHDFa6pcWvQEXwZZSIxiru46p7CRCSSoH/x5jqM5kK4SXOsiQBHuVRcfBP5VQUPM0a3A6412AR4CMG6DlWIG54SVb0Hg/cG1jFNlHIrVKXHCPmQBXR7B2LlqroP2IHy0yT+MnZGugOdt36w9BZnDQOqYGOZpFDVYOHlXDdxTVwwJF/ZuWt8Zo+WszmlTPswRJfQ0mxmP4LNzNG8tIfKP/ZXZqkkVmpLLy7SGG8MHGqgQh3b5DCFVJsjaEJ7YOm9tSIHEFP76ICb+LJrs6QZ6ymnGR3X+2vSGmoM1Xrb21wdAdfbL6Q11F24uu0Y8ICpaTZ0xzPA6A2esaSHZWifOjQJntR4D3nrmE19lozUR9vM99f32sy7TG8Pki1qsCab4bTBy0CrA7q+niTsaKOPdxG1XJotVd1OLGP4CmF1GCtWoqrGNZh+xJB8Bel07VibosDa20+f9p2e6mAvZtNje1M0dM5U9mnKiQOaS55g+eBen87eX4ayFq24rnFEeCJFA9I0YQJ8W0ecJfqyBtdQY1//gzBdDgkpkYoIOWXZqt6TSOu272051YoPueypSB3nYFnS+8LiXCbOtTsxFwJ03tMKj0RaqOtZK1t0EiCXtLSUCimBxKL62BliGNAGNVT108d35PWmDFadAOd25CA9CMk7yjh5fZusqVhBqHx9fnVNFOhcCg2ECr0FRTRMjGyAQOubgZu7wmi67AiLdPzCMC56qTvWGDyGpfm6+Py/FVSlrqy7YimE8VylGm1oNqEezJJmep7TolMGnMThdFVt8FNB+U4zXy3qHRV05cprVXUOZg0MI3j/xHP8OLAO6J+gyGXwAH2Y5CtYJgYyjVVvr56M8Tr0iiDX11eTcKHJaXVUk8Q1VwoeB8vVx1ko/tcaZQQMB28xxUH00ZejNaCqbhihPMXOFx9a+pYVE199+6011Wu0yjVvwgCTNRQ/ubESGhH8i279ppv0sB0Ae0zTzrv9KqKF5XJGVMFhom3Fw0G0d+5XZ5pq4pp0rOwbZiUAHFCnwjCd08zJkM2mKGO4tlSlkC6xTJ0+Cyvo2vvxJkD7mmK9MX8/n/KeKJoB3hGq8vq744xAAkiZvunr2FgH9jBBRgG4uJMOmRFcEkkdemMFZ6gfoWlo5puEF3rsxXtgyKurcrZhyhSUkzBW6LM5AaGmG1Apw6rj/eb6lLQHGAaz9UbYvu6kkfB8gQXJlbzdBXvvRC6+oga2dFirODSk4m+eLmF5nS+R2WwmX5eilQ+UnYBR1fs5tBE+TIeETKrd5ELPrtcHVoUN1zTC9/uYIg6s6YtcseFalw/C8vaUzBRzjaenIJkjNkF5ezq1HOmazvEc6m9PyYdJ3vM1Fale0xu0wjCX5G1niBE0WOWqXNMxJwIRuSSp3AouaTpZA1kvUjFXQDWWkfYtUGUWQI3DRlpDDeNiqzViJs7bkjxZ0oViCdFFltEpyshaYgX8vJXaTHstGMX00mx+I2yC0MqSLE/qJRriAqk5sGauv7J3bF2cvZtNb9hlMaIV8/SCUf4gcHhCt6tuvcsdV7gnrrK3NZJEeQVmK9UNMYoulyzpG28Ym5jrnOGs2MXs+vUZYWIhC5GS69nFFDiJQ69BMcoFkhRwEUYhfpjJsnfZPxULVTB1vXt3PR2LfZXG0wYfbMsph/J9o/i0tMFaED5mEMHFfpjJJjkmsLpWlSeeuR4rk3iDL7WOZUF5r9iKCepqIIRIYTew7ypeGZYq58gUwO1g0KiAPwB3ASD3iDnFSwI6CMyGcpZmFMn+bF+hd6dnlfLpwofDoOT9pyksNn6eQblOU3IMGOITvccx0bQ6PFoENP/pf7yPYNBAVTKhiuoNw6o052reNcgPguBUjCTLHO4+vDy9sq+8zJhY7SUWQRY7AxMsFZwKWQxz74fhkoXxssoBuIBieYddoFeT/jAMloDQMOcMrTPjO3rLsiKr1V6oeTi9NcyK7pceyRTIY1AfVuIx2FhD5scH8BICuWwMOYJMIDEqdw8b5EdAjBQIjNl2dgIUmdARMfPAx+PSUrUs23X6JLPZ7LxWSnEKKqRc5Eu5mq7jOfkKB0coXTQlm5DLLaKN54237HQGGYSDJgU5lpjRZLpjJ6PcKgrzlHba/ZNIzMbe6TAMpKQx0N2w0EpF9MC6X8GVjIoCSb5+Z0nTxBRqsl8no9qASrVBO1vv3Aj10xU401pq4+XtrOCG5RyICJaXSkGYdBItfa0SVB3Bj9JQFWqzcF2+1lQ/cCaQsiLDZzh+nKmx5RkM+5MfhCb41Ar7IIQkTedgY3pa3+wM9DpDs+9WMQF2mImlfsPrhlgf2XMfP8xEnQyzSo0rljs1tD1bZQYta8K1NK4kaJ/+IhX7E9KyfPySS9cR1DJgFwdqfLjHlJOGdsq8gWvi6ZIpWoe72dnFi/Pr6/YYI1gEM1K9wItTeAuUmzV55weaWNanhIV3AVuwpoXiZzlWFZuKS72bXf/nBCB6hdj4MtQZIrOyEPnVRD9AZpCqPr6jtz6DI2OuACX5JJghn6fF4+Gd7WmHWWDFuLr2XvdoOCgAswlR6DpyBWZKNIuA7Ryzr/sVbMuwIxns+63clFFozVDP6MhaBpiJ5wi2qF2RLLDQEGnyjfeYMPsQBVSTexEJ2GouseqqwpZcc2nusT63xh5DJGHJW6oMqA3lNZNVZWy0w9dk8ZMJgJeIUu+V3LfXnPjkCsmw7MeuJ9FVg/4gDMlTVHZV+SOvJ0YmWkCITKrC0+JU04wRkqeonKpC1x7lDkSYfKrCVDKrqSxC8hSPYe3P1X24loWEZLR9z1Nyfb/oEsnTba4kkq3NAvoCC/LGp57MlJwWzyjFlmFljJ6SJacrl/MlUt8glPnAr9MZYTqMPTk9XuagUAs8vc/Blxf3TWamRDdaTKiNJ/eYpjedxKxns8dz7U1kE1kpbjmbDqrJ5VBkYfAi5N4XZlpcnCwMXpiLRXGPEJecag0pvtnXjzPV7Gu/vcXS+pxGlXr1yg0kVXq/MrN4fXpn1KyJXBIuZe57ldW65fmwk6RQzOxCZPYErICV7fvl9IrI3LCM/RnaCsMUfmW/NRdWqMaB9Xl25cYgQt6nL36+phpeIeY+OVxukIlcNF9L1JCFWYP+MAws4XOmZAJ6moKcS86SHZ6SN3P0J6p3uZSINXXtzkjJpx4SOdIF/0HbcylXpMi5pCkBpaQi0/Lg7LcWMBY/8bC46rA6LrEg+FyMJM0RR8HBSDweBjSYEqCXK7kAROv4JRM3ld9gZgerDOWTwCV1W21UZJ8+XJZqTHucuwAZNnIHo7AmO8L92qXkLVWsDethXMoTn2h6DVDmG6z400PswQEUYipmuUg+SfVeqBDflwBq2gPz1Y64GQvPe1AI6tU1+VqANmU/1ak1Ir4WVOmbkZDzBy3R3wuqqDBMALGDELjNORUTpbevhTQUbhOAFKuL8MXSj+JCbRYAgnTGG4eX0eESLYeHOpcRvB4b5VxuISUv6oZ1tnSM7MWC6vIjFwjtPvDB0f6ziRPBuyZ/d5OYFlrioBR6ZLsPX1SPo9AHrKT76Ie74SuaMrlAa0P/wZIni0ld6B0ULCnfA5ki4wcYCZcaRrKIo6AhlvV502QYz/2vkqvC/nEyWN+OCyuJsAftds2SNSmHvTdorF5uVSiIB2MHmvqqKLodjeN94DXY+ijZ+4HBijio4Ey6D8kmTYGjLQ0kwDaQBg7WHGkYFGIxhFMOykyugaACfpyrd+3r09zArioQ2h3xTmzIRTrHQN6naKfCkplClG3NuGqfTDVtCZegFOUFVmfXWuvgvrFGgGVyrG3XwWmXliyZzWb3Kknu0WxNPqoMP5BROGQu8sC+SIUmtFEumTTGHoFqdWjMhFFneZkmPSr4ionE6VfTodhvY5qe31/MymEm2hUV6IIjhQBWlvD2KMNo0ComWSwzh+XVxMZDSuthB+LDxL0G6+ZEGwVi5VLCnUN9SmcYpbWc3wCSz/zD6fnFp2tyff2eUOObXE2X8woOiIJewWFimpYFgnj3LZBpF18nVAgsAWaf0XvthyHv3l1PeFAsqNG35HCtugQy7bnQicTao1oh8fdlIfHrxnDDqIL/9ShqVGewEVhCM8M2aMiu9wM4g3jV+rTWD3UaTKzqKFenZw7l5HwNDcIg6lfXdnXupVtp+IoF5WsBIoHJ0Wu+lBLSGa/CBnTV+qk+2B2gRspIPVSXuk983x19sR6mB5+X5VHf/P38ikg1qRaLBpdlMker6ObpTzJdBCxYNsUvp+f3hGOKHKmDQonj2o4xsXOChg3gPSLXberDONY0B5Uqmatkk1pehSzYBnaoZJ67/wsI7oPUcm08pHWmfSjKHBTL7a/xYJ5X2CzSHCyHOBAontb5MdTd8YO5kckzj3WCf8T/yp7L4yL03v5wXoNPZypaezaPj9aOej+kTKx8QBUWg25B9YNNY9VO9UV6NprS9ensoj3cCKw/MR4P3xPBEr9HdSq8xAuXbzFZAsKqkNOMcL1vWU8t7nIgPgzdVVnOtu46lPd0xGlxp+MwHsoHuQy1yECvc6oAqzn5HqsrdtEaahgYbqHbSYH8WiV4TdtDBeV7xPJrleD2a29Dmmgx1SpBzeQJsCZ3adcqwew1HuBM7TGuVYLbYzzgWVOVhubB05qMB2CIiTxdZBPzeNxJR+wy3jnokxuMa5XgSYAB1jQPjlYJZvPugGVq326LBq1vd8AyrWW3RXKUY33/bt1aJXgNsAOqT5PaFmqNeYyvz6aeYbQj8x9UQ9WJ8xrMNOVEc9osZBkV0/X1JTmdWChTaz5ewfOBNtpzh6Y5xBiYO6IioqBpjTEMx1DEhMa9Y83VqJBCv/RFvqaobmasW1sEsXVioXptKFrBwn/5y6uTn27LxWmUDR3Dg3V4TtOMiVAxvznMKBqsmhlTS2VowwxWC+3Twsiyy4IbhhjFViuYFJeli8UfgNWvLthDWkOMYcGsS3fWyL69LhYv3rnRpvoXi0VbbIwK7/Rz3xBjcPCiHi7lqjPACBKds4TJkTsWK/ShGmlq9MPW3gfERLyqPF0I17xX3rneiQS1os/HNbhByipkrkCuqSrQTkSId8wqfC5t6QB0ukAMlAzVKFpDDKJBfINNq7GIXJaVCI0B9ZywJRFSwHP7RVG65yYsoFkroIghnF8uzq/DIBNjqPB209UpC5ZJ2EyySWIxDf8sGjm1z7uRyG1v01r/uUN73xppsBw9Hy1pkrng84lAQsQCJp7as+QHm/AeGUUTQA/pSDjVaz/WJD3YKCpShtW+/Or0oxtBc1qlqE7DhFYnzZWadiN4/X/yKoU5oDWkvLqu2s87dPwe6JzIf2QNYwquAhIuDEJnqzeMw365CiiLc0+JrjKFEMCxzpdX3v0Y03bPw4m/Rk0kkxcGTyRoAJrICtDABP1vGowCyUHpLRqtFJxPF1NRuer0hQaF2cnxk6jhK4ttTW3pWIy1dHxYXQ+5tTiKPOe75jDDYBT3LIOlw+n7D2up/uGy5EpTrn4FiDOsIIcaosYgY5hQT9Mez+QzpBB5Ug3PxEs3VqYgkq3jk3bNEicIlRbNfCnVuKL+IFj7nl9VWeeJK2UyVBdLGVwU5LgcVOiltNiRTx/fTQKoAK1F6RKUC9Q3chqaDUUSwsviPlNihDY0x2tSsgcysVMJrubb1nan9IIvEc0zaKjGUYF9bgFrjXU3OEQfTBvbRD/MkypchRmHfBggF8aDlh7/ueACFF0wbtmlTqgII0503aNGWHyeGlGxwapWVW7ZFBVpwxSWwf6zJT11R+x3sTRYD+TinDwrBPtagB+NuM78bMlATQj530iWzxF9Ly4NPp9c9nCTY53e2VX9a5OQeAUYB8/FTENCPueCfPRq9kQGlAtcT49z8gQLvF2z1hoMA1PD8tnDDvmHN5PN25uCiwSriVKTOZ9RA6tJpm4LCo0DNDBN0WQtGsRHtYFnIovcopn4Pn+5nLYoW/61oBwtO9DiaA8wBgY1hMGCmRzAsNnmG07xzu+XGfl8eXo1aZe2SA31vzysof6WCpkbmueILtrTK/K+XvX9NM95VQhoko6/xWr7/8W3/V/JA1cP6M0WcrZBWjmgN+QL5ORCMMP8gn12/efuhnZLC7NGLJr7X6eFWd+rZO5taUbGBPRJw9RqDrdoyeZl1uB/9XKG7n+UiEIX5pMqi+Ck9djJDaitYiZ4vf6pDbu7gCksacHN3MUB/E6WlDf6jI3Mxi5iKUt12kOT7RoUeCtduDVVkVvpIswgPenMT2l6j8m0D+8dU3F/1r/X/lIO61C3c0SHRx8av2+I/SCZbrOgsRHGT3xjVz6umXYF+5j29WWNJAnNTRHWX9HtvsXymhqSyAy0nbTLMeyc0Eu5IueQyLR1vKuJeFqdy3HodEq6LiKmr9P9QwkHwMirH5ZcuzVPpDAgjAuTYkIbKkwJQ/di7Ak6mgIw7RrYuuiYx+Qqz1MTkjdpWVGDrJnRhJIrMF+YEZYthd0/6RyNarJ6LQueEgEbUGQB1bnLqdJA3oGhvijpUsmsNtSzS7nSL2c0uQGjf+iQP2cKEsN3z4kJuCn5AJ5Z+BMuajBPeheSw6aj1E5ZyR4RobGS55Ar8J5HiySFJROQEim4g2XoggPJaN6PKtOrbshNzBMY9rhsWXxx/pMvouZvfGUz8d+CW5oYwuXK71f3FXOzY06c8KfFfc9uR06VYUnBqXK/Dxt7MngyOqQPOil9J6NDefikDG7J5rh78ur/7sn4nvQU84u0IQ+7vnLxx7w38/HJoOu2dngS0BT0OvGfBDa7bFj3/2HInDMr65ZHeBLgaJEyM0847bTveRLwoKcowJMAtk66Du0nAYyJw4DhSkwl53i6Jy0Fegj3wF22JUAaU4cakGv69MzaF0uzgEXTkUM6QsLDtIiWHNKhfocWMbyKPX6EI6yiqFlVepfPL1dnmpGWj/Ss4L2XLzmGWB2cwnt3cDX/8KddU6k9kyKxjwM18qlrtgPsZsNw2WF9dc/sMFWv0/JAXsoVeb0BYcrSD4VIQVkVREFgVJ2pL9ktpESDsUQaP26OoYcVlnITOrQfrLBUm9Ahfa9N6TOjx7YvHXYwO/O6x5rcbw3WshM7jHAu30pt6iySt0+kBpE6X43/UPcdm5oN6dtZ307Y0ZTV7fxocGEvZptf6smdvde9vbid2Rv5rS7u5jfs5f3tf+7y9viOEXhDmy94Q1rdWpYSSlZsA6Iykn27goBdosPsF7gaSPoUhb9vw6MxaNCQ+W6uOqX8Y+x13XnoNtjNe7Fzq/zaD01m7iI9D9ZsQ13PWZLQLgdZAAFm1qDIpwthfvqNSEXecEnNz6+I73AZ+g4m9UIod8z7EHH3G563c4PiKZ8R7AtJOzowKsAx7bgc+Zs3MEi1pSpFE+pqHK027fpKXsw+N+Q9ShRw2o0Q1L4CiX9EA+xQ8tedVO0Xz/6/VGzFXJcp/5umtHLHOmDJXyOBERezz7/1LEGA31mJhy9Bhai7yjFen/1B7QqOh74+a6ApqKP4rt+6ocjF+UO8pB5v3VnqyBzmK33SRjaezNHtbLQUtC72gpa7KFZ1OZOcu1jDb5EB29V7hJgbe+aYJolfOkgt0oageim7garDC/0ENb4sWTwVUTWT2gW7ZdLH63ZmX/avZJpoluV8F/bJftklGQNN1kSzFMizvxCzVgV59euvP5At1UQDiGqUkZV4EsLrhJXQuRQa8JYi+WZOhSv0WtkUqmR4e5V1LwXyjC7kBmqLwURvZGXJ3rRRQLPB+5N8M8fmkZcKUla05bQYC/Vdn+RYGRbYkjDzj+LVX376q/Ys/WXuGGgJ+h+d2fzD6oOXdAeKvCKvRUJzXYRSVFalvBdf76P+QOdHT2xl3yg/vyL/Zqf7nPz8M/k3kkhl5WVfkskP+pz8L27+t/0i06S5KN/1bqGQKTxZXVdsYZ5Qzhc0ucGVgD04IY27NtR4vcIuIog0l0wYp5q0m7uUQN3hmINSnX4P0eVBnUPCKHeIHVJtpLKStdh5qcN+sKGcpf5g9IEiZCkLkdoXhoMDz8QqCEd3Bi82b0SHcgxfYLgOI26jgV3YcUnTp/LOBTi+FVQGRrGkR+sIqnD9y04X9s99yYTts0/NXqKVy3LbTshbubVb09U5mSBSWWXMSHIDkN+xaE/ixftGFk3JBLSeb1g6T7G8rq9LzrMCAYoad8ld2a2aXljWLrk4b9reRY+Jg2XMqt3OV+4Ww88iXPWLc6Ist9bOoOIWjaoVmOprd66EVkhBT4++Ej4SbnwlFIorqMv4L85L2+sH1zthX/FTgXtoF7shRmn/KR0x34Djpex+q3PeKR73Pya4Q7OO2P8kZLOe7okxz7u7dfYNCGe9PHWl1hKekP8eHkbPXpas0/TgCD56O6pVjmZnp7Mg+yZU2OVhWS5VXztDl7j4bYVBFE/D/PHJP1VOEe9vZ9NR5Yv9T/YKu5dznGZ+Ql79+hvZunXPgApCOe+3FTijvhOT9vYjsgUFniw1hAPVhkjRShdpLuKji4nf9iL23FUMt21Yuy9SpW7hXFQTJGshuVzt2o64JVM9dUd/JcmaKpoYv4j2Uu8cfmc0F6QQIaaHN2zmgxm1sRO6vaMe04kw4rt0GkVmhUwpSjeCottBnuY4a0uspImTWL2PQgSbg0ySQpUUtaEipSolQqqMcvZnX3yvVFnv+qQhyuHgJZLFovMk3WuR9qgrMC85W4KbcY+CryGRIh0QsPfbPdcG084yMiFXxyXnYHoPwKARlToB3ijWYoO1fDNlHukgX9uxe4/z0FFunszB45dJYdrdrh5aSSDtBEg8uOiBSB9p4V+LFGPZLck/pcCutjDCFu3opYjpw2s/tle4w6LQbvQpMXBrwuUrK1iW6NKxOLCe/X3oYdsBjTXNfZpeIlUKKd47GIJswjOlqxFLGaOMtKm+WPevd18rJbMTR7VwSfk6AUEVk16szwpu2AvDQBFaq0G1r2WTUUFXfam5hHDn3in1RQ/KY9WEme81kVvhPWOGZnnbMhgQu+rWSnaDj5jRJFkzq93IFPQJeVdo49SkOlHf+GsgLpcaOHCTRhnYcmlxb+AYkpDb5HJAv3aqLHDtDgS1onXKNiy1kk2zx1K1lJaRXZeM7GNr8foneZszdbQZ7vfT+4Ju7Ulkhu/8ZLVlelZes6DcAR23jUbc9EETznPLjSt+dtIZsgonk0VsDpR1BLmHUqzWP/ZVcRLk1wKKox0l13HMnaI9f9xSTRyIdODcOHA/xV7UiEJBY0EReNoqMwiv7yrDwJrPEaDmcwzpOY/JippEX0WniiAr1V6Rx1EhW+pj7xvTeS7v9eYcyjbv4muHOAv2D0SrGkJsQ1Bvd5GHC9a64NhupwEtShYmkRm89Bgq5cVFZctuIWwqyt4ndQVy4IDABlS3EvGRJlaOHpIAa56dMZMPbvJip3agf6WrTBdXspxq74Bdsr3i0y/demfOUE2VICvjRzP1bEBlYmTpPmGiNFGlwcnSi7u/8QPaJnxuaul1TVAq8v46hMYyXQYEtO1qbvxyh4ayJHUuNYvIOCadLadOi9RXmHKh/OXdHazCU3AzxytddE9WJIoMFEvuy4t653aELLaRidUz2aqb4dmSv9+dqYVeKexuviUXfzxC9ZrStSu73fzrwPBzwTvLHZo+jADznB6zVt133QsZsv7rDaGdNFbGFgtpCCXrUPGiP4CWy9W8DFR5FKZeHsR7M/Vj1Exp8L59KXLPPvoFf8lZssO+PSN8YeYAhOLagu8G+HLBMeOm+xfwQ8GhWTq9DsmVPL7FllgrQBfC2+v29VBpmmr7L/eoUl4C6isAc8fjnKypWMFcwBabFww5LmFbc/U7IcQYxRaFgRqH6Mboaw/dSuv156+fdeicRmN21cq59sfHvzlOEWzHF4VezDX5rUe5dRlgdsHKgoN6H/OlNqBOyDX4TSk0qBO6AlfKO0S6L6UqMXRol2S83J74hrX+97W6FVKRhZJb7Rr/+b8mZZtrq3YN1pO+SGdUmdhmuopwbItKuFOykx16rDsleVqJjVhXSuYQHIpYb/GpIJSDMlV0kdoPGv7m3VuBfdSKALggpB6BOSVCihcKcnCazFj0Q19DR9w6+oVS9sJU+orbSSfHvWTew1a6fzoz2zKzDsKy5/Xk3A24cNkmgkjxwrd1GXkJnJAy7xEcEedNa87Alw6ABSmXxHIHw0CfkOs9T2k3NqhnVuEgPvPpfIW2SoxPGfXBNmlgv2Hhadmc0x/IoR6q7idM250MOdHBvmEFX/fpsAh0dOmn1aqNdMsy4Qll39+leFmU5w4FoVrLhDl7qd2NXn3Sbdglu4HfCSX5eqdZQjlJmb55TnLleqI8J2CS7/sFZaroIbmX93zofZ6NohkYUJrkVLsqXtoVcvC1CBKZZZaLyYbTvptaAyYZFff8e/BYEl9tDxEeJs++E5nlRfcOImwbJVsmUrkN8bSJFAnk5nkVSTG4GJ1pLgvOd769nDN+pr6hrecaojYQlwNPV93qGUtcGpm6FQkvmbiBNOQClYHoVDvrVFBQ7CffVdBOWDq2cbxTFQKV1dU7O3mzRBtACe/99WPhep8Hyyu57pbrqZzOoDLWbuyEbWINYzq0/vyPS9o/R5a0l4zj3/Fqym/caNU1VpAWCZDScwT95jYNilE+73lN0R6RazdkKTa338faA2hfmEG7ACQ3+qCSAzEsxmF0+9CtqV5XN9SKhT1ZhkWy9pG/ZY5NlWZ4VlJqlQizE6mGOdEqsb+q/r+baUosPxeEuZi7QiQcqLJ/coXw9tBCAmGwdqoysfNu74Nnfj0dAZ/0i5XIbMFEVTe7/mCFtFF1j9fLNb0+tqWvLo10W403LH7HcZD2XIkzP7qvyThsKfUaHLppvFo+b2W+OCdXntM8C4UbiO+2F5J+LbYf+uVqb4B+DFt+zfx8ce6WNKS8VWyiaz1oeuR8GKCfwok/RJYXbJnuV1I3eodZy77p1Q0J2l5cGLVjC698H/HU2KU/qwaudwUlA5JsLPvcHZKsBfZKpHuJ9oSc+fzMUO+U+w/GpVkHUDW/8dN3wRy3KEyVuSlN9RgVwrVIdQYf/6BsJdlQxeiCd7IAfVEGJkjO6QAj0CA0an2UxobWRVU/8onlVFbCKPMLmd3n65cXs7YMTULJWG9RGMrLPrCh4ORcyL2nxYMkF8KQa7YS1DGLgSOaS4VZvPb7Dv+yh3RWym7SVXV0/2mB1O6yO2Wp7Dk4V+8/EiYSXqRg2VloZGt/fkKevb6lWc7hdzLzBhFP1nHvk367iPPMHd236YxT+6elHxnTN1bkPgDXPVLxambMq/A0fGD6ZsTlahRbrUDhtbDrX7LPdV9AwOCk07UCvZY8tafH6+oDnUYbrvcjWBa6vvfAlZ998DLGD1Uxjovz/jSSyd75RGb5/MhxV25XQuyVa+Pq7Xu6WLywcKRw+alL125GpkUypKUFsfSRosbqyCtuKZWrPGD5eolvoEscVemWqseJ0OtW1bfclYaHyE5ioDTyM8tEKXlHk7Kecr9wa1nQUfUYKV6UAqoa50Je14ze1FoB1dFjg7WhpoglOFf2KMr4o6kddvCFvCUsfTn8ftmXtTgGQovoU6fwsb8LFkX/1S3fMeTue51Dft7tu3fIc8aELGL5OGt5JHoV/U5ZThrT6NCxyP4SmTB2ZcbGkTjl3PI9ooskAa2XBSev7fgkkSloeyTKYr/9mgUTKdxGXgDOtDlM8nwgb3EDO1VMlSAWoJx/M6OKcRfB02PB8/53sSLULeIL+9vemQmEcygXvrjQI0nEYXTyrIrnzEHpPCTdeg7TWbIgIuwD4ssKTz8MJBl6M1f3PcYOKPHCVxXkFWxV/tv2Q8qEJikYyniPkWEhC1P73cDUJD96bGZpsaVVHJvDMfyQGshyjhbNc0pSWNLgAgqVL0sffojWtFLxBhSnO5fIZWR4XMmznhtpP3Bad/g1LMsscG+r14aZwhVmJL0T2+sG3YJND72uUb1YNftOQmMjReBVicwye59wjtGZp05YLdg3V3LDUm8/K6vIZaAHA6FSmRzuaLy/tewN43upManH5fWLBre5C3p6HF5fjo7L6/+QiwPtTgdP7//IRXDA9N+unOEVzj13AcV+569nF+SiI1DVYaBVrQ3ZJeMIIiZ2Vdmwq6iK9H3sYSG2ul+49yxivpApdsZXJ+OuLXQELMRiGRCP1vGrJXiXwREyz2sm4JA67ANoK38IW7G0cuUMGPGy2FpjJw08wssfT8ir5p0XmM9U2d179slXzykdUS5Y4xaSom5F8KFfC+hLby2rMI0FbhzBENJrFU+bBpEqu5JuKOO068gglSmcuPzKJSg10GnB36FDbP3x/G5BWclCASjvgO1MKYQbaLY6GeCILJsvijTdRbfPsGweNQ+oRrfQcFih81ErVXyKismIVQ5aKXZzXRwjIYHpevSqr7lKi5SZKrNuXxctIOprbLfP2PCsZO9eGJ+kjxKLvYKbo2nlZ59fk2chV+Jzwa2svGDcJXC4OLDXt7nU9ps/kBddQ4Noe2FuhNyKhiKkISlcMYtNk/pAp82EHsEE1w4LPSuz3K9CatIlrGiyI58G1TXOFoo+RlJ+GLixxEyQjDKxVDSD0XCMnCrXtRe/TkJDuJy5YcmVTH1w9L4sYC3qrAcUuUP6cqECdiGwNKRm3bgr2JK3hXCq5DuZAifPmNic/PicMJk8Jwv7L7D/ooLynWb65Md+/6JJ8vmS007n/NgyVFPCP5sRN6izdTk+uSubX8nlaKEGI1GR+r8uAs6yDIIGZQ9yL6BNFpfvtpB9fveFKiAffQDwjz9+fvfl9MPrH3/0MbcbqigbPJNbqW5ipizfecG+lAPWPWyDRjAqYgsRIWcnbpWS6jmgiX0udggqzFIqEJolMRlIzZSEgDiLbwXp8Q/EIjrfUtZtTvxg64CrfR6bqL0+sVPUdbFAuhRmkWqjYme+u3xtNINY/S2N9o6WOR94RtJDk132jcE6Ik1INtnnvYR8F0tiyQYNTeVU0Qyxh061txpRzzTb6T39TPngeoL3N1xY8EH+/9AddS8y+85/j3LE0pqNPgAZBfkoh6P0447hk/IIQVuNna3ppc9MFdFeRtm5Opk/OLNb5+Te7ZkuS1azY/jDXNLXkjJu17os5jILPOPivJ7b5ipxWXXQwKqnhMFwVGEZcz23IuIB8zkk8NqFW4fsozOZZYVoW6I66MRhhZseiu4Kbs3foF+mrrDpwyTrh2K7piL9D9nvNdtjM9SwQzjDg9F1B26A04XOWcJktCjRY2nwDv2WKtF1Ojx16Fpk+VxiMePrq3cz8t7bUfdBqf1Avh41lOD675fkawFqoHZrwcVcQbtSJ25wQ80guiMfyqSz3rCuSkpPIj6kdaIydhsBSzQ/yHB0F1XT4xx7MN00foMGyqnKEHbLkkUwL9A8YgJyRbRIo3WlbdCMW+2qQTqlpi0VPpTuAkSyzqiKlVZS0d3ltNO++MHeJ5p0wqmi0Jyvo5+FBJZxE6gqwsuVK7WEQFYu/kCgmtPonTB8xanox8s53ecs9oMTKrdlYEXP6KDFnCauMUr89BNLW4uIynuN8GKVb34Rt2Yd/X1PxDwxap7qqHXXa9Qt5cM8TxMIbziNzjHEHMSKiYhJkV3SGLHRYr6c6y0zSXT+IeZLLreaZvFjV+q0hdngUUfwuiRizgQmO2EiB5UtdtEC3ju08+QGh/iGcoyzwvJ5rqSR8/guKUd988vcWRzj0+Zod5PL1TzFWGxLOH78WyLmGb2dGxPLbNAkbE80B4RHIWMCCTQTeKBzrud8weex3aIN2n9BJB69MniNduxaiHXasbN667R/RaT9GyLtf0ak/S+ItP+KQ9vInNMFYLCUinp89UzMs4I74XuxQ3gnS+L5DYJckhWcrbIcR/q2Uiblq9hBSIEywxBKNHxN4ttGxFz7gESEHdQqwdEmLWEcbVLvdJEj9CJNRJVWjaKqGmms6gG3CCzESGMVMyzaTq1BIV4IdiuokBoShEO4+c2uCtKjsPlN5mYNNEUwq8ksnyccwYZtCSM4SRxdtdiZ+GZRS1mjUM6LOYJPI1HMsIRyhAQiPacrEMkuYtRVnbagfPcnpAsM3Ju5KwOKQtmXg8FB7QNrUagvVvnmNxwbtJ4vmPkrSqGxRM/j9oprEVYyOqvWKNfcUYVExc9y097GH63XVo0wmLW388c3jnjiTuxDIe6rycerIFejvWQcMHQYPV9ibCJbxkzObhLGkA30nOUuSHGOwupYvvkl1SbvFPOPRFurBIU2Z0vAUGO0MzRnkLJoCaNN2kzgnJJMpgUHnUiM1Q7E2QqBN8lcb6mJ2vO/Rr0vgjwKYQUrpo2i8S0he9oIEp+CHGupFdpaa1eJXCHxVx+Z7484AnWjgGYIgqRPBcKCjSdcb9eS6bnvMBuf+o4qinLA04FE2BiUN76/fWy6TBsqovc5TrVZFCpWs8CSKvheQRhUi+hY48vRZU5ybLKuc8MyfrPrQysNjNFc0TSNfQdYGtutWpYOQniLWDZPlJQZSlUiSxhBTWPZHCc4MlQ8wljm/CZ6eaZcxy9ZynKdKxaZKKeGmSJ69BlnAuKV2NlT1VE76lR0XfJtfLMWl77q6XzJ5f/P3tc9uXEjeb7fX4H1w0ma0FC27PHe+Lyz0dvdHvdNS+5VS/bExkRUgFVgESMUUAJQZNN//QUSqG8UyWYDRWnv5mHCapKJxFciP38Z/DlviEdI+Tc2b3CpY4hGkDjGho7AavDcBCbyKEeX51EucClkaAFWLKs8xjUrqEpjiIVCRTmwMfpAcKIBXCk43eAy3AJAh874s1RDp+Px7Ta0BRKlokzYBtDBLVERXjMSkuaJpx/Xk+luOZHh36wysU15g5MN2pm6JWtbvEY5ZBEKN11PnNDCwJENLQ3KxDqSgrOLlTIfJuk6VJ3/iDR5KGnwQEBJZJFLzPUIczcE5W0UwuGfXotE9uHDoAtoAMJS5AlWZcCGAV3SEoemKglmMfQ7SVJYB4s6Gol4+EU2lMNCuHYoC5lF4Di8I1NF8A0r6xuOkA+gSOhEANvwOIJxosin8AfAB9AajGoEU0rRPILgVWVoL5uSaYx7INMsuCKtZOpDxQ1AWIdrsdWlWangqJqblIculPB2i30qUQvSGXr6Otfhj5UlGj6i1/T0DE13VwZHa62yZZQ89EqyCG9hpYhMMhq66j1K24o6MhRjGXSqNC5Ce4M3CeVK41UEzWBDpY6hhm9KHgG6SQtZ8ZBuVh8smgdR9KLSAr2rOBoN3WSPRGyW9ytmNEOXkmRUo0ssM4dmqAD+3c+O7ZwVcZWmOoQCGWiijwDfIBUM+Up1mnwIyuOt3HVRMrEjo8aCB9dvJapgoN5HnjGzhtZnBP3OJMnJAyrwEGihjcXyvBo2A4nOJKMKmjPUo7utBwAlpKqyFFKjMfAoQts11ohqVEqymjoKT0jLfUwTCt/CO6ujYQFR7pDdJ3ChGeWxO/J3WDWjdflUSIuc6DWRi/b7ai2q0YuGECcbIpt2RFqgEktF0BuiMXQEt3cVN0vw/Fbk6tWdLXt9ga5ci6+XSK89XYoADPgdca2PgW2O3hL9G9WcKP8+jw91lMVbQcvu5hbB4HayimCZrheUUy9/0HN3BnztgfiEXhiQDPGK4YpDr9+8gj6uNYi7H8B9gNe+Z07x4bibOTUg3K5/8YSxbzYiCVjTdBzyKgyL3pMHDbdiyl0wRzfqCYHUNq57Cx2qOZvoeAnouRHbgQN+riIaSfKpIkrvAe0+PVv58Vj5VmWAtjx2VCuxhx6pJu+0707Zx5PlCGJjvb8DQrv6wTvzkL3/D/c3NIPdXNVCAcb2nw2wGsIl8T7yCJvHZYkVQTZdu+EGjW5Vs0vuF+fhlzet4BvOhbTw9d5lRAgrpAiBdmd4f78qibnC6QztfUcI03ZoDmpve2jSSkIHtH1Ml0QW1KobczHdDmkbc9ANZSQniJENYQgrRXNuN67t1+8/+gDJfEb5DePvOenLs3R6NpxVnH6qyLBNIvZfvg6/pyEmntYFpdZoaGYvZCo4J5BbgbZUr6cEBUKeypBGY5fkpPKiR5sWZjlBnjRPFBM5TTFDhoMJ0we4OC93MNREm8bzrV253ik/e510tq0YZLWGfuAxo1glaxHdJrBGXGOuQS+VtqmRkYrdFjx+PABkL43hFt4014glZQTLxQVTwhjivft2BcFy9LP7xQJd8F3zrxF1Dba84hrhbJGKoqw0kX4xHMWNbyYWzzz7argX0GOxtyFU/6N6/fU3fza271VnO+oV+8rLtjunSdiI2bGOG7wjEv1r45NTrxwbwJz/1oeu/4l/5nnLc+/U792PE5OXD8m2Z8OGKWacBXr7y/trM3ciiXWegL80oyqVpMQ83Rmt0qlnbJgLgmCFXqL3b35AN1x/+/olunl7df33H9CHG66//w493653iBOq10SidC2Ua5UmpCSphm998/2//8uLZ94VIXodUcYN1wNk6qLA/nY8KvLpe+Q1v7dn8aZmyn/Fs8+L6a5sOsD5iYBxRz/wPn4HimlrnfxKpa4wQ7cXb73M/i44iefLOu1k/JfgZOFfW8PuFyNCYSKHhSdswef4Bu/ZhxxrssVnaJEOp/sOXWSZBD+tPeU+dpqnNy3KU+OcT42F3Fy+ubOv0mR4rMBqxuhHz6lkNVX3dqObO8PKhPfLrOGJnSCCrKEZe3oNa00ssd215hUQHXZxllHzZczagG2nl7//nZvxABiTEC64cDf8qn8ERqy0udZR9LpjnzSM3joO74TUjUgeCd0MAmywAVTvDkteNfPa2/lQntePST2tN1MLz4nPbpzLi+u4A8sXKyVSalRO6zca6TjIyGWJeU4WjemUCr6ieSVJhpY7oEl4BllDfjlTngg9MCoandCWvYOuIuAdsIC6f7eEK7gDQJJCaJK4zO7weUbhlzbjKsGJTcWPQLrUMg7xVYQjsYpQLcxiXIdY+CdlhEXFWVJ74uKp5UML3sxjMRyt60w4gwZ7rddEcqLR+11JXqIP9TN2Cw6wb9Fd7QAbvQS/TGlqdaueGZSJCdO4Ztr5xV8izJhXmSjbL0KCG5aQmLch0ryBlGuBlIbHnHL04WZSoKSQIBtNXgUX2YaoKCO0fTOEJVGhM3oN2QglLvZFDJ2KDv72CNza1goJIzwP3ikSeDbKR0QtdEIDtSoPZp0ADEcppBOsEEY/CbnFMhv36UboIodkL4mwufEPkEu3JHpLCPernoFREx8b4xYas26ozjKDADIeMiNGM6Tc5blCWkJBtRFLrsWGf4obhvkccfwjHJR1gkjHRTmaYN9l2UZSNsaCzcGA7b88oSOVJAUUgk04PLjjIvZYappWDEsEeNGoZuL59cMPtyIXq5W/+ztJE70m0be3x+x7M6C9jR2+rw3fht2LSq8J1y5ZfJJtVYVETjguoccOOc36B0XkJMOi0qmYd6XdkNMM31dpSpSa4BmQx08DRzst8QT4QkbFzYXcIU9hwoi3OYRTj0cy4NFIJQjwqVJw864YueVTDpsfopGi1J/VJhwe3cS7iZFFLYWaAUZJ1szH+WEG+jDlSFFdeeQnguIC4kS0o7rGCuFMlOZ10WtCJRJb3m6ZXTiNHwQXxUReLfTkUNRC1M+rRBjlnvLMyB8hVbMAGP1EGUEXjrHFaBmOcfbyZmL2Tk4mjDfzP0u6wuQS3LushbCr4JujZyFC1rs/YSFsvt69q9cIvRLTCaFLEbN6wDP5JVnjDRUVaJepKEopCjqRoUjmZu6a4yWDIrIVutzPG+WbRuxEZHLIYU/rRF4GehwGbS5zAoOe8Rv+Yu9u55Vt79vksWvLLCuuh+VsoTX6DMrAk/QUs/4oLQje45xwImlaTwkWBBL9hqkFVK/hqfX1dkOO2UX6zUJpOR38rOd0CuzW2eb0ev+cnHphx4o4L69p2hjhmhZEGblutT1JSjIZRHK7EAwU4uBGAPDgE7dBHnm0TsHuPtvR+va4OX2TqGBNTo+emnMYH5rhaG4w41YgHCEMvtzZvT44Oznr3tmLFmRu8vDOBcNSnUeAHJDjjQD5co/jt4e3LFRrg3m27Dj5KGeVICHv2BHyY9bjGHJuo8PYKPVQgjbwUwev3Kn0OimIXoszRElwz5OMLBvua5MbDlhKUkT1Ou2J6rwTzPlrDSN7zmUkT8jfF3/6+mv0/Pbq4u4FuqJKU55XVK1JBqXwXl6YyEV0XKB9kTDIll1ZPtw2wxcnMsakiOxV3Ff/aXbVx0FzY8AjH6zp82OuSwpp/03db8fxBzz5YqaY+2DS20wxzEKh0w0m8g5ntFJ2BCQkUrSgDEsrnozYNHcohXfdX14F91zRbE6kkW6m/AdzEGov4gAXs73k8eosLvi+uw5hDVdp2PH/OicRfDI6C85xQzplGZnflSlkzMSAUcgGllrIHHP6+56sah7vKBy72CesdPdMTSz3ikpvLWkk1J+fzHDwWliIL4td1Mtq/plgptcplgSVkmSioBx7C+464ukOa0q4VgfT4xmec7a3+KyTtdCPpIx0cM3VeWYEV4mlBjCkdqr7xeqMYEdO2BwjUVckIxJrkiXBksr2nA8jfH6qR2yCZ3dSbGjWgIe57+GyZE5THR0MB/5jnrW+TutXcNpJ0mymWTZDOqw/vZuYprd5KGRObqiNnq+HivsEBFyjdIZsCv5YzZM8gM7U+VGnEjr3TNTqqKCxYoWUFtJKfEOtIBrDaM/gWwvzrWf+2Rc0yxiZT8q9gfGOlXOe7e3IvZPkXN0eY57p3rnROghDfFdHZ1+ikmGzZeZ9FhIRnspdOeXlh1TIGezJIzLoZGNb/iyURm9wuqZ8wqTLcCTJ8dVwrT9wyPQvJTHiw+hHFuRMLdBthkv0K/zD6keZ4Lbu9B/jxxOt8YYYzYkRLNGnisgdAgxCVQquSK1R+YtTzXwT+M088tJh4KWGsqQ1CiS307e4fNN81lOagdX2AL1z4KjHcgpdnuI6zIZnvIaW7oEYGdvQPbxUIVlx7rVj1cvm5bGRZwsjNVFj5ygmzsKMvxEYbSnPxFYhVZKUrmhqPnnpqxN0ebLjC2KmZ/ltc27Qc0CEJTxtnyEIXb7orBaqOLzjtyTH6Q59UH3g2yYCWwwLaYNn15oRZjDYJ177rqkFrECtGhwy8yKOVrzBAfBU//cqTaGcZ7x8/WnHV6in0Hmteu2ZMczQe9Dcb06Y7Dx5vVNTdRm+zvVey7prmPo0Cuh4NvM47JqAQX9v2oRMuw2jHfIDUhwufoaygZAtAScr3GDKGVlR7nz1IJwA1a/A5QToIHB3UqFYJN5aB8xA/QstGBufbey5OyylCWzKxoetNU7XxcwQ+O2osOBoZB11tyNKk5cl5eE6iAW9G2bKUFQY9/H0CKlu2Q5si4XRbsv7PV07R1zHffsOcF1iWZ8p8+eX7VS2azqCUkfmdhhb1ia/HzU9HbxniYW1EHIXb8N/VCXmfzmIGFMz0kdRr9Vz39NkluXHV0D9wNzOphKNZlXjre+f1eQpSAjXUpSniI5MVMuRc+GoM+7GNNY2OVCOADza6o557+GlKErMd819hGsH7fStvbIh0jxDCeUr4VcKsPoYu0bogPwYWJE1Z1sSFxV99SlWjsBPFWM79J8VZnRFSYauoO7ZOge9rGzJMkmF+EjPFHT/jSyRHb+1nzGb0uaDo8224fCy0qByn9jC9PBdf9cM4brsOHe09ckv0Ptdaafeeg7M4tgdnN48SVZJUDDZAduGB+uIkM+UD7Z2yMwcrrpGuexzZz2LpZC1tx9CzO9uJ7a8g5UT+DjVa1HG7UO0ZynMyAc99zWbUohImkifKTOO2Q9UYu13TaY8wSpktL9DWLpy+sCUK8kCbnOHasBdaYzRpJKhvCEdmorIBOfhbMqWdPDnqU86aPpjn7Q79REEC3nQhINqFd44MfSDneZG0VtLMkiVCa1R2SHmqCXsydz3MCyoV6/cf186Fl65/3B5TT63P2ZE+rPz3HTOGD23k+kGz8Hj2mm1NppO5hqiGZOK8hWRciLuOp73LPPqKv4Hl97rnp2ByRqXeNXZBs+VgrC2iHqlPEPMdvyubdzeHLv3kEEsu3/6GxknaE03/KTlmsh5/BFGZ3cZT88vofXjC3QJ4/tZI1LPBJYysc6XRLrmn6SXhbkHnJdEDR13FrKz4WbQZ6qDFL13p+nvp3olHw+N4t9tdE9/93tr6MdIMuXmb9eIk1xoajewXGM10QFKpXPDCnW20g4+3VzQbHW0DlCjBJfBGauB0+v6G39CiqL5HBUVfXyjpuvh+8lGy0aaUKWq4EonUIZkqXjeuqfFUIBDImVUH+hoU7rS89oMju4hOL1POs2SIdEgg7so8vN7SO3c/xh1pOdpTD5eeu7hcVqEKsWSTcwXfRhSdY5sLzNZYo4eroLDNKpYhOlH4izqSOAGX7XtSroPEsjW75CCeJ2Q6Ob+4m9v7tCdeafQL3yi+0rLbaRK6lO4fb8Vfm5BDKVrkn5UJzmRjxPCcTHIfE3nGrzOBiIM0kBdC8JWCu7RcomkI1DIMyi5lo8GFWTSaACeNdbVbB0+u1xuMKOZPYgeJoaCcDZU632CEFbsI9mpodgOdPLrBNLAtNdalyqh0IM2CmnYyhgLkuLP4DbRnNeVL0JSvTtwo1JRFFFx4o7k2/LhHEL+EvwtlYQNLc3QLpYtwzxR6lwNb83IVob/5mZb12h5ubWlxkkp6Bxp1T6GLQcIOACm/NYALGu6xpyPgDNiw025UYGRiZjtTLDNzcPieh7+dnvx1r17rwbDNw+KFnLo+w+O2UbVx2QjWBVrAS7qPs7c9blpOmPX7XwrTrVCzy0T6gWgdUBhb91Rd0AeAdPe2bAqkjS7dbx+4FS7dIFFv+hgQyRkCqwqhlLBU1JqYyjf2z2cgFfYbmNKX7vwxmCvW2gbRkshNRJmfX/+jwtfCq532UOfOyHz+RMshwUGPRfrEluwEy9QzF+vf7m7uUNv8ENBeda09fZvq5nb7GmYvSaKE9Ny0xjNbt+0GvXJX7IYPD3bVjkmq/kKNs9dhF9PObra0XOWOal8c+VQeh0Xezlk823KmbEC6hkX/+3rhpvCHJ6NNcnQtxv8JcaEPlN2o2tXDVZ8E9QtbHHvS6QqT4o6VuhHpaXg+V+WDKcfGVWaZD++cn972XxK+Yqk/o9WVJItZl5FBi9Z5zcI8wwpgSaOpSQ5VVrujGU/p7AosV47sP6GBzTkYcQkOKXmYtMWQtt6rVTIDgp5o082nBOuOzkpNd+uIeOi6aa2GFz+ad6n+M7ICldMJ3AnfkArzHqlyL0p9TP433aSI+pOkW3L+LZsTUu8WtEUGgksCeFILAE3ogPo1eyLwo+YzPBiH5jK+NY3LmPDNY+sThYqNkzShESReIsKohTOHS5RKoz8hgZmPkXyVuToiqQimwj7OFrBfVQW8zlgAtOA4TmlERRhmhdNrBDlSmOuazb8Nr6mJz3i2fid8qricA+psW61rXNq2xOgtbFtocPub1RzolS9+4e7IHCyIbILUFFiqQh6QzQGTd3V3DZDPb8VuXp1Z5NqX4zIX7l0sFatwOgdscLCnnDeYXMCSYZsorhwnhZtLlQeV3l2e/zG3fObq29cwMXCvrXWNWACPOBUIyZyu19jXBuYHXSydqcFvqf6fYfM793GLiZPxoj0SSfFdzJGlKdPyuSWbObdk9f/f0/274kZNc6GPO36iuU/Ey/W1WfD3SZWqPRprEkSMyv26csW6/4/jTOw/eIV3D+NOVxlVCeAR/05stc3nD4jxtYBO+oGZYzy0xiLqzHVkuPzPWkZOalZbNxlWxGSxS4CmQ5bdGETLZAkyUZ6yEhJeJoVMdBDRtQPWBHTqzh/nfmwMa53+exyjaYZaPmQZwUfvXzpHGq1iw40arRs5u/+tOsbtZeCp+ZxwFp87pbthLgBkLqI4rC7updmGJv80rnPtyJ3bV1dFQNgyRkTRBInqEZTX9EHkiFFoNNu78f9MdS0wVJvwoj2kw2WZhNGpB+1KWNPYHj/0mkHczSvR6zJ49YgIMTCnnP5c51X6k4kG55IRXiDPMxErnzHpuND+nLWl55ywEY/mlzYm7vNdy0e4MR1Hy7uaPZafKmLu/k+9vJ+///u8kaufXJrPJQL1pHW9ZZlCKOcbghvnGRfriJglug0/0VcCyT7HJW/LyOiMenQEOUukeRThL3uBg9hg2HeDszv2mGK3cFFeum82RrbCusUjyXIktTJox9uuP7meyQk+okJrL993U/zSgVf0byS0/kt7bxPUXe/4HlDGPRzLZsEy3gGzIyp7Ji6muhLdzAIucUyi6bU7e9UbxWSX3v6HkaSMDxOTbPQqu4RdWw7MEw4qapF+RCS5pRjVv+mr60cWIdY+teexIibu1+/9ywB8qLJogBL0HA0XuUQr097UMeK46mvz5rgLGJ5fc+0g6HQzdVToqSW326wFMicFiv9rJ1sLE2i+9lwk4PbKlpwUYzpcikYA9zUL1EAm9U7Q86NOXNUodQuXd0erqOo3opxO4vphf4MLb4iXX4uqmohlK4L95a70aY1nbgMQUWLku3cPpkvQzIzwekaKZoR9PxrpNeyQq//9KcXaItdK6F6lD0r8Vkor0eshOurE20p0i/mVNimKrVPocFdNVdZeSmg53gpNqSzGNRfolOLN6UlwcXk/Um/mGNz5qUiGT0JNOHQQn3l0xwbxwJdIapr3B8Q6a8sTGjN9Lid1T8Q1IvsiESv0TVPcakqhhuwskfJdR/1JwY/PLmVvlG+fY3+zUz3Jfr2W/RvKBXS6MsWc6BupvY/mf7f5otUof6i+OEvuMjIZ2vr8i1JUszYEqcf45c+ZYQLXbdGA7vCLGJd8wKmyVRXOjgc0cGM4MgA4DZmwLHtY6+FNJo131mtw3zQAaPwMYXQSlQ8My8Mg4YMChABjkte7N+IEeUQsUB3HfaEjSZ2YccEzj6Xd86xgxT9HZpRSpp6rA5nCne/DLawfe5rIWyefaxbjVas6m1boJ/F1mzN2OakHAlpjDEt0EdCygOL9lm8eF/IotnGFMkmZsPz61ryQFsq25+aQyf+jl24oRJapt5c9X3v3OPi6PZ0h8Wws3BX/eYKSSOtFThUxr1FJrv/NysRrZ757CvR70cykS8XJRQ0Fvwt+NU7QMNvejSnkmDXCGhCUJr/1YGYLyDw4kZKVMlobPSSz9acVzRWIewTU6RPA4069rzDrTNvQN0RyJ262mpxT8h/jwijFS+jdkGzxOihBZCQ6O7y4s7pvinmZnloUQo51HgRPJFfXBpE9Xm4Pz7YpwoMcV+rWzQ25av2J63BbvUcsMwX6PWfvkdbWPeCYI4wY35fQV39vEKt/whtiSSWLNaIEaw0EnxQLtJfxLOriV/2InruaoywrVu734TMYOEgq4mkay6YyHfDQNyKypEWi9CfULrGEqfaLiIB+CLDhe3gjirucnpYz2c+WVEbuqDbBupjBhH2dVswFkVhlEzB6zCCxNtJmQaSdaBW4hQ0Vhuj4M7nINK0kjVFpTHPsMwQF7LAjP7uy+8VsvCuT+ayHE5eouN64e1ZpJbrhplXjK4IzNhj4CuSCp5NKNjtdidKzwBo75sQ5akoSka09wBMOlExKPDTQNNKY6nPdJDvzdje4zx1lPsnc/L4FYIHR0LORgkSTwY94NmZFv6aZzGW3ZD8XfAzoefUo9cqpk2vfT9c4ZGIinajLxA043YtyB0cbs1dti8PzLO/Tz1su2Er8KeTlCQVMiNZvHfQJdm4Z0o1I9Y6Rp1p03yxG18fv1ZSFAugWkFRvkoJx5IKq9YXFdP0j5oSiXBZsrr6pcWyKTDHua80FyEG4Z3aXrRMWV4VovqZQmLLbWRM46IcegYdx3XXpPHt0wqla2qsG5ERtUBvKqXBTOoStehZE3m5WJMTN2mvAFutDN8bMocmBJtcD2jXzjZN46k9ENio1hnd0MxoNnAe/ILsvhZk7weL55/kQ0nlbDNs99PGgh7MSaSa7exklRF6Rl8zTMEB3e8bDbjpB9C+a3m2GA3ZoqtVoSVQEbwVZ7P+oa8KaJCfKlLNdpTM6banqJWPWwxtT6suAFeXzRKYC9XqoVnUgEpBb0EjyLS80BFe37yIwWuZRGC1TGJoz2VIUdQnGqrVR0s1gq7UeUXOY0IOzEfvGzN6Lh/15pwqNg/JtVOCBe0DMUBDCO0IwulIiQ+hWKuKnQk0X1Q6FQV5ZXlojBfXwGV0QjB3S9AzICcOCNkQSXVsaNAp9Gk3uisCnGpNOnD5zNy4zb7STaWLoQZxJ9vqvjV8/NqtDeZMYao4XTl+NpNnAxoXI81GnWGbTrBevn1dZCJuwq99K71rCQqJfrl3qbFU1QkBQ78ajF/v0FSVpCqFogEFx1FnC8xpnrXows3dnUThqZhO4kEXPVIU8aogkqaPlUXeuc3U+fmISrbmZlixZO/3aGobwjPok3xQbonlP8+AXlOHdsW4O22Xsfi14KPlhn7Aexmzkj4mVt1Xk51gnZhxXq41bnKLudAIN53U/Am0TORJnahyFqFeH8RHC/U5MFN6su+vkG4FqNVj2O9G8ReMprs5uu1MyIU7YMCBa3O2m5DLFYuZN+1fwHeVA//3i1PBNXmIrbE2DN20rQLq6qosU+b/4FHFrGbIBwBz4HFO15jnJOFkG1sWTAUuybYT6gclRGtJl5UmHQkxztFXlnWjrXefv4mmxCUOJuyalWOjDh2z3BwwBIf5RZaZrv7mMW6hAswsWA04qNqcL7khcoHuid2UShG5wDkBKG+X6b4SsuZhRLsmY/X2FH6P7O87uBVCoqUUW/NZ/de07uNozK5JPOmb7A5LHdpN1xAO7VFxd0qMqkPnulOCZW0P0khXSpTEBRRjvcUXHGFGpG6yi2Q7qPubDW858dEBAYAkJI/CnCEu+B8lKQlYMvuyH+boi9LH0fd1Q7F63CtqI2x1+Gc0M9dUo5X16AoGXEK1CUeC/zEX5r/3vASgpCQexTHivHEnGPgKGDBMihWCDvOUqAW6b2XKsLFBt7IqDseXtpyvUsaIsSWjNtkmc+K36WaSskrp+kC6f4y2CX5CldlJVxPt/BtG8YVPp1Wg2bUfe8P8Fr2FZYqnlD07ZHgZLq+AC4SVEikFf6nZDa89CRt2Sz+SHzqNDKFx4UtUSuiJ8hIRnT7zK8pY4lANqw8EsWAooolUqMQKULwUADm4btKiKIwUE72g/bi0huh0r7pn34NzaXydPYzwMFnxnYqirMZ3MMK2YbSlPBNbl0/ruk2+bDIpJhdjNM1VxdgOfaows87PTBSYuka8MO96ICYmnq6u1zNSA/tRazjKP5LM1QLViehYgXfKGSjmk68a1hY027dxbIQKEVXUdTs7WbfEkIGavV/uz8XXL6XzvKL7MVxPE3QmsqDDxk6xXaxuzE6bvP2a9reBNe0VZfHveDPln2C05hpLklUpQXXkiPjdbbanfuJ5TaM9Ive9Nv7D97HzAJoXZtIvQNKP6iTIgRAeYze6eejWWK2bG2rUQk+VYZWubeZvXWPTlBle1pQGEGFmIs0wCyVT86vm3+NKU2TkOUcUcu4qnjKCpfkTAOG1rLkCwrrza13YeTj6YIVfNcZ5+qxfrFQUy6Z976r3YLmyUfmI12tDZaXm9vR1tRFgYNrjN0+A1HMlLu3oFpNx2lNqLbj5GtdaL/PNlWvBjZ474Ia6N6Ut+jW8vfDr1dYBfa4G/879fHPV7e/aiImx96AfkbNpgHYKC3uIjCzYUuU3UjdqFxPLvh/VdQXaVl3Y68fm1vieud3xZTMwurk6qMmG8s8d0GQNY6951mq0C3Rp6zMd3imzH+zXZoFB2f/GN185d9yy0k3lptDNY1RxRpRdGWEflK1AGywpXrJRFaAFZaAclQxPCAJFuIqKj9Lb0K6qakdeGEllNIy6vpCafb5/dXM31KGRg4y1HoWpuuwTGwoeXQvZRlosk+iGa3RPc45BWEwc0VLImOC1z0byyxzSu1p3E4DqCP9pGOncZThlmfAcnLe/vEeUp6zKiBFnrpGt+fkCPb9+wEXJyA/ozjpELFmQ3gu/XwQic7PHNsE51T4tfs6o+mhU7hP4ekQpXseN+dY9De+o+rgn5KolzXMi47Ww8y/Zr91YgOMBtNO1JGotWGZOj7XVJzqN9kLvM3gWxrF3J5Wfv7M6xosGjOPmyl9GcnR0PhVFmcycdwW74nKvoI2r9e+pavlHw47gUJ+6gnYzIqvSKSvNqaVnyhrrct5ISyEBecDI9Zq/iS5xWGZbLM+ToTdG1TfSFbuHyExiAhr5uRGiGL3BaY2n7FdujQia1Y4R/I+1gir3SyFrawZvai0JVsFzg5XGugqlODf+KEzZ2cwOM/hSPCCavZp+v8zLWs3BoeHowwj42N4Fw4X/6tbvWOTue6NDfjXuu3fKc0a5qELFODt1JCoPfqeMJA3pdBh5ZL8LTDg2MmPvSFwwZuQeUlWaEqVWFUPXZnyUiowocyRqsF+/ZUF5Rh4CLwCjSp+meT5RtsDAYIrJmoklkRDfLLCkDDJ4PB48G3/nOcKwiH80v/XOjEc4h2JpwYXOpBG70dHzJp+zJFKVrujWSpjRkjkVoU2IrxGeXkwUGVo31/g9jp1QYpWvJsnL+arst82HmHKFMqIxZR4nw1JUuvO7iakJNntuZu2xxU0eG/Ax/ZBqUpQsWjbPBcrICrsQkEO+rGP4LlvTaMUbIhneQSGXFu5xRc89N9J8AFa3+zVZ1VXg1levNNUVADMi78Ra22AM2PTU6xo0itXx76Q4NKcRZFUqisLcpzjH6NJSR7ST7FtKsaGZ9Z/VKHIFUZOJUJlITw80Pt5b9hNlrdaYdvPy/KrBQwlJT+eR9fXocWX9P8XyRL/TydP7P2LpAjD+21XSeMC5V5BQbHf+/u4G3YwUqi4b0VBrXXXJfg4CFnY11bB5UEP6Mf4wl1vtV+6tiEiWIotd8TWquBsqHY4XZHiZUI/W4dESbMhghsrzjgvYlQ7bBNomHkJzmjWhnAknXhHaahyVgQd4+cMpec28yyrmM1V39777YNFz6kAUJGs8kLTqehFs6teS+MpbaxSmfYkbMzhCvF7xrO8Qaaor8QZThseBDNS4whHUV66IlBOdFuwdOsXXHy7u5oyVwgFA2QDsaEou3UDRfDEhEWmRLKss2wX3z9AiCVoH1KFbKXIa0PleL1V4ipKKgCgHgxK7RFVzFCRQ1c1etZiruMqobirrWlw0x5GvsV1bsWFFSRte2D9JmyUWegU3s1nll79eo+euVuLXihldeUkZFHBAHtj1QymU+eYL9Mexo4EPozAfudjyniGkSFoBmMWmT32i02aKZ3DBDdNCL+sq97euNOmW5DjdoQ+T5hqjS4nPUZTvBu4tMeWowJSvJC7I3nSMEkvo2hsfJ6GnXN7BsOityGxydAsL2Mk68zCFDmhfkCpgFiKWhdTHjXtLtujnioMp+UZkhKHnlG8Wf3iJqEhfoqX5P2L+D3PMdoqqxR/88UWdlsmK4VHn/NA6VF/Dv7xDMCj4ukBO7urmV2K1F6hBi6ic2r8uHZ81DIIi0hxkL0ObIqzcHXD265vfsCTovU0A/sMffn3z28W76z/8webcbrDEdPJMboX8GLJk+eAF+60esBthm3SCYR5aiXA1O2FRSprnAKfmudhFMGFWQhKuaBpSgHRcSRE4LsJ7QTzxgVBEky2m4+bET/YOAPZ5aKLm+oQuUVfVMtKl0MtMaRm68h3qtaM5xLpvabB3tK75iOckPbXYpW0MNlJpXLFJW/fi6l0MiRWddDTVU43miD11ql40Is80h+U9fqF8Mp7g4x0Xhnmn/78bj9qqzLbz31mOWNbx0TtG9jJ5lsNRx3H38SfEDElbvZ3t2KXPdZPRXmfZAU7mC3C7jU7u4ch0DVlN54iHQdHXClNm1roGc7lzMuPmqlvbBkhcxhzUJPdAGExnFdY514lREU+YzymJ15Bu7aqPLkVRVHzoiRpxx08Dbnoqd2/Jg/4r8evUDW/qNM36qbzdY579h/BHzVreNNb0FMnwZO7GA/eYU5UqaUpFsCzRuSx44H6LJR8HHT531hUvykTEEsb3b9/coV+sH7VNSvUz8mnWVIL7/7xFnyoiJ7BbK8YTSYZInXGTGzoO0R16VxededO6Gi09DfiQdomK0G0EDNHyJMfRIaraExx7Mt0sfIMGzLAsIuyWIRvBvYDLgAXIDdEqC9aVtkczLNpVj3SG9VArfCrdJeHpusAyVFlJQ3dX4lH74idHn3A6SqcKQjNZBz8LKVmFLaBqCK9ygFqKQFYs/xmBaomDd8KwiFPBjxcE3RMa+sFxyG0FMapncKZ5glNojBK+/MTQVjyg8d4hvMzLzXf8Qa+Dv+8pT1Itk0wFxV3vUDeUT4s8HUF4w3BwicETwnPKAxZFjknHyI3mySpRW6rT4PKDJysmtgoX4XNXurS53sSjHiHqkvKE8pjihPKSyGK5C5bwPqJdph/jEN9gFuOs0DIppdAiCR+SAuqb7xLwOIanzaLdTSbyJIux2IZw+Py3lCcFfki0DuU26BM2J5qRCI9CQXkkpimPx3TJVMKWLAkdFu3R/joi8eDI4B3aobEQu7RDV/V2af8pIu3vI9L+14i0/1dE2n+OQ1uLkuEliSFSGurhzTOeFBUD5Xu5i/BO1sTLjxH0kqJiNC/KONq30TIxy0MnITnKNIZSosinNLxvhCfKJiRG2EEl0zjWpCEcx5pUO1WVEXqRprwpq45iqmqhjelBHiKIEC20Mcxi0QazJgrxitMHjrlQJI1wCDffm1WJ9ChsvhelXhOcRXCriaJMUhbBh20IRwiSAF253OnwblFDWUWhXFZJhJhGKqmmKWYRCohUgnPC013ArKsubY7Z7neSLWPwvUkABjQKZQsHE4drm1gbhfoyLzffx/FBq2RJ9Z+jAI2lKgnbK25AWIrgolpFueZAlaQyfJWbsj7+YL22OoSJXls/f3jniCUOal8U4hZNPhyCXIf2ijISw4ZRySrGJtJVyOLsPuEYuoFKaAlJikkUUUfLzXeZ0uUIzD8QbSXTKLQZXZEYZowCR3NBMhqsYLRPm/I4p6QQWcWISkWM1XbEaR5BNolSbbEO2vO/Q92XQR6EsCQ5VVri8J6QlnYEjU+SMtZSy2hrrQCJXEaSrzYz3x7xCNS1JLiIoEjaUqBYbMdTrrdrQVViO8yGp77DEkc54NlEIWwIyhvb3z40Xao05sH7HGdKLysZqllgTZXYXkExqFbBeQ2vR9c1yaHJQueGVfhm16ciDeyjmeMsC30HaBY6rFpDB0V4i2iRpFKIIgoqkSEcwUyjRRInOdIhHsVY5vJjcHimUoWHLKWlKiUNTJRhTXUVPPuMUU7CQey0VFXQjjoNXSi+De/WYsKiniYrJoI/5w3xCCn/xuYNLnUM0QgSx9jQEVgNnpvARB7l6PI8ygUuhQwtwIpllce4ZgVVaQyxUKgoBzZGHwhONIArBacbXIZbAOjQGX+Wauh0PL7dhrZAolSUCdsAOrglKsJrRkLSPPH043oy3S0nMvybVSa2KW9wskE7U7dkbYvXKIcsQuGm64kTWhg4sqGlQZlYR1JwdrFS5sMkXYeq8x+RJg8lDR4IKIkscom5HmHuhqC8jUI4/NNrkcg+fBh0AQ1AWIo8waoM2DCgS1ri0FQlwSyGfidJCutgUUcjEQ+/yIZyWAjXDmUhswgch3dkqgi+YWV9wxHyARQJnQhgGx5HME4U+RT+APgAWoNRjWBKKZpHELyqDO1lUzKNcQ9kmgVXpJVMfai4AQjrcC22ujQrFRxVc5Py0IUS3m6xTyVqQTpDT1/nOvyxskTDR/Sanp6h6e7K4GitVbaMkodeSRbhLawUkUlGQ1e9R2lbUUeGYiyDTpXGRWhv8CahXGm8iqAZbKjUMdTwTckjQDdpISse0s3qg0XzIIpeVFqgdxVHo6Gb7JGIzfJ+xYxm6FKSjGp0iWXm0AwVwL/72bGdsyKu0lSHUCADTfQR4BukgiFfqU6TD0F5vJW7LkomdmTUWPDg+q1EFQzU+8gzZtbQ+oyg35kkOXlABR4CLbSxWJ5Xw2Yg0ZlkVEFzhnp0t/UAoIRUVZZCajQGHkVou8YaUY1KSVZTR+EJabmPaULhW3hndTQsIModsvsELjSjPHZH/g6rZrQunwppkRO9JnLRfl+tRTV60RDiZENk045IC1RiqQh6QzSGjuD2ruJmCZ7fily9urNlry/QlWvx9RLptadLEYABvyOu9TGwzdFbon+jmhPl3+fxoY6yeCto2d3cIhjcTlYRLNP1gnLq5Q967s6Arz0Qn9ALA5IhXjFccej1m1fQx7UGcfcDuA/w2vfMKT4cdzOnBoTb9S+eMPbNRiQBa5qOQ16FYdF78qDhVky5C+boRj0hkNrGdW+hQzVnEx0vAT03YjtwwM9VRCNJPlVE6T2g3adnKz8eK9+qDNCWx45qJfbQI9XknfbdKft4shxBbKz3d0BoVz94Zx6y9//h/oZmsJurWijA2P6zAVZDuCTeRx5h87gssSLIpms33KDRrWp2yf3iPPzyphV8w7mQFr7eu4wIYYUUIdDuDO/vVyUxVzidob3vCGHaDs1B7W0PTVpJ6IC2j+mSyIJadWMuptshbWMOuqGM5AQxsiEMYaVozu3Gtf36/UcfIJnPKL9h/D0nfXmWTs+Gs4rTTxUZtknE/svX4fc0xMTTuqDUGg3N7IVMBecEcivQlur1lKBAyFMZ0mjskpxUXvRo08IsJ8iT5oliIqcpZshwMGH6ABfn5Q6GmmjTeL61K9c75Wevk862FYOs1tAPPGYUq2QtotsE1ohrzDXopdI2NTJSsduCx48HgOylMdzCm+YasaSMYLm4YEoYQ7x3364gWI5+dr9YoAu+a/41oq7BlldcI5wtUlGUlSbSL4ajuPHNxOKZZ18N9wJ6LPY2hOp/VK+//ubPxva96mxHvWJfedl25zQJGzE71nGDd0Sif218cuqVYwOY89/60PU/8c88b3nunfq9+3Fi8vIh2fZs2DDFjLNAb395f23mTiSxzhPwl2ZUpZKUmKc7o1U69YwNc0EQrNBL9P7ND+iG629fv0Q3b6+u//4D+nDD9fffoefb9Q5xQvWaSJSuhXKt0oSUJNXwrW++//d/efHMuyJEryPKuOF6gExdFNjfjkdFPn2PvOb39ize1Ez5r3j2eTHdlU0HOD8RMO7oB97H70Axba2TX6nUFWbo9uKtl9nfBSfxfFmnnYz/Epws/Gtr2P1iRChM5LDwhC34HN/gPfuQY022+Awt0uF036GLLJPgp7Wn3MdO8/SmRXlqnPOpsZCbyzd39lWaDI8VWM0Y/eg5laym6t5udHNnWJnwfpk1PLETRJA1NGNPr2GtiSW2u9a8AqLDLs4yar6MWRuw7fTy979zMx4AYxLCBRfuhl/1j8CIlTbXOoped+yThtFbx+GdkLoRySOhm0GADTaA6t1hyatmXns7H8rz+jGpp/VmauE58dmNc3lxHXdg+WKlREqNymn9RiMdBxm5LDHPyaIxnVLBVzSvJMnQcgc0Cc8ga8gvZ8oToQdGRaMT2rJ30FUEvAMWUPfvlnAFdwBIUghNEpfZHT7PKPzSZlwlOLGp+BFIl1rGIb6KcCRWEaqFWYzrEAv/pIywqDhLak9cPLV8aMGbeSyGo3WdCWfQYK/1mkhONHq/K8lL9KF+xm7BAfYtuqsdYKOX4JcpTa1u1TODMjFhGtdMO7/4S4QZ8yoTZftFSHDDEhLzNkSaN5ByLZDS8JhTjj7cTAqUFBJko8mr4CLbEBVlhLZvhrAkKnRGryEbocTFvoihU9HB3x6BW9taIWGE58E7RQLPRvmIqIVOaKBW5cGsE4DhKIV0ghXC6Ccht1hm4z7dCF3kkOwlETY3/gFy6ZZEbwnhftUzMGriY2PcQmPWDdVZZhBAxkNmxGiGlLs8V0hLKKg2Ysm12PBPccMwnyOOf4SDsk4Q6bgoRxPsuyzbSMrGWLA5GLD9lyd0pJKkgEKwCYcHd1zEHktN04phiQAvGtVMPL9++OFW5GK18nd/J2mi1yT69vaYfW8GtLexw/e14duwe1HpNeHaJYtPsq2qkMgJxyX02CGnWf+giJxkWFQ6FfOutBtymuH7Kk2JUhM8A/L4aeBopyWeAF/IqLi5kDvkKUwY8TaHcOrxSAY8GqkEAT5VCm7eFSO3fMph80M0UpT6s9qEw6ObeDcxsqilUDPAKMma+Tg/zEAfphwpqiuP/ERQXECciHZU11ghnInSvC56TahEYsvbLbMLp/GD4KKYyKuFnhyKWoj6eZUIo9xTnhn5I6RqFgCjnygj6MIxthgtwzHOXt5MzN7JyYTxZv5nSVeYXIJ7l7UQdhV8c/QsRMh69ycshM3Xu3f1GqFXYjohdCliVg94Jr8ka7yhogLtMhVFKUVBJzIUydzMXXO8ZFBEtkKX+3mjfNOInYhMDjnsaZ3Iy0CPw6DNZU5g0DN+w1/s3e28su19mzx2bZllxfWwnC20Rp9BGXiSnmLWH6UFwXucE04kTespwYJAot8wtYDqNTy1vt5uyDG7SL9ZKC2ng5/1nE6B3TrbnF7vn5NTL+xYEeflNU0bI1zTgigj1622J0lJJoNIbheCgUIc3AgAHnziNsgjj9Yp2N1nO1rfHjenbxIVrMnp0VNzDuNDMxzNDWbcCoQjhMGXO7vXB2cnZ907e9GCzE0e3rlgWKrzCJADcrwRIF/ucfz28JaFam0wz5YdJx/lrBIk5B07Qn7MehxDzm10GBulHkrQBn7q4JU7lV4nBdFrcYYoCe55kpFlw31tcsMBS0mKqF6nPVGdd4I5f61hZM+5jOQJ+fviT19/jZ7fXl3cvUBXVGnK84qqNcmgFN7LCxO5iI4LtC8SBtmyK8uH22b44kTGmBSRvYr76j/Nrvo4aG4MeOSDNX1+zHVJIe2/qfvtOP6AJ1/MFHMfTHqbKYZZKHS6wUTe4YxWyo6AhESKFpRhacWTEZvmDqXwrvvLq+CeK5rNiTTSzZT/YA5C7UUc4GK2lzxencUF33fXIazhKg07/l/nJIJPRmfBOW5Ipywj87syhYyZGDAK2cBSC5ljTn/fk1XN4x2FYxf7hJXunqmJ5V5R6a0ljYT685MZDl4LC/FlsYt6Wc0/E8z0OsWSoFKSTBSUY2/BXUc83WFNCdfqYHo8w3PO9hafdbIW+pGUkQ6uuTrPjOAqsdQAhtROdb9YnRHsyAmbYyTqimREYk2yJFhS2Z7zYYTPT/WITfDsTooNzRrwMPc9XJbMaaqjg+HAf8yz1tdp/QpOO0mazTTLZkiH9ad3E9P0Ng+FzMkNtdHz9VBxn4CAa5TOkE3BH6t5kgfQmTo/6lRC556JWh0VNFaskNJCWolvqBVEYxjtGXxrYb71zD/7gmYZI/NJuTcw3rFyzrO9Hbl3kpyr22PMM907N1oHYYjv6ujsS1QybLbMvM9CIsJTuSunvPyQCjmDPXlEBp1sbMufhdLoDU7XlE+YdBmOJDm+Gq71Bw6Z/qUkRnwY/ciCnKkFus1wiX6Ff1j9KBPc1p3+Y/x4ojXeEKM5MYIl+lQRuUOAQahKwRWpNSp/caqZbwK/mUdeOgy81FCWtEaB5Hb6Fpdvms96SjOw2h6gdw4c9VhOoctTXIfZ8IzX0NI9ECNjG7qHlyokK869dqx62bw8NvJsYaQmauwcxcRZmPE3AqMt5ZnYKqRKktIVTc0nL311gi5PdnxBzPQsv23ODXoOiLCEp+0zBKHLF53VQhWHd/yW5DjdoQ+qD3zbRGCLYSFt8OxaM8IMBvvEa981tYAVqFWDQ2ZexNGKNzgAnur/XqUplPOMl68/7fgK9RQ6r1WvPTOGGXoPmvvNCZOdJ693aqouw9e53mtZdw1Tn0YBHc9mHoddEzDo702bkGm3YbRDfkCKw8XPUDYQsiXgZIUbTDkjK8qdrx6EE6D6FbicAB0E7k4qFIvEW+uAGah/oQVj47ONPXeHpTSBTdn4sLXG6bqYGQK/HRUWHI2so+52RGnysqQ8XAexoHfDTBmKCuM+nh4h1S3bgW2xMNpteb+na+eI67hv3wGuSyzrM2X+/LKdynZNR1DqyNwOY8va5PejpqeD9yyxsBZC7uJt+I+qxPwvBxFjakb6KOq1eu57msyy/PgKqB+Y29lUotGsarz1/bOaPAUJ4VqK8hTRkYlqOXIuHHXG3ZjG2iYHyhGAR1vdMe89vBRFifmuuY9w7aCdvrVXNkSaZyihfCX8SgFWH2PXCB2QHwMrsuZsS+Kioq8+xcoR+KlibIf+s8KMrijJ0BXUPVvnoJeVLVkmqRAf6ZmC7r+RJbLjt/YzZlPafHC02TYcXlYaVO4TW5gevuvvmiFclx3njrY++QV6vyvt1FvPgVkcu4PTmyfJKgkKJjtg2/BgHRHymfLB1g6ZmcNV1yiXfe6sZ7EUsvb2Q4j53e3ElnewcgIfp3otyrh9iPYshRn5oOe+ZlMKEUkT6TNlxjH7gUqs/a7JlCdYhYz2dwhLV04fmHIlWcBt7lANuCuNMZpUMpQ3pENTEZngPJxN2ZIO/jz1SQdNf+yTdqc+gmAhD5pwUK3CGyeGfrDT3Ch6a0kGqTKhNSo7xBy1hD2Z+x6GBfXqlfvvS8fCK/cfLq/J5/bHjEh/dp6bzhmj53Yy3eA5eFw7rdZG08lcQzRjUlG+IlJOxF3H855lXl3F/+DSe92zMzBZ4xKvOtvguVIQ1hZRr5RniNmO37WN25tj9x4yiGX3T38j4wSt6YaftFwTOY8/wujsLuPp+SW0fnyBLmF8P2tE6pnAUibW+ZJI1/yT9LIw94Dzkqih485CdjbcDPpMdZCi9+40/f1Ur+TjoVH8u43u6e9+bw39GEmm3PztGnGSC03tBpZrrCY6QKl0blihzlbawaebC5qtjtYBapTgMjhjNXB6XX/jT0hRNJ+joqKPb9R0PXw/2WjZSBOqVBVc6QTKkCwVz1v3tBgKcEikjOoDHW1KV3pem8HRPQSn90mnWTIkGmRwF0V+fg+pnfsfo470PI3Jx0vPPTxOi1ClWLKJ+aIPQ6rOke1lJkvM0cNVcJhGFYsw/UicRR0J3OCrtl1J90EC2fodUhCvExLd3F/87c0dujPvFPqFT3RfabmNVEl9Crfvt8LPLYihdE3Sj+okJ/JxQjguBpmv6VyD19lAhEEaqGtB2ErBPVoukXQECnkGJdfy0aCCTBoNwLPGupqtw2eXyw1mNLMH0cPEUBDOhmq9TxDCin0kOzUU24FOfp1AGpj2WutSJRR60EYhDVsZY0FS/BncJprzuvJFSKp3B25UKooiKk7ckXxbPpxDyF+Cv6WSsKGlGdrFsmWYJ0qdq+GtGdnK8N/cbOsaLS+3ttQ4KQWdI63ax7DlAAEHwJTfGoBlTdeY8xFwRmy4KTcqMDIRs50Jtrl5WFzPw99uL966d+/VYPjmQdFCDn3/wTHbqPqYbASrYi3ARd3Hmbs+N01n7Lqdb8WpVui5ZUK9ALQOKOytO+oOyCNg2jsbVkWSZreO1w+capcusOgXHWyIhEyBVcVQKnhKSm0M5Xu7hxPwCtttTOlrF94Y7HULbcNoKaRGwqzvz/9x4UvB9S576HMnZD5/guWwwKDnYl1iC3biBYr56/Uvdzd36A1+KCjPmrbe/m01c5s9DbPXRHFiWm4ao9ntm1ajPvlLFoOnZ9sqx2Q1X8HmuYvw6ylHVzt6zjInlW+uHEqv42Ivh2y+TTkzVkA94+K/fd1wU5jDs7EmGfp2g7/EmNBnym507arBim+CuoUt7n2JVOVJUccK/ai0FDz/y5Lh9COjSpPsx1fuby+bTylfkdT/0YpKssXMq8jgJev8BmGeISXQxLGUJKdKy52x7OcUFiXWawfW3/CAhjyMmASn1Fxs2kJoW6+VCtlBIW/0yYZzwrXc/Y//GwAA//9WxwJp" } diff --git a/x-pack/filebeat/module/fortinet/firewall/_meta/fields.yml b/x-pack/filebeat/module/fortinet/firewall/_meta/fields.yml index aa1ec9eb99c..bc2ddf7602e 100644 --- a/x-pack/filebeat/module/fortinet/firewall/_meta/fields.yml +++ b/x-pack/filebeat/module/fortinet/firewall/_meta/fields.yml @@ -766,6 +766,11 @@ description: > ESP Transform + - name: eventtype + type: keyword + description: > + UTM Event Type + - name: exch type: keyword description: > @@ -2006,6 +2011,11 @@ description: > Security action performed by UTM + - name: utmref + type: keyword + description: > + Reference to UTM + - name: vap type: keyword description: > diff --git a/x-pack/filebeat/module/fortinet/firewall/ingest/event.yml b/x-pack/filebeat/module/fortinet/firewall/ingest/event.yml index 734e2832f26..c19f8e832bb 100644 --- a/x-pack/filebeat/module/fortinet/firewall/ingest/event.yml +++ b/x-pack/filebeat/module/fortinet/firewall/ingest/event.yml @@ -3,6 +3,10 @@ processors: - set: field: event.kind value: event +- set: + field: event.action + value: "{{fortinet.firewall.action}}" + ignore_empty_value: true - set: field: event.outcome value: failure @@ -16,24 +20,29 @@ processors: value: - user - start + allow_duplicates: false if: "['FSSO-logon', 'auth-logon'].contains(ctx.fortinet?.firewall?.action)" - append: field: event.type value: - user - end + allow_duplicates: false if: "['FSSO-logoff', 'auth-logout'].contains(ctx.fortinet?.firewall?.action)" - append: field: event.type value: connection + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'vpn'" - append: field: event.category value: network + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'vpn'" - append: field: event.type value: info + allow_duplicates: false if: "ctx.fortinet?.firewall?.action == 'perf-stats'" - append: field: event.category @@ -42,16 +51,19 @@ processors: - append: field: event.type value: info + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'update'" - append: field: event.category value: - host - malware + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'update'" - append: field: event.category value: authentication + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'user'" - rename: field: fortinet.firewall.dstip @@ -95,10 +107,6 @@ processors: target_field: destination.domain ignore_missing: true if: "ctx.destination?.address == null" -- rename: - field: fortinet.firewall.group - target_field: source.user.group.name - ignore_missing: true - convert: field: fortinet.firewall.sentbyte target_field: source.bytes @@ -144,10 +152,6 @@ processors: field: fortinet.firewall.saddr target_field: source.address ignore_missing: true -- rename: - field: fortinet.firewall.agent - target_field: user_agent.original - ignore_missing: true - rename: field: fortinet.firewall.file target_field: file.name @@ -167,18 +171,10 @@ processors: target_field: event.code ignore_missing: true if: "ctx.event?.code == null" -- rename: - field: fortinet.firewall.msg - target_field: message - ignore_missing: true - rename: field: fortinet.firewall.policyid target_field: rule.id ignore_missing: true -- rename: - field: fortinet.firewall.proto - target_field: network.iana_number - ignore_missing: true - rename: field: fortinet.firewall.dir target_field: network.direction @@ -207,21 +203,10 @@ processors: return } ctx.network.direction = k; -- rename: - field: fortinet.firewall.service - target_field: network.protocol - ignore_missing: true -- lowercase: - field: network.protocol - ignore_missing: true - rename: field: fortinet.firewall.error_num target_field: error.code ignore_missing: true -- rename: - field: fortinet.firewall.hostname - target_field: url.domain - ignore_missing: true - rename: field: fortinet.firewall.logdesc target_field: rule.description diff --git a/x-pack/filebeat/module/fortinet/firewall/ingest/pipeline.yml b/x-pack/filebeat/module/fortinet/firewall/ingest/pipeline.yml index c103fd14700..24a47a80abf 100644 --- a/x-pack/filebeat/module/fortinet/firewall/ingest/pipeline.yml +++ b/x-pack/filebeat/module/fortinet/firewall/ingest/pipeline.yml @@ -24,7 +24,7 @@ processors: source: | def fw = ctx?.fortinet?.firewall; if (fw != null) { - fw.entrySet().removeIf(entry -> entry.getValue() == "N/A"); + fw.entrySet().removeIf(entry -> entry.getValue() == "N/A" || entry.getValue() == "undefined"); } - set: field: observer.vendor @@ -35,12 +35,6 @@ processors: - set: field: observer.type value: firewall -- set: - field: event.module - value: fortinet -- set: - field: event.dataset - value: fortinet.firewall - set: field: event.timezone value: "{{fortinet.firewall.tz}}" @@ -198,18 +192,7 @@ processors: ) - remove: field: - - _temp.time - - _temp - message - - syslog5424_sd - - syslog5424_pri - - fortinet.firewall.tz - - fortinet.firewall.date - - fortinet.firewall.devid - - fortinet.firewall.eventtime - - fortinet.firewall.time - - fortinet.firewall.duration - - host ignore_missing: true - pipeline: name: '{< IngestPipeline "event" >}' @@ -220,6 +203,73 @@ processors: - pipeline: name: '{< IngestPipeline "utm" >}' if: "ctx.fortinet?.firewall?.type == 'utm' || ctx.fortinet?.firewall?.type == 'dns'" +- rename: + field: fortinet.firewall.reason + target_field: event.reason + ignore_missing: true +- rename: + field: fortinet.firewall.msg + target_field: message + ignore_missing: true +- rename: + field: fortinet.firewall.proto + target_field: network.iana_number + ignore_missing: true +- script: + lang: painless + ignore_failure: true + if: ctx?.network?.iana_number != null + source: | + if (ctx?.network == null) { + ctx.network = new HashMap(); + } + def iana_number = ctx.network.iana_number; + if (iana_number == '1') { + ctx.network.transport = 'icmp'; + } else if (iana_number == '2') { + ctx.network.transport = 'igmp'; + } else if (iana_number == '6') { + ctx.network.transport = 'tcp'; + } else if (iana_number == '17') { + ctx.network.transport = 'udp'; + } else if (iana_number == '58') { + ctx.network.transport = 'ipv6-icmp'; + } +- rename: + field: fortinet.firewall.group + target_field: source.user.group.name + ignore_missing: true +- uri_parts: + field: fortinet.firewall.url + remove_if_successful: true + ignore_failure: true + if: "ctx.fortinet?.firewall?.url != null" +- set: + field: url.domain + value: "{{fortinet.firewall.hostname}}" + ignore_empty_value: true + if: "ctx?.url?.domain == null" +- rename: + field: fortinet.firewall.service + target_field: network.protocol + ignore_missing: true +- lowercase: + field: network.protocol + ignore_missing: true +- set: + field: network.type + value: ipv4 + if: (ctx.source?.ip != null && ctx.source?.ip.contains('.')) || (ctx.destination?.ip != null && ctx.destination?.ip.contains('.')) +- set: + field: network.type + value: ipv6 + if: ctx.source?.ip != null && ctx.source?.ip.contains(':') || (ctx.destination?.ip != null && ctx.destination?.ip.contains(':')) +- community_id: + ignore_missing: true + ignore_failure: true +- user_agent: + field: fortinet.firewall.agent + ignore_missing: true - convert: field: fortinet.firewall.quotamax type: long @@ -315,30 +365,37 @@ processors: - append: field: related.ip value: "{{source.ip}}" + allow_duplicates: false if: "ctx.source?.ip != null" - append: field: related.ip value: "{{destination.ip}}" + allow_duplicates: false if: "ctx.destination?.ip != null" - append: field: related.user value: "{{source.user.name}}" + allow_duplicates: false if: "ctx.source?.user?.name != null" - append: field: related.user value: "{{destination.user.name}}" + allow_duplicates: false if: "ctx.destination?.user?.name != null" - append: field: related.hosts value: "{{destination.address}}" + allow_duplicates: false if: "ctx.destination?.address != null" - append: field: related.hosts value: "{{source.address}}" + allow_duplicates: false if: "ctx.source?.address != null" - append: field: related.hosts value: "{{dns.question.name}}" + allow_duplicates: false if: "ctx.dns?.question?.name != null" - script: lang: painless @@ -354,6 +411,45 @@ processors: } } } +- remove: + field: + - _temp + - syslog5424_sd + - syslog5424_pri + - fortinet.firewall.tz + - fortinet.firewall.date + - fortinet.firewall.devid + - fortinet.firewall.eventtime + - fortinet.firewall.time + - fortinet.firewall.duration + - host + - fortinet.firewall.hostname + - fortinet.firewall.agent + ignore_missing: true +- script: + lang: painless + description: This script processor iterates over the whole document to remove fields with null values. + 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: - set: field: error.message diff --git a/x-pack/filebeat/module/fortinet/firewall/ingest/traffic.yml b/x-pack/filebeat/module/fortinet/firewall/ingest/traffic.yml index 5166332e2a1..c1fe4c56945 100644 --- a/x-pack/filebeat/module/fortinet/firewall/ingest/traffic.yml +++ b/x-pack/filebeat/module/fortinet/firewall/ingest/traffic.yml @@ -11,32 +11,39 @@ processors: field: event.outcome value: success if: "ctx.fortinet?.firewall?.action != null" +- append: + field: event.type + value: denied + allow_duplicates: false + if: "['block', 'blocked', 'deny', 'close', 'server-rst'].contains(ctx.fortinet?.firewall?.action) || ['block'].contains(ctx.fortinet?.firewall?.utmaction)" +- append: + field: event.type + value: allowed + allow_duplicates: false + if: "(ctx.fortinet?.firewall?.utmaction == null || ['allow'].contains(ctx.fortinet?.firewall?.action)) && !['block', 'blocked', 'deny', 'close', 'server-rst'].contains(ctx.fortinet?.firewall?.action)" - append: field: event.category value: network + allow_duplicates: false - append: field: event.type value: connection + allow_duplicates: false - append: field: event.type value: start + allow_duplicates: false if: "ctx.fortinet?.firewall?.action == 'start'" - append: field: event.type value: end + allow_duplicates: false if: "ctx.fortinet?.firewall?.action != null && ctx.fortinet?.firewall?.action !='start'" - append: field: event.type value: protocol + allow_duplicates: false if: "ctx.fortinet?.firewall?.app != null && ctx.fortinet?.firewall?.action != 'deny'" -- append: - field: event.type - value: allowed - if: "ctx.fortinet?.firewall?.utmaction == null && ctx.fortinet?.firewall?.action != 'deny'" -- append: - field: event.type - value: denied - if: "ctx.fortinet?.firewall?.utmaction == 'block'" - rename: field: fortinet.firewall.dstip target_field: destination.ip @@ -81,10 +88,6 @@ processors: field: fortinet.firewall.dstunauthuser target_field: destination.user.name ignore_missing: true -- rename: - field: fortinet.firewall.group - target_field: source.user.group.name - ignore_missing: true - convert: field: fortinet.firewall.sentbyte target_field: source.bytes @@ -151,10 +154,6 @@ processors: target_field: event.code ignore_missing: true if: "ctx.event?.code == null" -- rename: - field: fortinet.firewall.msg - target_field: message - ignore_missing: true - rename: field: fortinet.firewall.comment target_field: rule.description @@ -185,21 +184,6 @@ processors: pattern: "\\." replacement: "-" ignore_missing: true -- rename: - field: fortinet.firewall.proto - target_field: network.iana_number - ignore_missing: true -- rename: - field: fortinet.firewall.service - target_field: network.protocol - ignore_missing: true -- lowercase: - field: network.protocol - ignore_missing: true -- rename: - field: fortinet.firewall.url - target_field: url.path - ignore_missing: true - remove: field: - fortinet.firewall.dstport diff --git a/x-pack/filebeat/module/fortinet/firewall/ingest/utm.yml b/x-pack/filebeat/module/fortinet/firewall/ingest/utm.yml index a788aa4c8bc..5ff1efe20ec 100644 --- a/x-pack/filebeat/module/fortinet/firewall/ingest/utm.yml +++ b/x-pack/filebeat/module/fortinet/firewall/ingest/utm.yml @@ -3,25 +3,42 @@ processors: - set: field: event.kind value: event +- set: + field: event.kind + value: alert + if: "['virus', 'ips'].contains(ctx.fortinet?.firewall?.subtype) || ctx.fortinet?.firewall?.attack != null" +- set: + field: event.action + value: "{{fortinet.firewall.action}}" + ignore_empty_value: true +- set: + field: event.outcome + value: success + if: "ctx.fortinet?.firewall?.action != null" +- append: + field: event.type + value: allowed + allow_duplicates: false + if: "['pass', 'passthrough', 'exempt'].contains(ctx.fortinet?.firewall?.action)" - append: field: event.type value: denied - if: "['block', 'blocked'].contains(ctx.fortinet?.firewall?.action)" + allow_duplicates: false + if: "['block', 'blocked', 'deny', 'close', 'server-rst', 'dropped'].contains(ctx.fortinet?.firewall?.action)" - append: field: event.type value: info + allow_duplicates: false if: "ctx.fortinet?.firewall?.subtype == 'dns'" -- append: - field: event.type - value: allowed - if: "['pass', 'passthrough'].contains(ctx.fortinet?.firewall?.action)" -- set: - field: event.outcome - value: success - if: "ctx.fortinet?.firewall?.action != null" - append: field: event.category value: network + allow_duplicates: false +- append: + field: event.category + value: intrusion_detection + allow_duplicates: false + if: ctx.fortinet?.firewall?.subtype == 'ips' - rename: field: fortinet.firewall.dstip target_field: destination.ip @@ -61,10 +78,6 @@ processors: field: fortinet.firewall.recipient target_field: destination.user.email ignore_missing: true -- rename: - field: fortinet.firewall.group - target_field: source.user.group.name - ignore_missing: true - rename: field: fortinet.firewall.locip target_field: source.ip @@ -126,10 +139,6 @@ processors: target_field: source.user.email ignore_missing: true if: "ctx.source?.user?.email == null" -- rename: - field: fortinet.firewall.agent - target_field: user_agent.original - ignore_missing: true - rename: field: fortinet.firewall.app target_field: network.application @@ -198,10 +207,6 @@ processors: target_field: event.id ignore_missing: true if: "ctx.event?.id == null" -- rename: - field: fortinet.firewall.eventtype - target_field: event.action - ignore_missing: true - rename: field: fortinet.firewall.filename target_field: file.name @@ -241,10 +246,6 @@ processors: target_field: file.extension ignore_missing: true if: "ctx.file?.extension == null" -- rename: - field: fortinet.firewall.hostname - target_field: url.domain - ignore_missing: true - rename: field: fortinet.firewall.ipaddr target_field: dns.resolved_ip @@ -262,10 +263,6 @@ processors: target_field: event.code ignore_missing: true if: "ctx.event?.code == null" -- rename: - field: fortinet.firewall.msg - target_field: message - ignore_missing: true - rename: field: fortinet.firewall.policy_id target_field: rule.id @@ -281,10 +278,6 @@ processors: target_field: rule.ruleset ignore_missing: true if: "ctx.rule?.ruleset == null" -- rename: - field: fortinet.firewall.proto - target_field: network.iana_number - ignore_missing: true - rename: field: fortinet.firewall.qclass target_field: dns.question.class @@ -297,17 +290,6 @@ processors: field: fortinet.firewall.qtype target_field: dns.question.type ignore_missing: true -- rename: - field: fortinet.firewall.service - target_field: network.protocol - ignore_missing: true -- lowercase: - field: network.protocol - ignore_missing: true -- rename: - field: fortinet.firewall.url - target_field: url.path - ignore_missing: true - rename: field: fortinet.firewall.xid target_field: dns.id diff --git a/x-pack/filebeat/module/fortinet/firewall/test/event.log b/x-pack/filebeat/module/fortinet/firewall/test/event.log new file mode 100644 index 00000000000..48b5d206117 --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/event.log @@ -0,0 +1,27 @@ +<189>date=2020-04-23 time=12:32:48 devname="testswitch3" devid="someotherrouteridagain" logid="0102043014" type="event" subtype="user" level="notice" vd="root" eventtime=1587231168439640874 tz="-0500" logdesc="FSSO logon authentication status" srcip=10.10.10.10 user="elasticouser" server="elasticserver" action="FSSO-logon" msg="FSSO-logon event from FSSO_elasticserver: user elasticouser logged on 10.10.10.10" +<187>date=2020-04-23 time=12:32:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101037124" type="event" subtype="vpn" level="error" vd="root" eventtime=1587231168339114138 tz="-0500" logdesc="IPsec phase 1 error" msg="IPsec phase 1 error" action="negotiate" remip=8.8.4.4 locip=8.8.8.8 remport=500 locport=500 outintf="wan2" cookies="345hkjhdrs87/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="N/A" status="negotiate_error" reason="peer SA proposal not match local policy" peer_notif="NOT-APPLICABLE" +<189>date=2020-04-23 time=12:32:31 devname="testswitch3" devid="someotherrouteridagain" logid="0101037127" type="event" subtype="vpn" level="notice" vd="root" eventtime=1587231151628960857 tz="-0500" logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action="negotiate" remip=8.4.5.4 locip=9.9.9.9 remport=500 locport=500 outintf="wan1" cookies="df868dsg876d/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="elasticvpn" status="success" init="local" mode="main" dir="outbound" stage=1 role="initiator" result="OK" +<189>date=2020-04-23 time=14:32:09 devname="testswitch3" devid="someotherrouteridagain" logid="0100040704" type="event" subtype="system" level="notice" vd="root" eventtime=1587231129938795255 tz="-0300" logdesc="System performance statistics" action="perf-stats" cpu=0 mem=10 totalsession=23 disk=0 bandwidth="23/4" setuprate=0 disklograte=0 fazlograte=0 freediskstorage=331 sysuptime=25170 msg="Performance statistics: average CPU: 0, memory: 23, concurrent sessions: 20, setup-rate: 0" +<189>date=2020-04-23 time=12:32:09 devname="testswitch3" devid="someotherrouteridagain" logid="0102043039" type="event" subtype="user" level="notice" vd="root" eventtime=1587231130109462858 tz="-0500" logdesc="Authentication logon" srcip=10.10.10.10 user="elastiiiuser" authserver="FSSO_elastiauth" action="auth-logon" status="logon" msg="User elastiiiuser added to auth logon" +<189>date=2020-04-23 time=12:32:00 devname="testswitch3" devid="someotherrouteridagain" logid="0101037127" type="event" subtype="vpn" level="notice" vd="root" eventtime=1587231120608961118 tz="-0500" logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action="negotiate" remip=8.8.5.4 locip=7.6.3.4 remport=500 locport=500 outintf="wan1" cookies="345khj34566/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="testvpn" status="success" init="local" mode="main" dir="outbound" stage=1 role="initiator" result="OK" +<189>date=2020-04-23 time=14:24:13 devname="testswitch3" devid="someotherrouteridagain" logid="0100041006" type="event" subtype="system" level="notice" vd="root" eventtime=1587230655301863513 tz="-0300" logdesc="FortiSandbox AV database updated" version="1.522479" msg="FortiSandbox AV database updated" +<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0107045057" type="event" subtype="endpoint" level="information" vd="root" eventtime=1587230627558979735 tz="-0500" logdesc="FortiClient connection added" action="add" status="success" license_limit="unlimited" used_for_type=3 connection_type="sslvpn" count=2 user="elastico" ip=172.16.0.2 name="somerouter" fctuid="645234fdd01F885824F764" msg="Add a FortiClient Connection." +<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101039943" type="event" subtype="vpn" level="information" vd="root" eventtime=1587230627334405765 tz="-0500" logdesc="SSL VPN new connection" action="ssl-new-con" tunneltype="ssl" tunnelid=2 remip=8.8.8.6 user="N/A" group="N/A" dst_host="N/A" reason="N/A" msg="SSL new connection" +<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101039947" type="event" subtype="vpn" level="information" vd="root" eventtime=1587230627698970007 tz="-0500" logdesc="SSL VPN tunnel up" action="tunnel-up" tunneltype="ssl-tunnel" tunnelid=2345 remip=8.8.5.4 tunnelip=10.10.10.10 user="someuser" group="somegroup" dst_host="N/A" reason="tunnel established" msg="SSL tunnel established" +<189>date=2020-04-23 time=14:16:42 devname="testswitch3" devid="someotherrouteridagain" logid="0102043015" type="event" subtype="user" level="notice" vd="root" eventtime=1587230204674924332 tz="-0300" logdesc="FSSO log off authentication status" srcip=192.168.1.1 user="elasticadmin" server="FSSO_somefssoserver" action="FSSO-logoff" msg="FSSO-logoff event from FSSO_somefssoserver: user elasticuser logged off 1192.168.1.1" +<189>date=2020-04-23 time=12:16:02 devname="testswitch3" devid="someotherrouteridagain" logid="0100022915" type="event" subtype="system" level="notice" vd="root" eventtime=1587230163121116383 tz="-0500" logdesc="FortiCloud server connected" server="9.9.9.9" action="connect" msg="FortiCloud 9.9.9.9 server is connected" +<189>date=2020-04-23 time=12:16:02 devname="testswitch3" devid="someotherrouteridagain" logid="0100022913" type="event" subtype="system" level="notice" vd="root" eventtime=1587230163375149856 tz="-0500" logdesc="FortiCloud server disconnected" server="4.4.4.4" action="disconnect" reason="connection reset" msg="FortiCloud 4.4.4.4 server is disconnected" +<190>date=2020-11-02 time=08:11:38 devname=testfirewall devid=newrouterid logid=0101037127 type="event" subtype=vpn level=notice vd=root logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action=negotiate remip=8.8.8.8 locip=10.10.10.10 remport=500 locport=500 outintf="port1" cookies="125cbf9ee8349965/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="P1_Test" status=success init=local mode=aggressive dir=outbound stage=1 role=initiator result=OK +<190>date=2019-05-13 time=11:20:54 logid="0100032001" type="event" subtype="system" level="information" vd="vdom1" eventtime=1557771654587081441 logdesc="Admin login successful" sn="1557771654" user="admin" ui="ssh(172.16.200.254)" method="ssh" srcip=172.16.200.254 dstip=172.16.200.2 action="login" status="success" reason="none" profile="super_admin" msg="Administrator admin logged in successfully from ssh(172.16.200.254)" +<190>date=2019-05-13 time=14:21:42 logid="0101037127" type="event" subtype="vpn" level="notice" vd="root" eventtime=1557782502722231889 logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action="negotiate" remip=50.1.1.101 locip=50.1.1.100 remport=500 locport=500 outintf="port14" cookies="9091f4d4837ea71c/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="test" status="success" init="local" mode="main" dir="outbound" stage=1 role="initiator" result="OK" +<190>date=2019-05-13 time=15:55:56 logid="0102043008" type="event" subtype="user" level="notice" vd="root" eventtime=1557788156913809277 logdesc="Authentication success" srcip=10.1.100.11 dstip=172.16.200.55 policyid=1 interface="port10" user="bob" group="local-group1" authproto="TELNET(10.1.100.11)" action="authentication" status="success" reason="N/A" msg="User bob succeeded in authentication" +<189>date=2019-05-14 time=08:32:13 logid="0107045057" type="event" subtype="endpoint" level="information" vd="root" eventtime=1557847933900764210 logdesc="FortiClient connection added" action="add" status="success" license_limit="unlimited" used_for_type=4 connection_type="sslvpn" count=1 user="skubas" ip=172.18.64.250 name="VAN-200957-PC" fctuid="52C66FE08F724FE0B116DAD5062C96CD" msg="Add a FortiClient Connection." +<189>date=2019-05-14 time=08:19:38 logid="0107045058" type="event" subtype="endpoint" level="information" vd="root" eventtime=1557847179037488154 logdesc="FortiClient connection closed" action="close" status="success" license_limit="unlimited" used_for_type=5 connection_type="sslvpn" count=1 user="skubas" ip=172.18.64.250 name="VAN-200957-PC" fctuid="52C66FE08F724FE0B116DAD5062C96CD" msg="Close a FortiClient Connection." +<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880370858 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="FCTEMS0000011111_AV-Running" msg="Updated tag FCTEMS0000011111_AV-Running." +<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880455433 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="MAC_FCTEMS0000011111_AV-Running" msg="Updated tag MAC_FCTEMS0000011111_AV-Running." +<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880744919 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="FCTEMS0000011111_Connected-to-EMS" msg="Updated tag FCTEMS0000011111_Connected-to-EMS." +<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880784143 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="MAC_FCTEMS0000011111_Connected-to-EMS" msg="Updated tag MAC_FCTEMS0000011111_Connected-to-EMS." +<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900027938 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="FCTEMS0000011111_AV-Running" msg="Updated tag FCTEMS0000011111_AV-Running." +<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900167367 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="MAC_FCTEMS0000011111_AV-Running" msg="Updated tag MAC_FCTEMS0000011111_AV-Running." +<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900749585 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="FCTEMS0000011111_Connected-to-EMS" msg="Updated tag FCTEMS0000011111_Connected-to-EMS." +<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900961834 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="MAC_FCTEMS0000011111_Connected-to-EMS" msg="Updated tag MAC_FCTEMS0000011111_Connected-to-EMS." diff --git a/x-pack/filebeat/module/fortinet/firewall/test/event.log-expected.json b/x-pack/filebeat/module/fortinet/firewall/test/event.log-expected.json new file mode 100644 index 00000000000..12a32029605 --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/event.log-expected.json @@ -0,0 +1,1179 @@ +[ + { + "@timestamp": "2020-04-23T12:32:48.000-05:00", + "event.action": "FSSO-logon", + "event.category": [ + "authentication" + ], + "event.code": "0102043014", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:32:48.439-05:00", + "event.timezone": "-0500", + "event.type": [ + "start", + "user" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "FSSO-logon", + "fortinet.firewall.server": "elasticserver", + "fortinet.firewall.subtype": "user", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 0, + "message": "FSSO-logon event from FSSO_elasticserver: user elasticouser logged on 10.10.10.10", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.10.10.10" + ], + "related.user": [ + "elasticouser" + ], + "rule.description": "FSSO logon authentication status", + "service.type": "fortinet", + "source.ip": "10.10.10.10", + "source.user.name": "elasticouser", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:32:47.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.4.4", + "destination.port": 500, + "event.action": "negotiate", + "event.category": [ + "network" + ], + "event.code": "0101037124", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "failure", + "event.reason": "peer SA proposal not match local policy", + "event.start": "2020-04-18T12:32:48.339-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "negotiate", + "fortinet.firewall.cookies": "345hkjhdrs87/0000000000000000", + "fortinet.firewall.outintf": "wan2", + "fortinet.firewall.peer_notif": "NOT-APPLICABLE", + "fortinet.firewall.status": "negotiate_error", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "error", + "log.offset": 413, + "message": "IPsec phase 1 error", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "8.8.4.4", + "8.8.8.8" + ], + "rule.description": "IPsec phase 1 error", + "service.type": "fortinet", + "source.as.number": 15169, + "source.as.organization.name": "Google LLC", + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 37.751, + "source.geo.location.lon": -97.822, + "source.ip": "8.8.8.8", + "source.port": 500, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:32:31.000-05:00", + "destination.as.number": 3356, + "destination.as.organization.name": "Level 3 Parent, LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.4.5.4", + "destination.port": 500, + "event.action": "negotiate", + "event.category": [ + "network" + ], + "event.code": "0101037127", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:32:31.628-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "negotiate", + "fortinet.firewall.cookies": "df868dsg876d/0000000000000000", + "fortinet.firewall.init": "local", + "fortinet.firewall.mode": "main", + "fortinet.firewall.outintf": "wan1", + "fortinet.firewall.result": "OK", + "fortinet.firewall.role": "initiator", + "fortinet.firewall.stage": "1", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vpntunnel": "elasticvpn", + "input.type": "log", + "log.level": "notice", + "log.offset": 981, + "message": "progress IPsec phase 1", + "network.direction": "outbound", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "8.4.5.4", + "9.9.9.9" + ], + "rule.description": "Progress IPsec phase 1", + "service.type": "fortinet", + "source.as.number": 19281, + "source.as.organization.name": "Quad9", + "source.geo.continent_name": "Europe", + "source.geo.country_iso_code": "FR", + "source.geo.country_name": "France", + "source.geo.location.lat": 48.8582, + "source.geo.location.lon": 2.3387, + "source.ip": "9.9.9.9", + "source.port": 500, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T14:32:09.000-03:00", + "event.action": "perf-stats", + "event.category": [ + "host" + ], + "event.code": "0100040704", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T14:32:09.938-03:00", + "event.timezone": "-0300", + "event.type": [ + "info" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "perf-stats", + "fortinet.firewall.bandwidth": "23/4", + "fortinet.firewall.cpu": "0", + "fortinet.firewall.disk": "0", + "fortinet.firewall.disklograte": "0", + "fortinet.firewall.fazlograte": "0", + "fortinet.firewall.freediskstorage": "331", + "fortinet.firewall.mem": 10, + "fortinet.firewall.setuprate": "0", + "fortinet.firewall.subtype": "system", + "fortinet.firewall.sysuptime": "25170", + "fortinet.firewall.totalsession": "23", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 1555, + "message": "Performance statistics: average CPU: 0, memory: 23, concurrent sessions: 20, setup-rate: 0", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "System performance statistics", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:32:09.000-05:00", + "event.action": "auth-logon", + "event.category": [ + "authentication" + ], + "event.code": "0102043039", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:32:10.109-05:00", + "event.timezone": "-0500", + "event.type": [ + "start", + "user" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "auth-logon", + "fortinet.firewall.authserver": "FSSO_elastiauth", + "fortinet.firewall.status": "logon", + "fortinet.firewall.subtype": "user", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 2045, + "message": "User elastiiiuser added to auth logon", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.10.10.10" + ], + "related.user": [ + "elastiiiuser" + ], + "rule.description": "Authentication logon", + "service.type": "fortinet", + "source.ip": "10.10.10.10", + "source.user.name": "elastiiiuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:32:00.000-05:00", + "destination.as.number": 3356, + "destination.as.organization.name": "Level 3 Parent, LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.5.4", + "destination.port": 500, + "event.action": "negotiate", + "event.category": [ + "network" + ], + "event.code": "0101037127", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:32:00.608-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "negotiate", + "fortinet.firewall.cookies": "345khj34566/0000000000000000", + "fortinet.firewall.init": "local", + "fortinet.firewall.mode": "main", + "fortinet.firewall.outintf": "wan1", + "fortinet.firewall.result": "OK", + "fortinet.firewall.role": "initiator", + "fortinet.firewall.stage": "1", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vpntunnel": "testvpn", + "input.type": "log", + "log.level": "notice", + "log.offset": 2423, + "message": "progress IPsec phase 1", + "network.direction": "outbound", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "7.6.3.4", + "8.8.5.4" + ], + "rule.description": "Progress IPsec phase 1", + "service.type": "fortinet", + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 37.751, + "source.geo.location.lon": -97.822, + "source.ip": "7.6.3.4", + "source.port": 500, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T14:24:13.000-03:00", + "event.code": "0100041006", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T14:24:15.301-03:00", + "event.timezone": "-0300", + "fileset.name": "firewall", + "fortinet.firewall.subtype": "system", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "fortinet.firewall.version": "1.522479", + "input.type": "log", + "log.level": "notice", + "log.offset": 2993, + "message": "FortiSandbox AV database updated", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "FortiSandbox AV database updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:23:47.000-05:00", + "event.action": "add", + "event.code": "0107045057", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T12:23:47.558-05:00", + "event.timezone": "-0500", + "fileset.name": "firewall", + "fortinet.firewall.action": "add", + "fortinet.firewall.connection_type": "sslvpn", + "fortinet.firewall.count": "2", + "fortinet.firewall.fctuid": "645234fdd01F885824F764", + "fortinet.firewall.ip": "172.16.0.2", + "fortinet.firewall.license_limit": "unlimited", + "fortinet.firewall.name": "somerouter", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "endpoint", + "fortinet.firewall.type": "event", + "fortinet.firewall.used_for_type": "3", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 3297, + "message": "Add a FortiClient Connection.", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.user": [ + "elastico" + ], + "rule.description": "FortiClient connection added", + "service.type": "fortinet", + "source.user.name": "elastico", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:23:47.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.6", + "event.action": "ssl-new-con", + "event.category": [ + "network" + ], + "event.code": "0101039943", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T12:23:47.334-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "ssl-new-con", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.tunnelid": "2", + "fortinet.firewall.tunneltype": "ssl", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 3767, + "message": "SSL new connection", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "8.8.8.6" + ], + "rule.description": "SSL VPN new connection", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:23:47.000-05:00", + "destination.as.number": 3356, + "destination.as.organization.name": "Level 3 Parent, LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.5.4", + "event.action": "tunnel-up", + "event.category": [ + "network" + ], + "event.code": "0101039947", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.reason": "tunnel established", + "event.start": "2020-04-18T12:23:47.698-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "tunnel-up", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.tunnelid": "2345", + "fortinet.firewall.tunnelip": "10.10.10.10", + "fortinet.firewall.tunneltype": "ssl-tunnel", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 4144, + "message": "SSL tunnel established", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "8.8.5.4" + ], + "related.user": [ + "someuser" + ], + "rule.description": "SSL VPN tunnel up", + "service.type": "fortinet", + "source.user.group.name": "somegroup", + "source.user.name": "someuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T14:16:42.000-03:00", + "event.action": "FSSO-logoff", + "event.category": [ + "authentication" + ], + "event.code": "0102043015", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T14:16:44.674-03:00", + "event.timezone": "-0300", + "event.type": [ + "end", + "user" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "FSSO-logoff", + "fortinet.firewall.server": "FSSO_somefssoserver", + "fortinet.firewall.subtype": "user", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 4575, + "message": "FSSO-logoff event from FSSO_somefssoserver: user elasticuser logged off 1192.168.1.1", + "network.type": "ipv4", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.1.1" + ], + "related.user": [ + "elasticadmin" + ], + "rule.description": "FSSO log off authentication status", + "service.type": "fortinet", + "source.ip": "192.168.1.1", + "source.user.name": "elasticadmin", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:16:02.000-05:00", + "event.action": "connect", + "event.code": "0100022915", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T12:16:03.121-05:00", + "event.timezone": "-0500", + "fileset.name": "firewall", + "fortinet.firewall.action": "connect", + "fortinet.firewall.server": "9.9.9.9", + "fortinet.firewall.subtype": "system", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 5000, + "message": "FortiCloud 9.9.9.9 server is connected", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "FortiCloud server connected", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:16:02.000-05:00", + "event.action": "disconnect", + "event.code": "0100022913", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.reason": "connection reset", + "event.start": "2020-04-18T12:16:03.375-05:00", + "event.timezone": "-0500", + "fileset.name": "firewall", + "fortinet.firewall.action": "disconnect", + "fortinet.firewall.server": "4.4.4.4", + "fortinet.firewall.subtype": "system", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 5320, + "message": "FortiCloud 4.4.4.4 server is disconnected", + "observer.name": "testswitch3", + "observer.product": "Fortigate", + "observer.serial_number": "someotherrouteridagain", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "FortiCloud server disconnected", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-11-02T08:11:38.000Z", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 500, + "event.action": "negotiate", + "event.category": [ + "network" + ], + "event.code": "0101037127", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "negotiate", + "fortinet.firewall.cookies": "125cbf9ee8349965/0000000000000000", + "fortinet.firewall.init": "local", + "fortinet.firewall.mode": "aggressive", + "fortinet.firewall.outintf": "port1", + "fortinet.firewall.result": "OK", + "fortinet.firewall.role": "initiator", + "fortinet.firewall.stage": "1", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vpntunnel": "P1_Test", + "input.type": "log", + "log.level": "notice", + "log.offset": 5675, + "message": "progress IPsec phase 1", + "network.direction": "outbound", + "network.type": "ipv4", + "observer.name": "testfirewall", + "observer.product": "Fortigate", + "observer.serial_number": "newrouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.10.10.10", + "8.8.8.8" + ], + "rule.description": "Progress IPsec phase 1", + "service.type": "fortinet", + "source.ip": "10.10.10.10", + "source.port": 500, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-13T11:20:54.000Z", + "destination.ip": "172.16.200.2", + "event.action": "login", + "event.code": "0100032001", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.reason": "none", + "event.start": "2019-05-13T18:20:54.587Z", + "fileset.name": "firewall", + "fortinet.firewall.action": "login", + "fortinet.firewall.method": "ssh", + "fortinet.firewall.profile": "super_admin", + "fortinet.firewall.sn": "1557771654", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "system", + "fortinet.firewall.type": "event", + "fortinet.firewall.ui": "ssh(172.16.200.254)", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "information", + "log.offset": 6184, + "message": "Administrator admin logged in successfully from ssh(172.16.200.254)", + "network.type": "ipv4", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "172.16.200.2", + "172.16.200.254" + ], + "related.user": [ + "admin" + ], + "rule.description": "Admin login successful", + "service.type": "fortinet", + "source.ip": "172.16.200.254", + "source.user.name": "admin", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-13T14:21:42.000Z", + "destination.as.number": 7065, + "destination.as.organization.name": "Sonoma Interconnect", + "destination.geo.city_name": "North Highlands", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 38.6741, + "destination.geo.location.lon": -121.3768, + "destination.geo.region_iso_code": "US-CA", + "destination.geo.region_name": "California", + "destination.ip": "50.1.1.101", + "destination.port": 500, + "event.action": "negotiate", + "event.category": [ + "network" + ], + "event.code": "0101037127", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-13T21:21:42.722Z", + "event.type": [ + "connection" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "negotiate", + "fortinet.firewall.cookies": "9091f4d4837ea71c/0000000000000000", + "fortinet.firewall.init": "local", + "fortinet.firewall.mode": "main", + "fortinet.firewall.outintf": "port14", + "fortinet.firewall.result": "OK", + "fortinet.firewall.role": "initiator", + "fortinet.firewall.stage": "1", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "vpn", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vpntunnel": "test", + "input.type": "log", + "log.level": "notice", + "log.offset": 6611, + "message": "progress IPsec phase 1", + "network.direction": "outbound", + "network.type": "ipv4", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "50.1.1.100", + "50.1.1.101" + ], + "rule.description": "Progress IPsec phase 1", + "service.type": "fortinet", + "source.as.number": 7065, + "source.as.organization.name": "Sonoma Interconnect", + "source.geo.city_name": "North Highlands", + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 38.6741, + "source.geo.location.lon": -121.3768, + "source.geo.region_iso_code": "US-CA", + "source.geo.region_name": "California", + "source.ip": "50.1.1.100", + "source.port": 500, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-13T15:55:56.000Z", + "destination.ip": "172.16.200.55", + "event.action": "authentication", + "event.category": [ + "authentication" + ], + "event.code": "0102043008", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2019-05-13T22:55:56.913Z", + "fileset.name": "firewall", + "fortinet.firewall.action": "authentication", + "fortinet.firewall.authproto": "TELNET(10.1.100.11)", + "fortinet.firewall.interface": "port10", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "user", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 7127, + "message": "User bob succeeded in authentication", + "network.type": "ipv4", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.55" + ], + "related.user": [ + "bob" + ], + "rule.description": "Authentication success", + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.11", + "source.user.group.name": "local-group1", + "source.user.name": "bob", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-14T08:32:13.000Z", + "event.action": "add", + "event.code": "0107045057", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2019-05-14T15:32:13.900Z", + "fileset.name": "firewall", + "fortinet.firewall.action": "add", + "fortinet.firewall.connection_type": "sslvpn", + "fortinet.firewall.count": "1", + "fortinet.firewall.fctuid": "52C66FE08F724FE0B116DAD5062C96CD", + "fortinet.firewall.ip": "172.18.64.250", + "fortinet.firewall.license_limit": "unlimited", + "fortinet.firewall.name": "VAN-200957-PC", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "endpoint", + "fortinet.firewall.type": "event", + "fortinet.firewall.used_for_type": "4", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 7526, + "message": "Add a FortiClient Connection.", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.user": [ + "skubas" + ], + "rule.description": "FortiClient connection added", + "service.type": "fortinet", + "source.user.name": "skubas", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-14T08:19:38.000Z", + "event.action": "close", + "event.code": "0107045058", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2019-05-14T15:19:39.037Z", + "fileset.name": "firewall", + "fortinet.firewall.action": "close", + "fortinet.firewall.connection_type": "sslvpn", + "fortinet.firewall.count": "1", + "fortinet.firewall.fctuid": "52C66FE08F724FE0B116DAD5062C96CD", + "fortinet.firewall.ip": "172.18.64.250", + "fortinet.firewall.license_limit": "unlimited", + "fortinet.firewall.name": "VAN-200957-PC", + "fortinet.firewall.status": "success", + "fortinet.firewall.subtype": "endpoint", + "fortinet.firewall.type": "event", + "fortinet.firewall.used_for_type": "5", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 7946, + "message": "Close a FortiClient Connection.", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.user": [ + "skubas" + ], + "rule.description": "FortiClient connection closed", + "service.type": "fortinet", + "source.user.name": "skubas", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.880+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "FCTEMS0000011111_AV-Running", + "fortinet.firewall.fctemssn": "FCTEMS0000011111", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 8371, + "message": "Updated tag FCTEMS0000011111_AV-Running.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EEF34CD12AB", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.880+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_AV-Running", + "fortinet.firewall.fctemssn": "FCTEMS0000011111", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 8717, + "message": "Updated tag MAC_FCTEMS0000011111_AV-Running.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EEF34CD12AB", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.880+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "FCTEMS0000011111_Connected-to-EMS", + "fortinet.firewall.fctemssn": "FCTEMS0000011111", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 9071, + "message": "Updated tag FCTEMS0000011111_Connected-to-EMS.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EEF34CD12AB", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.880+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_Connected-to-EMS", + "fortinet.firewall.fctemssn": "FCTEMS0000011111", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 9429, + "message": "Updated tag MAC_FCTEMS0000011111_Connected-to-EMS.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EEF34CD12AB", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.900+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "FCTEMS0000011111_AV-Running", + "fortinet.firewall.fctemssn": "(null)", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 9795, + "message": "Updated tag FCTEMS0000011111_AV-Running.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EAB12CD34EF", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.900+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_AV-Running", + "fortinet.firewall.fctemssn": "(null)", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 10131, + "message": "Updated tag MAC_FCTEMS0000011111_AV-Running.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EAB12CD34EF", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.900+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "FCTEMS0000011111_Connected-to-EMS", + "fortinet.firewall.fctemssn": "(null)", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 10475, + "message": "Updated tag FCTEMS0000011111_Connected-to-EMS.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EAB12CD34EF", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-05-07T08:31:14.000+01:00", + "event.code": "0112053203", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2021-05-07T08:31:14.900+01:00", + "event.timezone": "+0100", + "fileset.name": "firewall", + "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_Connected-to-EMS", + "fortinet.firewall.fctemssn": "(null)", + "fortinet.firewall.subtype": "connector", + "fortinet.firewall.type": "event", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 10823, + "message": "Updated tag MAC_FCTEMS0000011111_Connected-to-EMS.", + "observer.name": "firewall", + "observer.product": "Fortigate", + "observer.serial_number": "FG201EAB12CD34EF", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "rule.description": "Dynamic address updated", + "service.type": "fortinet", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + } +] \ No newline at end of file diff --git a/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log b/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log deleted file mode 100644 index 9cee313e6eb..00000000000 --- a/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log +++ /dev/null @@ -1,40 +0,0 @@ -<188>date=2020-04-23 time=12:17:48 devname="testswitch1" devid="somerouterid" logid="0316013056" type="utm" subtype="webfilter" eventtype="ftgd_blk" level="warning" vd="root" eventtime=1587230269052907555 tz="-0500" policyid=100602 sessionid=1234 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 srcport=61930 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=443 dstintf="wan1" dstintfrole="wan" proto=6 service="HTTPS" hostname="elastic.co" profile="elasticruleset" action="blocked" reqtype="direct" url="/config/" sentbyte=1152 rcvdbyte=1130 direction="outgoing" msg="URL belongs to a denied category in policy" method="domain" cat=76 catdesc="Internet Telephony" -<189>date=2020-04-23 time=01:16:08 devname="testswitch1" devid="somerouterid" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="OPERATIONAL" eventtime=1592961368 srcip=10.10.10.10 srcport=60899 srcintf="srcintfname" srcintfrole="lan" dstip=8.8.8.8 dstport=161 dstintf="dstintfname" dstintfrole="lan" sessionid=155313 proto=17 action="deny" policyid=0 policytype="policy" service="SNMP" dstcountry="Reserved" srccountry="Reserved" trandisp="noop" duration=0 sentbyte=0 rcvdbyte=0 sentpkt=0 appcat="unscanned" crscore=30 craction=131072 crlevel="high" -<189>date=2020-04-23 time=12:17:45 devname="testswitch1" devid="somerouterid" logid="0317013312" type="utm" subtype="webfilter" eventtype="ftgd_allow" level="notice" vd="root" eventtime=1587230266314799756 tz="-0500" policyid=38 sessionid=543234 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 srcport=65236 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=443 dstintf="wan1" dstintfrole="wan" proto=6 service="HTTPS" hostname="elastic.co" profile="elasticruleset" action="passthrough" reqtype="direct" url="/" sentbyte=3545 rcvdbyte=6812 direction="outgoing" msg="URL belongs to an allowed category in policy" method="domain" cat=23 catdesc="Web-based Email" -<190>date=2020-04-23 time=13:17:35 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1587230255061492894 tz="-0400" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=59790 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=12 sessionid=453234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.co" incidentserialno=23465 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="test.elastic.co" -<190>date=2020-04-23 time=13:17:35 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1591788391 tz="-0400" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=59790 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=12 sessionid=453234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.co" incidentserialno=23465 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="test.elastic.co" -<189>date=2020-04-23 time=12:17:29 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230249360109339 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=53430 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="test" xid=2234 qname="elastic.example.com" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8" msg="Domain is monitored" action="pass" cat=23 catdesc="Web-based Email" -<189>date=2020-04-23 time=12:17:29 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230249360109339 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=53430 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="test" xid=2234 qname="elastic.example.com" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8, 8.8.4.4" msg="Domain is monitored" action="pass" cat=23 catdesc="Web-based Email" -<190>date=2020-04-23 time=12:17:11 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1587230232148674303 tz="-0500" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=63012 dstport=443 srcintf="port1" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=100602 sessionid=543234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.no" incidentserialno=54323 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" -<189>date=2020-04-23 time=12:17:04 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230224712900694 tz="-0500" policyid=26 sessionid=5432 srcip=192.168.2.1 srcport=54438 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="elastictest" xid=2352 qname="elastic.co" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8" msg="Domain is monitored" action="pass" cat=93 catdesc="Remote Access" -<190>date=2020-04-23 time=12:17:12 devname="testswitch1" devid="somerouterid" logid="1500054000" type="utm" subtype="dns" eventtype="dns-query" level="information" vd="root" eventtime=1587230232658642672 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=54788 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="elastictest" xid=235 qname="elastic.co" qtype="A" qtypeval=1 qclass="IN" -<189>date=2020-04-23 time=13:15:18 devname="testswitch2" devid="someotherid" logid="1700062001" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="notice" vd="root" eventtime=1587230118838592454 tz="-0400" policyid=12 sessionid=42346234 service="HTTPS" user="elasticuser2" group="elasticgroup2" profile="somecerts" srcip=192.168.2.1 srcport=59726 dstip=8.8.4.4 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 action="passthrough" msg="Server certificate passed" reason="untrusted-cert" -<189>date=2020-04-23 time=12:32:48 devname="testswitch3" devid="someotherrouteridagain" logid="0102043014" type="event" subtype="user" level="notice" vd="root" eventtime=1587231168439640874 tz="-0500" logdesc="FSSO logon authentication status" srcip=10.10.10.10 user="elasticouser" server="elasticserver" action="FSSO-logon" msg="FSSO-logon event from FSSO_elasticserver: user elasticouser logged on 10.10.10.10" -<187>date=2020-04-23 time=12:32:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101037124" type="event" subtype="vpn" level="error" vd="root" eventtime=1587231168339114138 tz="-0500" logdesc="IPsec phase 1 error" msg="IPsec phase 1 error" action="negotiate" remip=8.8.4.4 locip=8.8.8.8 remport=500 locport=500 outintf="wan2" cookies="345hkjhdrs87/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="N/A" status="negotiate_error" reason="peer SA proposal not match local policy" peer_notif="NOT-APPLICABLE" -<189>date=2020-04-23 time=12:32:31 devname="testswitch3" devid="someotherrouteridagain" logid="0101037127" type="event" subtype="vpn" level="notice" vd="root" eventtime=1587231151628960857 tz="-0500" logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action="negotiate" remip=8.4.5.4 locip=9.9.9.9 remport=500 locport=500 outintf="wan1" cookies="df868dsg876d/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="elasticvpn" status="success" init="local" mode="main" dir="outbound" stage=1 role="initiator" result="OK" -<189>date=2020-04-23 time=14:32:09 devname="testswitch3" devid="someotherrouteridagain" logid="0100040704" type="event" subtype="system" level="notice" vd="root" eventtime=1587231129938795255 tz="-0300" logdesc="System performance statistics" action="perf-stats" cpu=0 mem=10 totalsession=23 disk=0 bandwidth="23/4" setuprate=0 disklograte=0 fazlograte=0 freediskstorage=331 sysuptime=25170 msg="Performance statistics: average CPU: 0, memory: 23, concurrent sessions: 20, setup-rate: 0" -<189>date=2020-04-23 time=12:32:09 devname="testswitch3" devid="someotherrouteridagain" logid="0102043039" type="event" subtype="user" level="notice" vd="root" eventtime=1587231130109462858 tz="-0500" logdesc="Authentication logon" srcip=10.10.10.10 user="elastiiiuser" authserver="FSSO_elastiauth" action="auth-logon" status="logon" msg="User elastiiiuser added to auth logon" -<189>date=2020-04-23 time=12:32:00 devname="testswitch3" devid="someotherrouteridagain" logid="0101037127" type="event" subtype="vpn" level="notice" vd="root" eventtime=1587231120608961118 tz="-0500" logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action="negotiate" remip=8.8.5.4 locip=7.6.3.4 remport=500 locport=500 outintf="wan1" cookies="345khj34566/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="testvpn" status="success" init="local" mode="main" dir="outbound" stage=1 role="initiator" result="OK" -<189>date=2020-04-23 time=14:24:13 devname="testswitch3" devid="someotherrouteridagain" logid="0100041006" type="event" subtype="system" level="notice" vd="root" eventtime=1587230655301863513 tz="-0300" logdesc="FortiSandbox AV database updated" version="1.522479" msg="FortiSandbox AV database updated" -<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0107045057" type="event" subtype="endpoint" level="information" vd="root" eventtime=1587230627558979735 tz="-0500" logdesc="FortiClient connection added" action="add" status="success" license_limit="unlimited" used_for_type=3 connection_type="sslvpn" count=2 user="elastico" ip=172.16.0.2 name="somerouter" fctuid="645234fdd01F885824F764" msg="Add a FortiClient Connection." -<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101039943" type="event" subtype="vpn" level="information" vd="root" eventtime=1587230627334405765 tz="-0500" logdesc="SSL VPN new connection" action="ssl-new-con" tunneltype="ssl" tunnelid=2 remip=8.8.8.6 user="N/A" group="N/A" dst_host="N/A" reason="N/A" msg="SSL new connection" -<190>date=2020-04-23 time=12:23:47 devname="testswitch3" devid="someotherrouteridagain" logid="0101039947" type="event" subtype="vpn" level="information" vd="root" eventtime=1587230627698970007 tz="-0500" logdesc="SSL VPN tunnel up" action="tunnel-up" tunneltype="ssl-tunnel" tunnelid=2345 remip=8.8.5.4 tunnelip=10.10.10.10 user="someuser" group="somegroup" dst_host="N/A" reason="tunnel established" msg="SSL tunnel established" -<189>date=2020-04-23 time=14:16:42 devname="testswitch3" devid="someotherrouteridagain" logid="0102043015" type="event" subtype="user" level="notice" vd="root" eventtime=1587230204674924332 tz="-0300" logdesc="FSSO log off authentication status" srcip=192.168.1.1 user="elasticadmin" server="FSSO_somefssoserver" action="FSSO-logoff" msg="FSSO-logoff event from FSSO_somefssoserver: user elasticuser logged off 1192.168.1.1" -<189>date=2020-04-23 time=12:16:02 devname="testswitch3" devid="someotherrouteridagain" logid="0100022915" type="event" subtype="system" level="notice" vd="root" eventtime=1587230163121116383 tz="-0500" logdesc="FortiCloud server connected" server="9.9.9.9" action="connect" msg="FortiCloud 9.9.9.9 server is connected" -<189>date=2020-04-23 time=12:16:02 devname="testswitch3" devid="someotherrouteridagain" logid="0100022913" type="event" subtype="system" level="notice" vd="root" eventtime=1587230163375149856 tz="-0500" logdesc="FortiCloud server disconnected" server="4.4.4.4" action="disconnect" reason="connection reset" msg="FortiCloud 4.4.4.4 server is disconnected" -<188>date=2020-04-23 time=12:14:09 devname="newfirewall" devid="newrouterid" logid="0000000011" type="traffic" subtype="forward" level="warning" vd="root" eventtime=1587230049761513222 tz="-0500" srcip=192.168.1.6 srcport=53438 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" sessionid=435234 proto=17 action="dns" policyid=26 policytype="policy" poluuid="2345de-b143-52134d8-6654f-4654sdfg16f431" policyname="elasticnewruleset" service="DNS" dstcountry="Netherlands" srccountry="Reserved" appcat="unscanned" crscore=5 craction=54144 crlevel="low" -<189>date=2020-04-23 time=12:11:51 devname="newfirewall" devid="newrouterid" logid="0000000020" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1587229911390385486 tz="-0500" srcip=192.168.10.10 srcport=6000 srcintf="port1" srcintfrole="lan" dstip=8.6.4.7 dstport=6000 dstintf="wan1" dstintfrole="wan" sessionid=4352 proto=17 action="accept" policyid=3426 policytype="policy" poluuid="1765de8-5a13-765da73fdsfa1c" policyname="newruleelastic" service="portname" dstcountry="Netherlands" srccountry="Reserved" trandisp="snat" transip=123.123.123.123 transport=60964 appcat="unknown" applist="policylist" duration=5462 sentbyte=438650 rcvdbyte=65446 sentpkt=723417 rcvdpkt=1045601 vwlid=0 sentdelta=576 rcvddelta=728 -<189>date=2020-04-23 time=12:11:48 devname="newfirewall" devid="newrouterid" logid="0001000014" type="traffic" subtype="local" level="notice" vd="root" eventtime=1587229908751434997 tz="-0500" srcip=2001:4860:4860::8888 identifier=0 srcintf="port1" srcintfrole="lan" dstip=2001:4860:4860::8888 dstintf="unknown0" dstintfrole="undefined" sessionid=6542345 proto=58 action="accept" policyid=0 policytype="someotherpolicy" service="icmp6/1/0" trandisp="noop" app="icmp6/25/0" duration=42 sentbyte=3014 rcvdbyte=20 sentpkt=4 rcvdpkt=0 appcat="unscanned" -<189>date=2020-04-23 time=13:10:57 devname="newfirewall" devid="newrouterid" logid="0001000014" type="traffic" subtype="local" level="notice" vd="root" eventtime=1587229857509058693 tz="-0400" srcip=9.7.7.7 identifier=61 srcintf="wan1" srcintfrole="wan" dstip=8.8.8.8 dstintf="unknown0" dstintfrole="undefined" sessionid=123 proto=1 action="accept" policyid=0 policytype="rulepolicy" service="PING" dstcountry="Norway" srccountry="Netherlands" trandisp="noop" app="PING" duration=20 sentbyte=0 rcvdbyte=10 sentpkt=0 rcvdpkt=40 appcat="unscanned" -<188>date=2020-04-23 time=12:14:39 devname="firewall3" devid="oldfwid" logid="0000000011" type="traffic" subtype="forward" level="warning" vd="root" eventtime=1587230079841464445 tz="-0500" srcip=192.168.1.1 srcport=62493 srcintf="port1" srcintfrole="lan" dstip=192.168.100.100 dstport=1235 dstintf="newinterface" dstintfrole="undefined" sessionid=54234 proto=17 action="ip-conn" policyid=49 policytype="policy" poluuid="654cc-b6542-53467u8-e45234-1566casd35f7836" policyname="oldpolicyname" user="elasticsuper" authserver="FSSO_newfsso" service="udp/12302" dstcountry="Reserved" srccountry="Reserved" appcat="unscanned" crscore=5 craction=63332144 crlevel="low" -<189>date=2020-04-23 time=12:14:28 devname="firewall3" devid="oldfwid" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1587230069291463928 tz="-0500" srcip=192.168.50.50 srcport=56603 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=442 dstintf="wan1" dstintfrole="wan" sessionid=2345 proto=6 action="close" policyid=2365 policytype="policy" poluuid="654644c-b064-fdgdf3425-f003-1234ghdf682e05f" policyname="someoldpolicyname" user="elasticuser" group="testgroup" authserver="FSSO_something" service="HTTPS" dstcountry="Netherlands" srccountry="Reserved" trandisp="snat" transip=23.23.23.23 transport=603 appid=43540 app="Skype.Portals" appcat="Collaboration" apprisk="elevated" applist="someapplist" appact="detected" duration=126 sentbyte=923 rcvdbyte=77654 sentpkt=113 rcvdpkt=70 vwlid=4 vwlquality="Seq_num(3), alive, selected" wanin=1130 wanout=6671 lanin=1406 lanout=146506 utmaction="block" countweb=1 countapp=1 crscore=5 craction=6144 crlevel="low" -<190>date=2019-05-15 time=18:03:36 logid="1059028704" type="utm" subtype="app-ctrl" eventtype="app-ctrl-all" level="information" vd="root" eventtime=1557968615 appid=40568 srcip=10.1.100.22 dstip=195.8.215.136 srcport=50798 dstport=443 srcintf="port10" srcintfrole="lan" dstintf="port9" dstintfrole="wan" proto=6 service="HTTPS" direction="outgoing" policyid=1 sessionid=4414 applist="block-social.media" appcat="Web.Client" app="HTTPS.BROWSER" action="pass" hostname="www.dailymotion.com" incidentserialno=1962906680 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="*.dailymotion.com" scertissuer="DigiCert SHA2 High Assurance Server CA" -<190>date=2020-11-02 time=08:11:38 devname=testfirewall devid=newrouterid logid=0101037127 type="event" subtype=vpn level=notice vd=root logdesc="Progress IPsec phase 1" msg="progress IPsec phase 1" action=negotiate remip=8.8.8.8 locip=10.10.10.10 remport=500 locport=500 outintf="port1" cookies="125cbf9ee8349965/0000000000000000" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="P1_Test" status=success init=local mode=aggressive dir=outbound stage=1 role=initiator result=OK -<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880370858 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="FCTEMS0000011111_AV-Running" msg="Updated tag FCTEMS0000011111_AV-Running." -<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880455433 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="MAC_FCTEMS0000011111_AV-Running" msg="Updated tag MAC_FCTEMS0000011111_AV-Running." -<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880744919 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="FCTEMS0000011111_Connected-to-EMS" msg="Updated tag FCTEMS0000011111_Connected-to-EMS." -<190>devname="firewall" devid="FG201EEF34CD12AB" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674880784143 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="FCTEMS0000011111" addr="MAC_FCTEMS0000011111_Connected-to-EMS" msg="Updated tag MAC_FCTEMS0000011111_Connected-to-EMS." -<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900027938 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="FCTEMS0000011111_AV-Running" msg="Updated tag FCTEMS0000011111_AV-Running." -<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900167367 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="MAC_FCTEMS0000011111_AV-Running" msg="Updated tag MAC_FCTEMS0000011111_AV-Running." -<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900749585 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="FCTEMS0000011111_Connected-to-EMS" msg="Updated tag FCTEMS0000011111_Connected-to-EMS." -<190>devname="firewall" devid="FG201EAB12CD34EF" vd="root" date=2021-05-07 time=08:31:14 eventtime=1620372674900961834 tz="+0100" logid="0112053203" type="event" subtype="connector" level="information" logdesc="Dynamic address updated" fctemssn="(null)" addr="MAC_FCTEMS0000011111_Connected-to-EMS" msg="Updated tag MAC_FCTEMS0000011111_Connected-to-EMS." diff --git a/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log-expected.json b/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log-expected.json deleted file mode 100644 index bb0699e2ea1..00000000000 --- a/x-pack/filebeat/module/fortinet/firewall/test/fortinet.log-expected.json +++ /dev/null @@ -1,2274 +0,0 @@ -[ - { - "@timestamp": "2020-04-23T12:17:48.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 1130, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 443, - "event.action": "ftgd_blk", - "event.category": [ - "network" - ], - "event.code": "0316013056", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:49.052-05:00", - "event.timezone": "-0500", - "event.type": [ - "denied" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "blocked", - "fortinet.firewall.authserver": "elasticauth", - "fortinet.firewall.cat": "76", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.method": "domain", - "fortinet.firewall.reqtype": "direct", - "fortinet.firewall.sessionid": "1234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "webfilter", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "warning", - "log.offset": 0, - "message": "URL belongs to a denied category in policy", - "network.bytes": 2282, - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "https", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Internet Telephony", - "rule.id": "100602", - "rule.ruleset": "elasticruleset", - "service.type": "fortinet", - "source.bytes": 1152, - "source.ip": "192.168.2.1", - "source.port": 61930, - "source.user.group.name": "elasticgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "url.domain": "elastic.co", - "url.path": "/config/" - }, - { - "@timestamp": "2020-04-23T01:16:08.000Z", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 0, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 161, - "event.action": "deny", - "event.category": [ - "network" - ], - "event.code": "0000000013", - "event.dataset": "fortinet.firewall", - "event.duration": 0, - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-06-24T01:16:08.000Z", - "event.type": [ - "connection", - "end" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "deny", - "fortinet.firewall.craction": "131072", - "fortinet.firewall.crlevel": "high", - "fortinet.firewall.crscore": "30", - "fortinet.firewall.dstcountry": "Reserved", - "fortinet.firewall.dstintfrole": "lan", - "fortinet.firewall.sessionid": "155313", - "fortinet.firewall.srccountry": "Reserved", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "forward", - "fortinet.firewall.trandisp": "noop", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "OPERATIONAL", - "input.type": "log", - "log.level": "notice", - "log.offset": 707, - "network.bytes": 0, - "network.iana_number": "17", - "network.protocol": "snmp", - "observer.egress.interface.name": "dstintfname", - "observer.ingress.interface.name": "srcintfname", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "10.10.10.10", - "8.8.8.8" - ], - "rule.category": "unscanned", - "rule.id": "0", - "rule.ruleset": "policy", - "service.type": "fortinet", - "source.bytes": 0, - "source.ip": "10.10.10.10", - "source.packets": 0, - "source.port": 60899, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:17:45.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 6812, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 443, - "event.action": "ftgd_allow", - "event.category": [ - "network" - ], - "event.code": "0317013312", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:46.314-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "passthrough", - "fortinet.firewall.authserver": "elasticauth", - "fortinet.firewall.cat": "23", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.method": "domain", - "fortinet.firewall.reqtype": "direct", - "fortinet.firewall.sessionid": "543234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "webfilter", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 1278, - "message": "URL belongs to an allowed category in policy", - "network.bytes": 10357, - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "https", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Web-based Email", - "rule.id": "38", - "rule.ruleset": "elasticruleset", - "service.type": "fortinet", - "source.bytes": 3545, - "source.ip": "192.168.2.1", - "source.port": 65236, - "source.user.group.name": "elasticgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "url.domain": "elastic.co", - "url.path": "/" - }, - { - "@timestamp": "2020-04-23T13:17:35.000-04:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 443, - "event.action": "signature", - "event.category": [ - "network" - ], - "event.code": "1059028704", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T13:17:35.061-04:00", - "event.timezone": "-0400", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.appid": "40568", - "fortinet.firewall.apprisk": "medium", - "fortinet.firewall.authserver": "elasticauth", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.incidentserialno": "23465", - "fortinet.firewall.sessionid": "453234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "app-ctrl", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 1980, - "message": "Web.Client: HTTPS.BROWSER,", - "network.application": "HTTPS.BROWSER", - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "ssl", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "LAN", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Web-Client", - "rule.id": "12", - "rule.ruleset": "elasticruleset", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 59790, - "source.user.group.name": "elasticgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "tls.server.x509.subject.common_name": "test.elastic.co", - "url.domain": "elastic.co", - "url.path": "/" - }, - { - "@timestamp": "2020-04-23T13:17:35.000-04:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 443, - "event.action": "signature", - "event.category": [ - "network" - ], - "event.code": "1059028704", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-06-10T07:26:31.000-04:00", - "event.timezone": "-0400", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.appid": "40568", - "fortinet.firewall.apprisk": "medium", - "fortinet.firewall.authserver": "elasticauth", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.incidentserialno": "23465", - "fortinet.firewall.sessionid": "453234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "app-ctrl", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 2683, - "message": "Web.Client: HTTPS.BROWSER,", - "network.application": "HTTPS.BROWSER", - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "ssl", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "LAN", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Web-Client", - "rule.id": "12", - "rule.ruleset": "elasticruleset", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 59790, - "source.user.group.name": "elasticgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "tls.server.x509.subject.common_name": "test.elastic.co", - "url.domain": "elastic.co", - "url.path": "/" - }, - { - "@timestamp": "2020-04-23T12:17:29.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 53, - "dns.id": "2234", - "dns.question.class": "IN", - "dns.question.name": "elastic.example.com", - "dns.question.type": "A", - "dns.resolved_ip": [ - "8.8.8.8" - ], - "event.action": "dns-response", - "event.category": [ - "network" - ], - "event.code": "1501054802", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:29.360-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "info" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.cat": "23", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.qtypeval": "1", - "fortinet.firewall.sessionid": "543234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "dns", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 3377, - "message": "Domain is monitored", - "network.iana_number": "17", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.hosts": [ - "elastic.example.com" - ], - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "rule.category": "Web-based Email", - "rule.id": "26", - "rule.ruleset": "test", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 53430, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:17:29.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 53, - "dns.id": "2234", - "dns.question.class": "IN", - "dns.question.name": "elastic.example.com", - "dns.question.type": "A", - "dns.resolved_ip": [ - "8.8.4.4", - "8.8.8.8" - ], - "event.action": "dns-response", - "event.category": [ - "network" - ], - "event.code": "1501054802", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:29.360-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "info" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.cat": "23", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.qtypeval": "1", - "fortinet.firewall.sessionid": "543234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "dns", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 3927, - "message": "Domain is monitored", - "network.iana_number": "17", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.hosts": [ - "elastic.example.com" - ], - "related.ip": [ - "192.168.2.1", - "8.8.4.4", - "8.8.8.8" - ], - "rule.category": "Web-based Email", - "rule.id": "26", - "rule.ruleset": "test", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 53430, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:17:11.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 443, - "event.action": "signature", - "event.category": [ - "network" - ], - "event.code": "1059028704", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:12.148-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.appid": "40568", - "fortinet.firewall.apprisk": "medium", - "fortinet.firewall.authserver": "elasticauth", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.incidentserialno": "54323", - "fortinet.firewall.sessionid": "543234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "app-ctrl", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 4486, - "message": "Web.Client: HTTPS.BROWSER,", - "network.application": "HTTPS.BROWSER", - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "ssl", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Web-Client", - "rule.id": "100602", - "rule.ruleset": "elasticruleset", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 63012, - "source.user.group.name": "elasticgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "url.domain": "elastic.no", - "url.path": "/" - }, - { - "@timestamp": "2020-04-23T12:17:04.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 53, - "dns.id": "2352", - "dns.question.class": "IN", - "dns.question.name": "elastic.co", - "dns.question.type": "A", - "dns.resolved_ip": [ - "8.8.8.8" - ], - "event.action": "dns-response", - "event.category": [ - "network" - ], - "event.code": "1501054802", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:17:04.712-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "info" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.cat": "93", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.qtypeval": "1", - "fortinet.firewall.sessionid": "5432", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "dns", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 5166, - "message": "Domain is monitored", - "network.iana_number": "17", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.hosts": [ - "elastic.co" - ], - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "rule.category": "Remote Access", - "rule.id": "26", - "rule.ruleset": "elastictest", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 54438, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:17:12.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 53, - "dns.id": "235", - "dns.question.class": "IN", - "dns.question.name": "elastic.co", - "dns.question.type": "A", - "event.action": "dns-query", - "event.category": [ - "network" - ], - "event.code": "1500054000", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:17:12.658-05:00", - "event.timezone": "-0500", - "event.type": [ - "info" - ], - "fileset.name": "firewall", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.qtypeval": "1", - "fortinet.firewall.sessionid": "543234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "dns", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 5710, - "network.iana_number": "17", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "testswitch1", - "observer.product": "Fortigate", - "observer.serial_number": "somerouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.hosts": [ - "elastic.co" - ], - "related.ip": [ - "192.168.2.1", - "8.8.8.8" - ], - "rule.id": "26", - "rule.ruleset": "elastictest", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 54788, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T13:15:18.000-04:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.4.4", - "destination.port": 443, - "event.action": "ssl-anomalies", - "event.category": [ - "network" - ], - "event.code": "1700062001", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T13:15:18.838-04:00", - "event.timezone": "-0400", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "passthrough", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.reason": "untrusted-cert", - "fortinet.firewall.sessionid": "42346234", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "ssl", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 6169, - "message": "Server certificate passed", - "network.iana_number": "6", - "network.protocol": "https", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "LAN", - "observer.name": "testswitch2", - "observer.product": "Fortigate", - "observer.serial_number": "someotherid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.2.1", - "8.8.4.4" - ], - "related.user": [ - "elasticuser2" - ], - "rule.id": "12", - "rule.ruleset": "somecerts", - "service.type": "fortinet", - "source.ip": "192.168.2.1", - "source.port": 59726, - "source.user.group.name": "elasticgroup2", - "source.user.name": "elasticuser2", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:32:48.000-05:00", - "event.category": [ - "authentication" - ], - "event.code": "0102043014", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:32:48.439-05:00", - "event.timezone": "-0500", - "event.type": [ - "start", - "user" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "FSSO-logon", - "fortinet.firewall.server": "elasticserver", - "fortinet.firewall.subtype": "user", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 6699, - "message": "FSSO-logon event from FSSO_elasticserver: user elasticouser logged on 10.10.10.10", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "10.10.10.10" - ], - "related.user": [ - "elasticouser" - ], - "rule.description": "FSSO logon authentication status", - "service.type": "fortinet", - "source.ip": "10.10.10.10", - "source.user.name": "elasticouser", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:32:47.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.4.4", - "destination.port": 500, - "event.category": [ - "network" - ], - "event.code": "0101037124", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "failure", - "event.start": "2020-04-18T12:32:48.339-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "negotiate", - "fortinet.firewall.cookies": "345hkjhdrs87/0000000000000000", - "fortinet.firewall.outintf": "wan2", - "fortinet.firewall.peer_notif": "NOT-APPLICABLE", - "fortinet.firewall.reason": "peer SA proposal not match local policy", - "fortinet.firewall.status": "negotiate_error", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "error", - "log.offset": 7112, - "message": "IPsec phase 1 error", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "8.8.4.4", - "8.8.8.8" - ], - "rule.description": "IPsec phase 1 error", - "service.type": "fortinet", - "source.as.number": 15169, - "source.as.organization.name": "Google LLC", - "source.geo.continent_name": "North America", - "source.geo.country_iso_code": "US", - "source.geo.country_name": "United States", - "source.geo.location.lat": 37.751, - "source.geo.location.lon": -97.822, - "source.ip": "8.8.8.8", - "source.port": 500, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:32:31.000-05:00", - "destination.as.number": 3356, - "destination.as.organization.name": "Level 3 Parent, LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.4.5.4", - "destination.port": 500, - "event.category": [ - "network" - ], - "event.code": "0101037127", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:32:31.628-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "negotiate", - "fortinet.firewall.cookies": "df868dsg876d/0000000000000000", - "fortinet.firewall.init": "local", - "fortinet.firewall.mode": "main", - "fortinet.firewall.outintf": "wan1", - "fortinet.firewall.result": "OK", - "fortinet.firewall.role": "initiator", - "fortinet.firewall.stage": "1", - "fortinet.firewall.status": "success", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "fortinet.firewall.vpntunnel": "elasticvpn", - "input.type": "log", - "log.level": "notice", - "log.offset": 7680, - "message": "progress IPsec phase 1", - "network.direction": "outbound", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "8.4.5.4", - "9.9.9.9" - ], - "rule.description": "Progress IPsec phase 1", - "service.type": "fortinet", - "source.as.number": 19281, - "source.as.organization.name": "Quad9", - "source.geo.continent_name": "Europe", - "source.geo.country_iso_code": "FR", - "source.geo.country_name": "France", - "source.geo.location.lat": 48.8582, - "source.geo.location.lon": 2.3387, - "source.ip": "9.9.9.9", - "source.port": 500, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T14:32:09.000-03:00", - "event.category": [ - "host" - ], - "event.code": "0100040704", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T14:32:09.938-03:00", - "event.timezone": "-0300", - "event.type": [ - "info" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "perf-stats", - "fortinet.firewall.bandwidth": "23/4", - "fortinet.firewall.cpu": "0", - "fortinet.firewall.disk": "0", - "fortinet.firewall.disklograte": "0", - "fortinet.firewall.fazlograte": "0", - "fortinet.firewall.freediskstorage": "331", - "fortinet.firewall.mem": 10, - "fortinet.firewall.setuprate": "0", - "fortinet.firewall.subtype": "system", - "fortinet.firewall.sysuptime": "25170", - "fortinet.firewall.totalsession": "23", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 8254, - "message": "Performance statistics: average CPU: 0, memory: 23, concurrent sessions: 20, setup-rate: 0", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "System performance statistics", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:32:09.000-05:00", - "event.category": [ - "authentication" - ], - "event.code": "0102043039", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:32:10.109-05:00", - "event.timezone": "-0500", - "event.type": [ - "start", - "user" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "auth-logon", - "fortinet.firewall.authserver": "FSSO_elastiauth", - "fortinet.firewall.status": "logon", - "fortinet.firewall.subtype": "user", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 8744, - "message": "User elastiiiuser added to auth logon", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "10.10.10.10" - ], - "related.user": [ - "elastiiiuser" - ], - "rule.description": "Authentication logon", - "service.type": "fortinet", - "source.ip": "10.10.10.10", - "source.user.name": "elastiiiuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:32:00.000-05:00", - "destination.as.number": 3356, - "destination.as.organization.name": "Level 3 Parent, LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.5.4", - "destination.port": 500, - "event.category": [ - "network" - ], - "event.code": "0101037127", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:32:00.608-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "negotiate", - "fortinet.firewall.cookies": "345khj34566/0000000000000000", - "fortinet.firewall.init": "local", - "fortinet.firewall.mode": "main", - "fortinet.firewall.outintf": "wan1", - "fortinet.firewall.result": "OK", - "fortinet.firewall.role": "initiator", - "fortinet.firewall.stage": "1", - "fortinet.firewall.status": "success", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "fortinet.firewall.vpntunnel": "testvpn", - "input.type": "log", - "log.level": "notice", - "log.offset": 9122, - "message": "progress IPsec phase 1", - "network.direction": "outbound", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "7.6.3.4", - "8.8.5.4" - ], - "rule.description": "Progress IPsec phase 1", - "service.type": "fortinet", - "source.geo.continent_name": "North America", - "source.geo.country_iso_code": "US", - "source.geo.country_name": "United States", - "source.geo.location.lat": 37.751, - "source.geo.location.lon": -97.822, - "source.ip": "7.6.3.4", - "source.port": 500, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T14:24:13.000-03:00", - "event.code": "0100041006", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T14:24:15.301-03:00", - "event.timezone": "-0300", - "fileset.name": "firewall", - "fortinet.firewall.subtype": "system", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "fortinet.firewall.version": "1.522479", - "input.type": "log", - "log.level": "notice", - "log.offset": 9692, - "message": "FortiSandbox AV database updated", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "FortiSandbox AV database updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:23:47.000-05:00", - "event.code": "0107045057", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:23:47.558-05:00", - "event.timezone": "-0500", - "fileset.name": "firewall", - "fortinet.firewall.action": "add", - "fortinet.firewall.connection_type": "sslvpn", - "fortinet.firewall.count": "2", - "fortinet.firewall.fctuid": "645234fdd01F885824F764", - "fortinet.firewall.ip": "172.16.0.2", - "fortinet.firewall.license_limit": "unlimited", - "fortinet.firewall.name": "somerouter", - "fortinet.firewall.status": "success", - "fortinet.firewall.subtype": "endpoint", - "fortinet.firewall.type": "event", - "fortinet.firewall.used_for_type": "3", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 9996, - "message": "Add a FortiClient Connection.", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.user": [ - "elastico" - ], - "rule.description": "FortiClient connection added", - "service.type": "fortinet", - "source.user.name": "elastico", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:23:47.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.6", - "event.category": [ - "network" - ], - "event.code": "0101039943", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:23:47.334-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "ssl-new-con", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.tunnelid": "2", - "fortinet.firewall.tunneltype": "ssl", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 10466, - "message": "SSL new connection", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "8.8.8.6" - ], - "rule.description": "SSL VPN new connection", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:23:47.000-05:00", - "destination.as.number": 3356, - "destination.as.organization.name": "Level 3 Parent, LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.5.4", - "event.category": [ - "network" - ], - "event.code": "0101039947", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:23:47.698-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "tunnel-up", - "fortinet.firewall.reason": "tunnel established", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.tunnelid": "2345", - "fortinet.firewall.tunnelip": "10.10.10.10", - "fortinet.firewall.tunneltype": "ssl-tunnel", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 10843, - "message": "SSL tunnel established", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "8.8.5.4" - ], - "related.user": [ - "someuser" - ], - "rule.description": "SSL VPN tunnel up", - "service.type": "fortinet", - "source.user.group.name": "somegroup", - "source.user.name": "someuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T14:16:42.000-03:00", - "event.category": [ - "authentication" - ], - "event.code": "0102043015", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T14:16:44.674-03:00", - "event.timezone": "-0300", - "event.type": [ - "end", - "user" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "FSSO-logoff", - "fortinet.firewall.server": "FSSO_somefssoserver", - "fortinet.firewall.subtype": "user", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 11274, - "message": "FSSO-logoff event from FSSO_somefssoserver: user elasticuser logged off 1192.168.1.1", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.1.1" - ], - "related.user": [ - "elasticadmin" - ], - "rule.description": "FSSO log off authentication status", - "service.type": "fortinet", - "source.ip": "192.168.1.1", - "source.user.name": "elasticadmin", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:16:02.000-05:00", - "event.code": "0100022915", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:16:03.121-05:00", - "event.timezone": "-0500", - "fileset.name": "firewall", - "fortinet.firewall.action": "connect", - "fortinet.firewall.server": "9.9.9.9", - "fortinet.firewall.subtype": "system", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 11699, - "message": "FortiCloud 9.9.9.9 server is connected", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "FortiCloud server connected", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:16:02.000-05:00", - "event.code": "0100022913", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2020-04-18T12:16:03.375-05:00", - "event.timezone": "-0500", - "fileset.name": "firewall", - "fortinet.firewall.action": "disconnect", - "fortinet.firewall.reason": "connection reset", - "fortinet.firewall.server": "4.4.4.4", - "fortinet.firewall.subtype": "system", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 12019, - "message": "FortiCloud 4.4.4.4 server is disconnected", - "observer.name": "testswitch3", - "observer.product": "Fortigate", - "observer.serial_number": "someotherrouteridagain", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "FortiCloud server disconnected", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:14:09.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 53, - "event.action": "dns", - "event.category": [ - "network" - ], - "event.code": "0000000011", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:14:09.761-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "connection", - "end" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "dns", - "fortinet.firewall.craction": "54144", - "fortinet.firewall.crlevel": "low", - "fortinet.firewall.crscore": "5", - "fortinet.firewall.dstcountry": "Netherlands", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.sessionid": "435234", - "fortinet.firewall.srccountry": "Reserved", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "forward", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "warning", - "log.offset": 12374, - "network.iana_number": "17", - "network.protocol": "dns", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "newfirewall", - "observer.product": "Fortigate", - "observer.serial_number": "newrouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.1.6", - "8.8.8.8" - ], - "rule.category": "unscanned", - "rule.id": "26", - "rule.name": "elasticnewruleset", - "rule.ruleset": "policy", - "rule.uuid": "2345de-b143-52134d8-6654f-4654sdfg16f431", - "service.type": "fortinet", - "source.ip": "192.168.1.6", - "source.port": 53438, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:11:51.000-05:00", - "destination.as.number": 40386, - "destination.as.organization.name": "Bloomip Inc.", - "destination.bytes": 65446, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.6.4.7", - "destination.packets": 1045601, - "destination.port": 6000, - "event.action": "accept", - "event.category": [ - "network" - ], - "event.code": "0000000020", - "event.dataset": "fortinet.firewall", - "event.duration": 5462000000000, - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:11:51.390-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "connection", - "end" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "accept", - "fortinet.firewall.applist": "policylist", - "fortinet.firewall.dstcountry": "Netherlands", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.rcvddelta": "728", - "fortinet.firewall.sentdelta": "576", - "fortinet.firewall.sessionid": "4352", - "fortinet.firewall.srccountry": "Reserved", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "forward", - "fortinet.firewall.trandisp": "snat", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "root", - "fortinet.firewall.vwlid": "0", - "input.type": "log", - "log.level": "notice", - "log.offset": 12966, - "network.bytes": 504096, - "network.iana_number": "17", - "network.packets": 1769018, - "network.protocol": "portname", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "newfirewall", - "observer.product": "Fortigate", - "observer.serial_number": "newrouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.10.10", - "8.6.4.7" - ], - "rule.category": "unknown", - "rule.id": "3426", - "rule.name": "newruleelastic", - "rule.ruleset": "policy", - "rule.uuid": "1765de8-5a13-765da73fdsfa1c", - "service.type": "fortinet", - "source.as.number": 4808, - "source.as.organization.name": "China Unicom Beijing Province Network", - "source.bytes": 438650, - "source.geo.city_name": "Beijing", - "source.geo.continent_name": "Asia", - "source.geo.country_iso_code": "CN", - "source.geo.country_name": "China", - "source.geo.location.lat": 39.9288, - "source.geo.location.lon": 116.3889, - "source.geo.region_iso_code": "CN-BJ", - "source.geo.region_name": "Beijing", - "source.ip": "192.168.10.10", - "source.nat.ip": "123.123.123.123", - "source.nat.port": 60964, - "source.packets": 723417, - "source.port": 6000, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:11:48.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 20, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "2001:4860:4860::8888", - "destination.packets": 0, - "event.action": "accept", - "event.category": [ - "network" - ], - "event.code": "0001000014", - "event.dataset": "fortinet.firewall", - "event.duration": 42000000000, - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:11:48.751-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "connection", - "end", - "protocol" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "accept", - "fortinet.firewall.dstintfrole": "undefined", - "fortinet.firewall.identifier": "0", - "fortinet.firewall.sessionid": "6542345", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "local", - "fortinet.firewall.trandisp": "noop", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 13700, - "network.application": "icmp6/25/0", - "network.bytes": 3034, - "network.iana_number": "58", - "network.packets": 4, - "network.protocol": "icmp6/1/0", - "observer.egress.interface.name": "unknown0", - "observer.ingress.interface.name": "port1", - "observer.name": "newfirewall", - "observer.product": "Fortigate", - "observer.serial_number": "newrouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "2001:4860:4860::8888", - "2001:4860:4860::8888" - ], - "rule.category": "unscanned", - "rule.id": "0", - "rule.ruleset": "someotherpolicy", - "service.type": "fortinet", - "source.as.number": 15169, - "source.as.organization.name": "Google LLC", - "source.bytes": 3014, - "source.geo.continent_name": "North America", - "source.geo.country_iso_code": "US", - "source.geo.country_name": "United States", - "source.geo.location.lat": 37.751, - "source.geo.location.lon": -97.822, - "source.ip": "2001:4860:4860::8888", - "source.packets": 4, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T13:10:57.000-04:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 10, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.packets": 40, - "event.action": "accept", - "event.category": [ - "network" - ], - "event.code": "0001000014", - "event.dataset": "fortinet.firewall", - "event.duration": 20000000000, - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T13:10:57.509-04:00", - "event.timezone": "-0400", - "event.type": [ - "allowed", - "connection", - "end", - "protocol" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "accept", - "fortinet.firewall.dstcountry": "Norway", - "fortinet.firewall.dstintfrole": "undefined", - "fortinet.firewall.identifier": "61", - "fortinet.firewall.sessionid": "123", - "fortinet.firewall.srccountry": "Netherlands", - "fortinet.firewall.srcintfrole": "wan", - "fortinet.firewall.subtype": "local", - "fortinet.firewall.trandisp": "noop", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "notice", - "log.offset": 14250, - "network.application": "PING", - "network.bytes": 10, - "network.iana_number": "1", - "network.packets": 40, - "network.protocol": "ping", - "observer.egress.interface.name": "unknown0", - "observer.ingress.interface.name": "wan1", - "observer.name": "newfirewall", - "observer.product": "Fortigate", - "observer.serial_number": "newrouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "8.8.8.8", - "9.7.7.7" - ], - "rule.category": "unscanned", - "rule.id": "0", - "rule.ruleset": "rulepolicy", - "service.type": "fortinet", - "source.bytes": 0, - "source.geo.continent_name": "North America", - "source.geo.country_iso_code": "US", - "source.geo.country_name": "United States", - "source.geo.location.lat": 37.751, - "source.geo.location.lon": -97.822, - "source.ip": "9.7.7.7", - "source.packets": 0, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:14:39.000-05:00", - "destination.ip": "192.168.100.100", - "destination.port": 1235, - "event.action": "ip-conn", - "event.category": [ - "network" - ], - "event.code": "0000000011", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:14:39.841-05:00", - "event.timezone": "-0500", - "event.type": [ - "allowed", - "connection", - "end" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "ip-conn", - "fortinet.firewall.authserver": "FSSO_newfsso", - "fortinet.firewall.craction": "63332144", - "fortinet.firewall.crlevel": "low", - "fortinet.firewall.crscore": "5", - "fortinet.firewall.dstcountry": "Reserved", - "fortinet.firewall.dstintfrole": "undefined", - "fortinet.firewall.sessionid": "54234", - "fortinet.firewall.srccountry": "Reserved", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "forward", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "warning", - "log.offset": 14796, - "network.iana_number": "17", - "network.protocol": "udp/12302", - "observer.egress.interface.name": "newinterface", - "observer.ingress.interface.name": "port1", - "observer.name": "firewall3", - "observer.product": "Fortigate", - "observer.serial_number": "oldfwid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.1.1", - "192.168.100.100" - ], - "related.user": [ - "elasticsuper" - ], - "rule.category": "unscanned", - "rule.id": "49", - "rule.name": "oldpolicyname", - "rule.ruleset": "policy", - "rule.uuid": "654cc-b6542-53467u8-e45234-1566casd35f7836", - "service.type": "fortinet", - "source.ip": "192.168.1.1", - "source.port": 62493, - "source.user.name": "elasticsuper", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2020-04-23T12:14:28.000-05:00", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.bytes": 77654, - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.packets": 70, - "destination.port": 442, - "event.action": "close", - "event.category": [ - "network" - ], - "event.code": "0000000013", - "event.dataset": "fortinet.firewall", - "event.duration": 126000000000, - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2020-04-18T12:14:29.291-05:00", - "event.timezone": "-0500", - "event.type": [ - "connection", - "denied", - "end", - "protocol" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "close", - "fortinet.firewall.appact": "detected", - "fortinet.firewall.appid": "43540", - "fortinet.firewall.applist": "someapplist", - "fortinet.firewall.apprisk": "elevated", - "fortinet.firewall.authserver": "FSSO_something", - "fortinet.firewall.countapp": "1", - "fortinet.firewall.countweb": "1", - "fortinet.firewall.craction": "6144", - "fortinet.firewall.crlevel": "low", - "fortinet.firewall.crscore": "5", - "fortinet.firewall.dstcountry": "Netherlands", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.lanin": "1406", - "fortinet.firewall.lanout": "146506", - "fortinet.firewall.sessionid": "2345", - "fortinet.firewall.srccountry": "Reserved", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "forward", - "fortinet.firewall.trandisp": "snat", - "fortinet.firewall.type": "traffic", - "fortinet.firewall.utmaction": "block", - "fortinet.firewall.vd": "root", - "fortinet.firewall.vwlid": "4", - "fortinet.firewall.vwlquality": "Seq_num(3), alive, selected", - "fortinet.firewall.wanin": "1130", - "fortinet.firewall.wanout": "6671", - "input.type": "log", - "log.level": "notice", - "log.offset": 15459, - "network.application": "Skype.Portals", - "network.bytes": 78577, - "network.iana_number": "6", - "network.packets": 183, - "network.protocol": "https", - "observer.egress.interface.name": "wan1", - "observer.ingress.interface.name": "port1", - "observer.name": "firewall3", - "observer.product": "Fortigate", - "observer.serial_number": "oldfwid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "192.168.50.50", - "8.8.8.8" - ], - "related.user": [ - "elasticuser" - ], - "rule.category": "Collaboration", - "rule.id": "2365", - "rule.name": "someoldpolicyname", - "rule.ruleset": "policy", - "rule.uuid": "654644c-b064-fdgdf3425-f003-1234ghdf682e05f", - "service.type": "fortinet", - "source.as.number": 14618, - "source.as.organization.name": "Amazon.com, Inc.", - "source.bytes": 923, - "source.geo.city_name": "Ashburn", - "source.geo.continent_name": "North America", - "source.geo.country_iso_code": "US", - "source.geo.country_name": "United States", - "source.geo.location.lat": 39.0481, - "source.geo.location.lon": -77.4728, - "source.geo.region_iso_code": "US-VA", - "source.geo.region_name": "Virginia", - "source.ip": "192.168.50.50", - "source.nat.ip": "23.23.23.23", - "source.nat.port": 603, - "source.packets": 113, - "source.port": 56603, - "source.user.group.name": "testgroup", - "source.user.name": "elasticuser", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2019-05-15T18:03:36.000Z", - "destination.as.number": 41690, - "destination.as.organization.name": "Dailymotion S.A.", - "destination.geo.continent_name": "Europe", - "destination.geo.country_iso_code": "FR", - "destination.geo.country_name": "France", - "destination.geo.location.lat": 48.8582, - "destination.geo.location.lon": 2.3387, - "destination.ip": "195.8.215.136", - "destination.port": 443, - "event.action": "app-ctrl-all", - "event.category": [ - "network" - ], - "event.code": "1059028704", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.start": "2019-05-16T01:03:35.000Z", - "event.type": [ - "allowed" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "pass", - "fortinet.firewall.appid": "40568", - "fortinet.firewall.apprisk": "medium", - "fortinet.firewall.dstintfrole": "wan", - "fortinet.firewall.incidentserialno": "1962906680", - "fortinet.firewall.sessionid": "4414", - "fortinet.firewall.srcintfrole": "lan", - "fortinet.firewall.subtype": "app-ctrl", - "fortinet.firewall.type": "utm", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 16463, - "message": "Web.Client: HTTPS.BROWSER,", - "network.application": "HTTPS.BROWSER", - "network.direction": "outbound", - "network.iana_number": "6", - "network.protocol": "https", - "observer.egress.interface.name": "port9", - "observer.ingress.interface.name": "port10", - "observer.product": "Fortigate", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "10.1.100.22", - "195.8.215.136" - ], - "rule.category": "Web-Client", - "rule.id": "1", - "rule.ruleset": "block-social.media", - "service.type": "fortinet", - "source.ip": "10.1.100.22", - "source.port": 50798, - "tags": [ - "fortinet-firewall", - "forwarded" - ], - "tls.server.issuer": "DigiCert SHA2 High Assurance Server CA", - "tls.server.x509.issuer.common_name": "DigiCert SHA2 High Assurance Server CA", - "tls.server.x509.subject.common_name": "*.dailymotion.com", - "url.domain": "www.dailymotion.com", - "url.path": "/" - }, - { - "@timestamp": "2020-11-02T08:11:38.000Z", - "destination.as.number": 15169, - "destination.as.organization.name": "Google LLC", - "destination.geo.continent_name": "North America", - "destination.geo.country_iso_code": "US", - "destination.geo.country_name": "United States", - "destination.geo.location.lat": 37.751, - "destination.geo.location.lon": -97.822, - "destination.ip": "8.8.8.8", - "destination.port": 500, - "event.category": [ - "network" - ], - "event.code": "0101037127", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.outcome": "success", - "event.type": [ - "connection" - ], - "fileset.name": "firewall", - "fortinet.firewall.action": "negotiate", - "fortinet.firewall.cookies": "125cbf9ee8349965/0000000000000000", - "fortinet.firewall.init": "local", - "fortinet.firewall.mode": "aggressive", - "fortinet.firewall.outintf": "port1", - "fortinet.firewall.result": "OK", - "fortinet.firewall.role": "initiator", - "fortinet.firewall.stage": "1", - "fortinet.firewall.status": "success", - "fortinet.firewall.subtype": "vpn", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "fortinet.firewall.vpntunnel": "P1_Test", - "input.type": "log", - "log.level": "notice", - "log.offset": 17123, - "message": "progress IPsec phase 1", - "network.direction": "outbound", - "observer.name": "testfirewall", - "observer.product": "Fortigate", - "observer.serial_number": "newrouterid", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "related.ip": [ - "10.10.10.10", - "8.8.8.8" - ], - "rule.description": "Progress IPsec phase 1", - "service.type": "fortinet", - "source.ip": "10.10.10.10", - "source.port": 500, - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.880+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "FCTEMS0000011111_AV-Running", - "fortinet.firewall.fctemssn": "FCTEMS0000011111", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 17632, - "message": "Updated tag FCTEMS0000011111_AV-Running.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EEF34CD12AB", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.880+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_AV-Running", - "fortinet.firewall.fctemssn": "FCTEMS0000011111", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 17978, - "message": "Updated tag MAC_FCTEMS0000011111_AV-Running.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EEF34CD12AB", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.880+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "FCTEMS0000011111_Connected-to-EMS", - "fortinet.firewall.fctemssn": "FCTEMS0000011111", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 18332, - "message": "Updated tag FCTEMS0000011111_Connected-to-EMS.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EEF34CD12AB", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.880+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_Connected-to-EMS", - "fortinet.firewall.fctemssn": "FCTEMS0000011111", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 18690, - "message": "Updated tag MAC_FCTEMS0000011111_Connected-to-EMS.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EEF34CD12AB", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.900+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "FCTEMS0000011111_AV-Running", - "fortinet.firewall.fctemssn": "(null)", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 19056, - "message": "Updated tag FCTEMS0000011111_AV-Running.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EAB12CD34EF", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.900+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_AV-Running", - "fortinet.firewall.fctemssn": "(null)", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 19392, - "message": "Updated tag MAC_FCTEMS0000011111_AV-Running.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EAB12CD34EF", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.900+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "FCTEMS0000011111_Connected-to-EMS", - "fortinet.firewall.fctemssn": "(null)", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 19736, - "message": "Updated tag FCTEMS0000011111_Connected-to-EMS.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EAB12CD34EF", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - }, - { - "@timestamp": "2021-05-07T08:31:14.000+01:00", - "event.code": "0112053203", - "event.dataset": "fortinet.firewall", - "event.kind": "event", - "event.module": "fortinet", - "event.start": "2021-05-07T08:31:14.900+01:00", - "event.timezone": "+0100", - "fileset.name": "firewall", - "fortinet.firewall.addrgrp": "MAC_FCTEMS0000011111_Connected-to-EMS", - "fortinet.firewall.fctemssn": "(null)", - "fortinet.firewall.subtype": "connector", - "fortinet.firewall.type": "event", - "fortinet.firewall.vd": "root", - "input.type": "log", - "log.level": "information", - "log.offset": 20084, - "message": "Updated tag MAC_FCTEMS0000011111_Connected-to-EMS.", - "observer.name": "firewall", - "observer.product": "Fortigate", - "observer.serial_number": "FG201EAB12CD34EF", - "observer.type": "firewall", - "observer.vendor": "Fortinet", - "rule.description": "Dynamic address updated", - "service.type": "fortinet", - "tags": [ - "fortinet-firewall", - "forwarded" - ] - } -] \ No newline at end of file diff --git a/x-pack/filebeat/module/fortinet/firewall/test/traffic.log b/x-pack/filebeat/module/fortinet/firewall/test/traffic.log new file mode 100644 index 00000000000..5da8ddc11e0 --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/traffic.log @@ -0,0 +1,13 @@ +<189>date=2020-04-23 time=01:16:08 devname="testswitch1" devid="somerouterid" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="OPERATIONAL" eventtime=1592961368 srcip=10.10.10.10 srcport=60899 srcintf="srcintfname" srcintfrole="lan" dstip=8.8.8.8 dstport=161 dstintf="dstintfname" dstintfrole="lan" sessionid=155313 proto=17 action="deny" policyid=0 policytype="policy" service="SNMP" dstcountry="Reserved" srccountry="Reserved" trandisp="noop" duration=0 sentbyte=0 rcvdbyte=0 sentpkt=0 appcat="unscanned" crscore=30 craction=131072 crlevel="high" +<188>date=2020-04-23 time=12:14:09 devname="newfirewall" devid="newrouterid" logid="0000000011" type="traffic" subtype="forward" level="warning" vd="root" eventtime=1587230049761513222 tz="-0500" srcip=192.168.1.6 srcport=53438 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" sessionid=435234 proto=17 action="dns" policyid=26 policytype="policy" poluuid="2345de-b143-52134d8-6654f-4654sdfg16f431" policyname="elasticnewruleset" service="DNS" dstcountry="Netherlands" srccountry="Reserved" appcat="unscanned" crscore=5 craction=54144 crlevel="low" +<189>date=2020-04-23 time=12:11:51 devname="newfirewall" devid="newrouterid" logid="0000000020" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1587229911390385486 tz="-0500" srcip=192.168.10.10 srcport=6000 srcintf="port1" srcintfrole="lan" dstip=8.6.4.7 dstport=6000 dstintf="wan1" dstintfrole="wan" sessionid=4352 proto=17 action="accept" policyid=3426 policytype="policy" poluuid="1765de8-5a13-765da73fdsfa1c" policyname="newruleelastic" service="portname" dstcountry="Netherlands" srccountry="Reserved" trandisp="snat" transip=123.123.123.123 transport=60964 appcat="unknown" applist="policylist" duration=5462 sentbyte=438650 rcvdbyte=65446 sentpkt=723417 rcvdpkt=1045601 vwlid=0 sentdelta=576 rcvddelta=728 +<189>date=2020-04-23 time=12:11:48 devname="newfirewall" devid="newrouterid" logid="0001000014" type="traffic" subtype="local" level="notice" vd="root" eventtime=1587229908751434997 tz="-0500" srcip=2001:4860:4860::8888 identifier=0 srcintf="port1" srcintfrole="lan" dstip=2001:4860:4860::8888 dstintf="unknown0" dstintfrole="undefined" sessionid=6542345 proto=58 action="accept" policyid=0 policytype="someotherpolicy" service="icmp6/1/0" trandisp="noop" app="icmp6/25/0" duration=42 sentbyte=3014 rcvdbyte=20 sentpkt=4 rcvdpkt=0 appcat="unscanned" +<189>date=2020-04-23 time=13:10:57 devname="newfirewall" devid="newrouterid" logid="0001000014" type="traffic" subtype="local" level="notice" vd="root" eventtime=1587229857509058693 tz="-0400" srcip=9.7.7.7 identifier=61 srcintf="wan1" srcintfrole="wan" dstip=8.8.8.8 dstintf="unknown0" dstintfrole="undefined" sessionid=123 proto=1 action="accept" policyid=0 policytype="rulepolicy" service="PING" dstcountry="Norway" srccountry="Netherlands" trandisp="noop" app="PING" duration=20 sentbyte=0 rcvdbyte=10 sentpkt=0 rcvdpkt=40 appcat="unscanned" +<188>date=2020-04-23 time=12:14:39 devname="firewall3" devid="oldfwid" logid="0000000011" type="traffic" subtype="forward" level="warning" vd="root" eventtime=1587230079841464445 tz="-0500" srcip=192.168.1.1 srcport=62493 srcintf="port1" srcintfrole="lan" dstip=192.168.100.100 dstport=1235 dstintf="newinterface" dstintfrole="undefined" sessionid=54234 proto=17 action="ip-conn" policyid=49 policytype="policy" poluuid="654cc-b6542-53467u8-e45234-1566casd35f7836" policyname="oldpolicyname" user="elasticsuper" authserver="FSSO_newfsso" service="udp/12302" dstcountry="Reserved" srccountry="Reserved" appcat="unscanned" crscore=5 craction=63332144 crlevel="low" +<189>date=2020-04-23 time=12:14:28 devname="firewall3" devid="oldfwid" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1587230069291463928 tz="-0500" srcip=192.168.50.50 srcport=56603 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=442 dstintf="wan1" dstintfrole="wan" sessionid=2345 proto=6 action="close" policyid=2365 policytype="policy" poluuid="654644c-b064-fdgdf3425-f003-1234ghdf682e05f" policyname="someoldpolicyname" user="elasticuser" group="testgroup" authserver="FSSO_something" service="HTTPS" dstcountry="Netherlands" srccountry="Reserved" trandisp="snat" transip=23.23.23.23 transport=603 appid=43540 app="Skype.Portals" appcat="Collaboration" apprisk="elevated" applist="someapplist" appact="detected" duration=126 sentbyte=923 rcvdbyte=77654 sentpkt=113 rcvdpkt=70 vwlid=4 vwlquality="Seq_num(3), alive, selected" wanin=1130 wanout=6671 lanin=1406 lanout=146506 utmaction="block" countweb=1 countapp=1 crscore=5 craction=6144 crlevel="low" +<189>date=2019-03-31 time=06:42:54 logid="0002000012" type="traffic" subtype="multicast" level="notice" vd="vdom1" eventtime=1554039772 srcip=172.16.200.55 srcport=60660 srcintf="port25" srcintfrole="undefined" dstip=230.1.1.2 dstport=7878 dstintf="port3" dstintfrole="undefined" sessionid=1162 proto=17 action="accept" policyid=1 policytype="multicast-policy" service="udp/7878" dstcountry="Reserved" srccountry="Reserved" trandisp="noop" duration=22 sentbyte=5940 rcvdbyte=0 sentpkt=11 rcvdpkt=0 appcat="unscanned" +<189>date=2019-05-10 time=14:18:54 logid="0004000017" type="traffic" subtype="sniffer" level="notice" vd="root" eventtime=1557523134021045897 srcip=208.91.114.4 srcport=50463 srcintf="port1" srcintfrole="undefined" dstip=104.80.88.154 dstport=443 dstintf="port1" dstintfrole="undefined" sessionid=2193276 proto=6 action="accept" policyid=3 policytype="sniffer" service="HTTPS" dstcountry="United States" srccountry="Canada" trandisp="snat" transip=0.0.0.0 transport=0 duration=10 sentbyte=0 rcvdbyte=0 sentpkt=0 rcvdpkt=0 appcat="unscanned" utmaction="allow" countips=1 crscore=5 craction=32768 sentdelta=0 rcvddelta=0 utmref=65162-7772 +<189>date=2019-05-13 time=11:45:04 logid="0000000013" type="traffic" subtype="forward" level="notice" vd="vdom1" eventtime=1557773104815101919 srcip=10.1.100.11 srcport=60446 srcintf="port12" srcintfrole="undefined" dstip=172.16.200.55 dstport=80 dstintf="port11" dstintfrole="undefined" srcuuid="48420c8a-5c88-51e9-0424-a37f9e74621e" dstuuid="187d6f46-5c86-51e9-70a0-fadcfc349c3e" poluuid="3888b41a-5c88-51e9-cb32-1c32c66b4edf" sessionid=359260 proto=6 action="close" policyid=4 policytype="policy" service="HTTP" dstcountry="Reserved" srccountry="Reserved" trandisp="snat" transip=172.16.200.2 transport=60446 appid=15893 app="HTTP.BROWSER" appcat="Web.Client" apprisk="medium" applist="g-default" duration=1 sentbyte=412 rcvdbyte=2286 sentpkt=6 rcvdpkt=6 wanin=313 wanout=92 lanin=92 lanout=92 utmaction="block" countav=1 countapp=1 crscore=50 craction=2 osname="Ubuntu" mastersrcmac="a2:e9:00:ec:40:01" srcmac="a2:e9:00:ec:40:01" srcserver=0 utmref=65497-770 +<189>date=2019-05-13 time=16:29:50 logid="0000000013" type="traffic" subtype="forward" level="notice" vd="vdom1" eventtime=1557790190452146185 srcip=10.1.100.11 srcport=44258 srcintf="port12" srcintfrole="undefined" dstip=185.244.31.158 dstport=80 dstintf="port11" dstintfrole="undefined" srcuuid="ae28f494-5735-51e9-f247-d1d2ce663f4b" dstuuid="ae28f494-5735-51e9-f247-d1d2ce663f4b" poluuid="ccb269e0-5735-51e9-a218-a397dd08b7eb" sessionid=381780 proto=6 action="close" policyid=1 policytype="policy" service="HTTP" dstcountry="Germany" srccountry="Reserved" trandisp="snat" transip=172.16.200.2 transport=44258 duration=5 sentbyte=736 rcvdbyte=3138 sentpkt=14 rcvdpkt=5 appcat="unscanned" utmaction="block" countweb=1 crscore=30 craction=4194304 osname="Ubuntu" mastersrcmac="a2:e9:00:ec:40:01" srcmac="a2:e9:00:ec:40:01" srcserver=0 utmref=65497-796 +<189>date=2019-05-15 time=17:58:10 logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1557968289 srcip=10.1.100.22 srcport=46810 srcintf="port10" srcintfrole="lan" dstip=172.16.200.55 dstport=80 dstintf="port9" dstintfrole="wan" poluuid="d8ce7a90-7763-51e9-e2be-741294c96f31" sessionid=4017 proto=6 action="close" policyid=1 policytype="policy" service="HTTP" dstcountry="Reserved" srccountry="Reserved" trandisp="snat" transip=172.16.200.10 transport=46810 duration=89 sentbyte=565 rcvdbyte=9112 sentpkt=9 rcvdpkt=8 appcat="unscanned" utmaction="block" countips=1 crscore=50 craction=4096 devtype="Unknown" devcategory="None" mastersrcmac="00:0c:29:51:38:5e" srcmac="00:0c:29:51:38:5e" srcserver=0 utmref=0-302 +<189>date=2019-05-15 time=17:45:34 logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1557967534 srcip=10.1.100.22 srcport=50354 srcintf="port10" srcintfrole="lan" dstip=52.216.177.83 dstport=443 dstintf="port9" dstintfrole="wan" poluuid="d8ce7a90-7763-51e9-e2be-741294c96f31" sessionid=3423 proto=6 action="server-rst" policyid=1 policytype="policy" service="HTTPS" dstcountry="United States" srccountry="Reserved" trandisp="snat" transip=172.16.200.10 transport=50354 duration=5 sentbyte=2314 rcvdbyte=5266 sentpkt=33 rcvdpkt=12 appcat="unscanned" wanin=43936 wanout=710 lanin=753 lanout=753 utmaction="block" countdlp=1 crscore=5 craction=262144 crlevel="low" devtype="Unknown" devcategory="None" mastersrcmac="00:0c:29:51:38:5e" srcmac="00:0c:29:51:38:5e" srcserver=0 utmref=0-152 diff --git a/x-pack/filebeat/module/fortinet/firewall/test/traffic.log-expected.json b/x-pack/filebeat/module/fortinet/firewall/test/traffic.log-expected.json new file mode 100644 index 00000000000..69668eff862 --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/traffic.log-expected.json @@ -0,0 +1,1079 @@ +[ + { + "@timestamp": "2020-04-23T01:16:08.000Z", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 0, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 161, + "event.action": "deny", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 0, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-06-24T01:16:08.000Z", + "event.type": [ + "connection", + "denied", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "deny", + "fortinet.firewall.craction": "131072", + "fortinet.firewall.crlevel": "high", + "fortinet.firewall.crscore": "30", + "fortinet.firewall.dstcountry": "Reserved", + "fortinet.firewall.dstintfrole": "lan", + "fortinet.firewall.sessionid": "155313", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "noop", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "OPERATIONAL", + "input.type": "log", + "log.level": "notice", + "log.offset": 0, + "network.bytes": 0, + "network.community_id": "1:5XHCUlirlh1DoTaoFuXEVxc6Obs=", + "network.iana_number": "17", + "network.protocol": "snmp", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "dstintfname", + "observer.ingress.interface.name": "srcintfname", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.10.10.10", + "8.8.8.8" + ], + "rule.category": "unscanned", + "rule.id": "0", + "rule.ruleset": "policy", + "service.type": "fortinet", + "source.bytes": 0, + "source.ip": "10.10.10.10", + "source.packets": 0, + "source.port": 60899, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:14:09.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 53, + "event.action": "dns", + "event.category": [ + "network" + ], + "event.code": "0000000011", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:14:09.761-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "connection", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "dns", + "fortinet.firewall.craction": "54144", + "fortinet.firewall.crlevel": "low", + "fortinet.firewall.crscore": "5", + "fortinet.firewall.dstcountry": "Netherlands", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.sessionid": "435234", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "warning", + "log.offset": 571, + "network.community_id": "1:3UJ+CJ3YHclw01NEh4cnwf958wY=", + "network.iana_number": "17", + "network.protocol": "dns", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "newfirewall", + "observer.product": "Fortigate", + "observer.serial_number": "newrouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.1.6", + "8.8.8.8" + ], + "rule.category": "unscanned", + "rule.id": "26", + "rule.name": "elasticnewruleset", + "rule.ruleset": "policy", + "rule.uuid": "2345de-b143-52134d8-6654f-4654sdfg16f431", + "service.type": "fortinet", + "source.ip": "192.168.1.6", + "source.port": 53438, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:11:51.000-05:00", + "destination.as.number": 40386, + "destination.as.organization.name": "Bloomip Inc.", + "destination.bytes": 65446, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.6.4.7", + "destination.packets": 1045601, + "destination.port": 6000, + "event.action": "accept", + "event.category": [ + "network" + ], + "event.code": "0000000020", + "event.dataset": "fortinet.firewall", + "event.duration": 5462000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:11:51.390-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "connection", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "accept", + "fortinet.firewall.applist": "policylist", + "fortinet.firewall.dstcountry": "Netherlands", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.rcvddelta": "728", + "fortinet.firewall.sentdelta": "576", + "fortinet.firewall.sessionid": "4352", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vwlid": "0", + "input.type": "log", + "log.level": "notice", + "log.offset": 1163, + "network.bytes": 504096, + "network.community_id": "1:1+gwRFW+FnJQJZjzI/5oD2giJeY=", + "network.iana_number": "17", + "network.packets": 1769018, + "network.protocol": "portname", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "newfirewall", + "observer.product": "Fortigate", + "observer.serial_number": "newrouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.10.10", + "8.6.4.7" + ], + "rule.category": "unknown", + "rule.id": "3426", + "rule.name": "newruleelastic", + "rule.ruleset": "policy", + "rule.uuid": "1765de8-5a13-765da73fdsfa1c", + "service.type": "fortinet", + "source.as.number": 4808, + "source.as.organization.name": "China Unicom Beijing Province Network", + "source.bytes": 438650, + "source.geo.city_name": "Beijing", + "source.geo.continent_name": "Asia", + "source.geo.country_iso_code": "CN", + "source.geo.country_name": "China", + "source.geo.location.lat": 39.9288, + "source.geo.location.lon": 116.3889, + "source.geo.region_iso_code": "CN-BJ", + "source.geo.region_name": "Beijing", + "source.ip": "192.168.10.10", + "source.nat.ip": "123.123.123.123", + "source.nat.port": 60964, + "source.packets": 723417, + "source.port": 6000, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:11:48.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 20, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "2001:4860:4860::8888", + "destination.packets": 0, + "event.action": "accept", + "event.category": [ + "network" + ], + "event.code": "0001000014", + "event.dataset": "fortinet.firewall", + "event.duration": 42000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:11:48.751-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "connection", + "end", + "protocol" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "accept", + "fortinet.firewall.identifier": "0", + "fortinet.firewall.sessionid": "6542345", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "local", + "fortinet.firewall.trandisp": "noop", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 1897, + "network.application": "icmp6/25/0", + "network.bytes": 3034, + "network.community_id": "1:ajyH1GcZSUXhLMFORcVo2L1sA1Y=", + "network.iana_number": "58", + "network.packets": 4, + "network.protocol": "icmp6/1/0", + "network.transport": "ipv6-icmp", + "network.type": "ipv6", + "observer.egress.interface.name": "unknown0", + "observer.ingress.interface.name": "port1", + "observer.name": "newfirewall", + "observer.product": "Fortigate", + "observer.serial_number": "newrouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "2001:4860:4860::8888" + ], + "rule.category": "unscanned", + "rule.id": "0", + "rule.ruleset": "someotherpolicy", + "service.type": "fortinet", + "source.as.number": 15169, + "source.as.organization.name": "Google LLC", + "source.bytes": 3014, + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 37.751, + "source.geo.location.lon": -97.822, + "source.ip": "2001:4860:4860::8888", + "source.packets": 4, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T13:10:57.000-04:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 10, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.packets": 40, + "event.action": "accept", + "event.category": [ + "network" + ], + "event.code": "0001000014", + "event.dataset": "fortinet.firewall", + "event.duration": 20000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T13:10:57.509-04:00", + "event.timezone": "-0400", + "event.type": [ + "allowed", + "connection", + "end", + "protocol" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "accept", + "fortinet.firewall.dstcountry": "Norway", + "fortinet.firewall.identifier": "61", + "fortinet.firewall.sessionid": "123", + "fortinet.firewall.srccountry": "Netherlands", + "fortinet.firewall.srcintfrole": "wan", + "fortinet.firewall.subtype": "local", + "fortinet.firewall.trandisp": "noop", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 2447, + "network.application": "PING", + "network.bytes": 10, + "network.community_id": "1:e4Ubz/EgdwpC5IEhMK4GmP2pwJM=", + "network.iana_number": "1", + "network.packets": 40, + "network.protocol": "ping", + "network.transport": "icmp", + "network.type": "ipv4", + "observer.egress.interface.name": "unknown0", + "observer.ingress.interface.name": "wan1", + "observer.name": "newfirewall", + "observer.product": "Fortigate", + "observer.serial_number": "newrouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "8.8.8.8", + "9.7.7.7" + ], + "rule.category": "unscanned", + "rule.id": "0", + "rule.ruleset": "rulepolicy", + "service.type": "fortinet", + "source.bytes": 0, + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 37.751, + "source.geo.location.lon": -97.822, + "source.ip": "9.7.7.7", + "source.packets": 0, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:14:39.000-05:00", + "destination.ip": "192.168.100.100", + "destination.port": 1235, + "event.action": "ip-conn", + "event.category": [ + "network" + ], + "event.code": "0000000011", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:14:39.841-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "connection", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "ip-conn", + "fortinet.firewall.authserver": "FSSO_newfsso", + "fortinet.firewall.craction": "63332144", + "fortinet.firewall.crlevel": "low", + "fortinet.firewall.crscore": "5", + "fortinet.firewall.dstcountry": "Reserved", + "fortinet.firewall.sessionid": "54234", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "warning", + "log.offset": 2993, + "network.community_id": "1:8S1phidNTgIiEGM89KsStyENoH8=", + "network.iana_number": "17", + "network.protocol": "udp/12302", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "newinterface", + "observer.ingress.interface.name": "port1", + "observer.name": "firewall3", + "observer.product": "Fortigate", + "observer.serial_number": "oldfwid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.1.1", + "192.168.100.100" + ], + "related.user": [ + "elasticsuper" + ], + "rule.category": "unscanned", + "rule.id": "49", + "rule.name": "oldpolicyname", + "rule.ruleset": "policy", + "rule.uuid": "654cc-b6542-53467u8-e45234-1566casd35f7836", + "service.type": "fortinet", + "source.ip": "192.168.1.1", + "source.port": 62493, + "source.user.name": "elasticsuper", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:14:28.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 77654, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.packets": 70, + "destination.port": 442, + "event.action": "close", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 126000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:14:29.291-05:00", + "event.timezone": "-0500", + "event.type": [ + "connection", + "denied", + "end", + "protocol" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "close", + "fortinet.firewall.appact": "detected", + "fortinet.firewall.appid": "43540", + "fortinet.firewall.applist": "someapplist", + "fortinet.firewall.apprisk": "elevated", + "fortinet.firewall.authserver": "FSSO_something", + "fortinet.firewall.countapp": "1", + "fortinet.firewall.countweb": "1", + "fortinet.firewall.craction": "6144", + "fortinet.firewall.crlevel": "low", + "fortinet.firewall.crscore": "5", + "fortinet.firewall.dstcountry": "Netherlands", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.lanin": "1406", + "fortinet.firewall.lanout": "146506", + "fortinet.firewall.sessionid": "2345", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "block", + "fortinet.firewall.vd": "root", + "fortinet.firewall.vwlid": "4", + "fortinet.firewall.vwlquality": "Seq_num(3), alive, selected", + "fortinet.firewall.wanin": "1130", + "fortinet.firewall.wanout": "6671", + "input.type": "log", + "log.level": "notice", + "log.offset": 3656, + "network.application": "Skype.Portals", + "network.bytes": 78577, + "network.community_id": "1:a9EOn6Ei99BmsI8Wi5+qyGjIUgI=", + "network.iana_number": "6", + "network.packets": 183, + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "firewall3", + "observer.product": "Fortigate", + "observer.serial_number": "oldfwid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.50.50", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Collaboration", + "rule.id": "2365", + "rule.name": "someoldpolicyname", + "rule.ruleset": "policy", + "rule.uuid": "654644c-b064-fdgdf3425-f003-1234ghdf682e05f", + "service.type": "fortinet", + "source.as.number": 14618, + "source.as.organization.name": "Amazon.com, Inc.", + "source.bytes": 923, + "source.geo.city_name": "Ashburn", + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "US", + "source.geo.country_name": "United States", + "source.geo.location.lat": 39.0481, + "source.geo.location.lon": -77.4728, + "source.geo.region_iso_code": "US-VA", + "source.geo.region_name": "Virginia", + "source.ip": "192.168.50.50", + "source.nat.ip": "23.23.23.23", + "source.nat.port": 603, + "source.packets": 113, + "source.port": 56603, + "source.user.group.name": "testgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-31T06:42:54.000Z", + "destination.bytes": 0, + "destination.ip": "230.1.1.2", + "destination.packets": 0, + "destination.port": 7878, + "event.action": "accept", + "event.category": [ + "network" + ], + "event.code": "0002000012", + "event.dataset": "fortinet.firewall", + "event.duration": 22000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-03-31T13:42:52.000Z", + "event.type": [ + "allowed", + "connection", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "accept", + "fortinet.firewall.dstcountry": "Reserved", + "fortinet.firewall.sessionid": "1162", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.subtype": "multicast", + "fortinet.firewall.trandisp": "noop", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "notice", + "log.offset": 4660, + "network.bytes": 5940, + "network.community_id": "1:2HKGEYlW4AJ/Af+zmajWDRu3kog=", + "network.iana_number": "17", + "network.packets": 11, + "network.protocol": "udp/7878", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port25", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "172.16.200.55", + "230.1.1.2" + ], + "rule.category": "unscanned", + "rule.id": "1", + "rule.ruleset": "multicast-policy", + "service.type": "fortinet", + "source.bytes": 5940, + "source.ip": "172.16.200.55", + "source.packets": 11, + "source.port": 60660, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-10T14:18:54.000Z", + "destination.as.number": 20940, + "destination.as.organization.name": "Akamai International B.V.", + "destination.bytes": 0, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "104.80.88.154", + "destination.packets": 0, + "destination.port": 443, + "event.action": "accept", + "event.category": [ + "network" + ], + "event.code": "0004000017", + "event.dataset": "fortinet.firewall", + "event.duration": 10000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-10T21:18:54.021Z", + "event.type": [ + "connection", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "accept", + "fortinet.firewall.countips": "1", + "fortinet.firewall.craction": "32768", + "fortinet.firewall.crscore": "5", + "fortinet.firewall.dstcountry": "United States", + "fortinet.firewall.rcvddelta": "0", + "fortinet.firewall.sentdelta": "0", + "fortinet.firewall.sessionid": "2193276", + "fortinet.firewall.srccountry": "Canada", + "fortinet.firewall.subtype": "sniffer", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "allow", + "fortinet.firewall.utmref": "65162-7772", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 5177, + "network.bytes": 0, + "network.community_id": "1:xA35Yo5iuXuJBnFVsWZvOqdphyc=", + "network.iana_number": "6", + "network.packets": 0, + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port1", + "observer.ingress.interface.name": "port1", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "104.80.88.154", + "208.91.114.4" + ], + "rule.category": "unscanned", + "rule.id": "3", + "rule.ruleset": "sniffer", + "service.type": "fortinet", + "source.as.number": 40934, + "source.as.organization.name": "Fortinet Inc.", + "source.bytes": 0, + "source.geo.city_name": "Surrey", + "source.geo.continent_name": "North America", + "source.geo.country_iso_code": "CA", + "source.geo.country_name": "Canada", + "source.geo.location.lat": 49.1963, + "source.geo.location.lon": -122.8106, + "source.geo.region_iso_code": "CA-BC", + "source.geo.region_name": "British Columbia", + "source.ip": "208.91.114.4", + "source.nat.ip": "0.0.0.0", + "source.nat.port": 0, + "source.packets": 0, + "source.port": 50463, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-13T11:45:04.000Z", + "destination.bytes": 2286, + "destination.ip": "172.16.200.55", + "destination.packets": 6, + "destination.port": 80, + "event.action": "close", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 1000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-13T18:45:04.815Z", + "event.type": [ + "connection", + "denied", + "end", + "protocol" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "close", + "fortinet.firewall.appid": "15893", + "fortinet.firewall.applist": "g-default", + "fortinet.firewall.apprisk": "medium", + "fortinet.firewall.countapp": "1", + "fortinet.firewall.countav": "1", + "fortinet.firewall.craction": "2", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.dstcountry": "Reserved", + "fortinet.firewall.dstuuid": "187d6f46-5c86-51e9-70a0-fadcfc349c3e", + "fortinet.firewall.lanin": "92", + "fortinet.firewall.lanout": "92", + "fortinet.firewall.mastersrcmac": "a2:e9:00:ec:40:01", + "fortinet.firewall.osname": "Ubuntu", + "fortinet.firewall.sessionid": "359260", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcserver": "0", + "fortinet.firewall.srcuuid": "48420c8a-5c88-51e9-0424-a37f9e74621e", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "block", + "fortinet.firewall.utmref": "65497-770", + "fortinet.firewall.vd": "vdom1", + "fortinet.firewall.wanin": "313", + "fortinet.firewall.wanout": "92", + "input.type": "log", + "log.level": "notice", + "log.offset": 5814, + "network.application": "HTTP.BROWSER", + "network.bytes": 2698, + "network.community_id": "1:mS2/WPDX46+WauGLEZvCIQ/IKK0=", + "network.iana_number": "6", + "network.packets": 12, + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port11", + "observer.ingress.interface.name": "port12", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.55" + ], + "rule.category": "Web-Client", + "rule.id": "4", + "rule.ruleset": "policy", + "rule.uuid": "3888b41a-5c88-51e9-cb32-1c32c66b4edf", + "service.type": "fortinet", + "source.bytes": 412, + "source.ip": "10.1.100.11", + "source.mac": "a2:e9:00:ec:40:01", + "source.nat.ip": "172.16.200.2", + "source.nat.port": 60446, + "source.packets": 6, + "source.port": 60446, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-13T16:29:50.000Z", + "destination.as.number": 42831, + "destination.as.organization.name": "UK Dedicated Servers Limited", + "destination.bytes": 3138, + "destination.geo.city_name": "Coventry", + "destination.geo.continent_name": "Europe", + "destination.geo.country_iso_code": "GB", + "destination.geo.country_name": "United Kingdom", + "destination.geo.location.lat": 52.382, + "destination.geo.location.lon": -1.5874, + "destination.geo.region_iso_code": "GB-COV", + "destination.geo.region_name": "Coventry", + "destination.ip": "185.244.31.158", + "destination.packets": 5, + "destination.port": 80, + "event.action": "close", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 5000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-13T23:29:50.452Z", + "event.type": [ + "connection", + "denied", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "close", + "fortinet.firewall.countweb": "1", + "fortinet.firewall.craction": "4194304", + "fortinet.firewall.crscore": "30", + "fortinet.firewall.dstcountry": "Germany", + "fortinet.firewall.dstuuid": "ae28f494-5735-51e9-f247-d1d2ce663f4b", + "fortinet.firewall.mastersrcmac": "a2:e9:00:ec:40:01", + "fortinet.firewall.osname": "Ubuntu", + "fortinet.firewall.sessionid": "381780", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcserver": "0", + "fortinet.firewall.srcuuid": "ae28f494-5735-51e9-f247-d1d2ce663f4b", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "block", + "fortinet.firewall.utmref": "65497-796", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "notice", + "log.offset": 6777, + "network.bytes": 3874, + "network.community_id": "1:6Q3s77giRtaDlbjtG7Qfum6LzEk=", + "network.iana_number": "6", + "network.packets": 19, + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port11", + "observer.ingress.interface.name": "port12", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "185.244.31.158" + ], + "rule.category": "unscanned", + "rule.id": "1", + "rule.ruleset": "policy", + "rule.uuid": "ccb269e0-5735-51e9-a218-a397dd08b7eb", + "service.type": "fortinet", + "source.bytes": 736, + "source.ip": "10.1.100.11", + "source.mac": "a2:e9:00:ec:40:01", + "source.nat.ip": "172.16.200.2", + "source.nat.port": 44258, + "source.packets": 14, + "source.port": 44258, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-15T17:58:10.000Z", + "destination.bytes": 9112, + "destination.ip": "172.16.200.55", + "destination.packets": 8, + "destination.port": 80, + "event.action": "close", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 89000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-16T00:58:09.000Z", + "event.type": [ + "connection", + "denied", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "close", + "fortinet.firewall.countips": "1", + "fortinet.firewall.craction": "4096", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.devcategory": "None", + "fortinet.firewall.devtype": "Unknown", + "fortinet.firewall.dstcountry": "Reserved", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.mastersrcmac": "00:0c:29:51:38:5e", + "fortinet.firewall.sessionid": "4017", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.srcserver": "0", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "block", + "fortinet.firewall.utmref": "0-302", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 7629, + "network.bytes": 9677, + "network.community_id": "1:h1lO9dsjUlBQibNPDwk2LSH5uV4=", + "network.iana_number": "6", + "network.packets": 17, + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port9", + "observer.ingress.interface.name": "port10", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.22", + "172.16.200.55" + ], + "rule.category": "unscanned", + "rule.id": "1", + "rule.ruleset": "policy", + "rule.uuid": "d8ce7a90-7763-51e9-e2be-741294c96f31", + "service.type": "fortinet", + "source.bytes": 565, + "source.ip": "10.1.100.22", + "source.mac": "00:0c:29:51:38:5e", + "source.nat.ip": "172.16.200.10", + "source.nat.port": 46810, + "source.packets": 9, + "source.port": 46810, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-15T17:45:34.000Z", + "destination.as.number": 16509, + "destination.as.organization.name": "Amazon.com, Inc.", + "destination.bytes": 5266, + "destination.geo.city_name": "Ashburn", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 39.0481, + "destination.geo.location.lon": -77.4728, + "destination.geo.region_iso_code": "US-VA", + "destination.geo.region_name": "Virginia", + "destination.ip": "52.216.177.83", + "destination.packets": 12, + "destination.port": 443, + "event.action": "server-rst", + "event.category": [ + "network" + ], + "event.code": "0000000013", + "event.dataset": "fortinet.firewall", + "event.duration": 5000000000, + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-16T00:45:34.000Z", + "event.type": [ + "connection", + "denied", + "end" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "server-rst", + "fortinet.firewall.countdlp": "1", + "fortinet.firewall.craction": "262144", + "fortinet.firewall.crlevel": "low", + "fortinet.firewall.crscore": "5", + "fortinet.firewall.devcategory": "None", + "fortinet.firewall.devtype": "Unknown", + "fortinet.firewall.dstcountry": "United States", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.lanin": "753", + "fortinet.firewall.lanout": "753", + "fortinet.firewall.mastersrcmac": "00:0c:29:51:38:5e", + "fortinet.firewall.sessionid": "3423", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.srcserver": "0", + "fortinet.firewall.subtype": "forward", + "fortinet.firewall.trandisp": "snat", + "fortinet.firewall.type": "traffic", + "fortinet.firewall.utmaction": "block", + "fortinet.firewall.utmref": "0-152", + "fortinet.firewall.vd": "root", + "fortinet.firewall.wanin": "43936", + "fortinet.firewall.wanout": "710", + "input.type": "log", + "log.level": "notice", + "log.offset": 8377, + "network.bytes": 7580, + "network.community_id": "1:J2etn+6EN21BXHPPJZQeRpj+C3k=", + "network.iana_number": "6", + "network.packets": 45, + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port9", + "observer.ingress.interface.name": "port10", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.22", + "52.216.177.83" + ], + "rule.category": "unscanned", + "rule.id": "1", + "rule.ruleset": "policy", + "rule.uuid": "d8ce7a90-7763-51e9-e2be-741294c96f31", + "service.type": "fortinet", + "source.bytes": 2314, + "source.ip": "10.1.100.22", + "source.mac": "00:0c:29:51:38:5e", + "source.nat.ip": "172.16.200.10", + "source.nat.port": 50354, + "source.packets": 33, + "source.port": 50354, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + } +] \ No newline at end of file diff --git a/x-pack/filebeat/module/fortinet/firewall/test/utm.log b/x-pack/filebeat/module/fortinet/firewall/test/utm.log new file mode 100644 index 00000000000..32bce5c6cc4 --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/utm.log @@ -0,0 +1,28 @@ +<188>date=2020-04-23 time=12:17:48 devname="testswitch1" devid="somerouterid" logid="0316013056" type="utm" subtype="webfilter" eventtype="ftgd_blk" level="warning" vd="root" eventtime=1587230269052907555 tz="-0500" policyid=100602 sessionid=1234 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 srcport=61930 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=443 dstintf="wan1" dstintfrole="wan" proto=6 service="HTTPS" hostname="elastic.co" profile="elasticruleset" action="blocked" reqtype="direct" url="/config/" sentbyte=1152 rcvdbyte=1130 direction="outgoing" msg="URL belongs to a denied category in policy" method="domain" cat=76 catdesc="Internet Telephony" +<189>date=2020-04-23 time=12:17:45 devname="testswitch1" devid="somerouterid" logid="0317013312" type="utm" subtype="webfilter" eventtype="ftgd_allow" level="notice" vd="root" eventtime=1587230266314799756 tz="-0500" policyid=38 sessionid=543234 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 srcport=65236 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=443 dstintf="wan1" dstintfrole="wan" proto=6 service="HTTPS" hostname="elastic.co" profile="elasticruleset" action="passthrough" reqtype="direct" url="/" sentbyte=3545 rcvdbyte=6812 direction="outgoing" msg="URL belongs to an allowed category in policy" method="domain" cat=23 catdesc="Web-based Email" +<190>date=2020-04-23 time=13:17:35 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1587230255061492894 tz="-0400" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=59790 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=12 sessionid=453234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.co" incidentserialno=23465 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="test.elastic.co" +<190>date=2020-04-23 time=13:17:35 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1591788391 tz="-0400" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=59790 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=12 sessionid=453234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.co" incidentserialno=23465 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="test.elastic.co" +<189>date=2020-04-23 time=12:17:29 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230249360109339 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=53430 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="test" xid=2234 qname="elastic.example.com" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8" msg="Domain is monitored" action="pass" cat=23 catdesc="Web-based Email" +<189>date=2020-04-23 time=12:17:29 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230249360109339 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=53430 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="test" xid=2234 qname="elastic.example.com" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8, 8.8.4.4" msg="Domain is monitored" action="pass" cat=23 catdesc="Web-based Email" +<190>date=2020-04-23 time=12:17:11 devname="testswitch1" devid="somerouterid" logid="1059028704" type="utm" subtype="app-ctrl" eventtype="signature" level="information" vd="root" eventtime=1587230232148674303 tz="-0500" appid=40568 user="elasticuser" group="elasticgroup" authserver="elasticauth" srcip=192.168.2.1 dstip=8.8.8.8 srcport=63012 dstport=443 srcintf="port1" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 service="SSL" direction="outgoing" policyid=100602 sessionid=543234 applist="elasticruleset" action="pass" appcat="Web.Client" app="HTTPS.BROWSER" hostname="elastic.no" incidentserialno=54323 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" +<189>date=2020-04-23 time=12:17:04 devname="testswitch1" devid="somerouterid" logid="1501054802" type="utm" subtype="dns" eventtype="dns-response" level="notice" vd="root" eventtime=1587230224712900694 tz="-0500" policyid=26 sessionid=5432 srcip=192.168.2.1 srcport=54438 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="elastictest" xid=2352 qname="elastic.co" qtype="A" qtypeval=1 qclass="IN" ipaddr="8.8.8.8" msg="Domain is monitored" action="pass" cat=93 catdesc="Remote Access" +<190>date=2020-04-23 time=12:17:12 devname="testswitch1" devid="somerouterid" logid="1500054000" type="utm" subtype="dns" eventtype="dns-query" level="information" vd="root" eventtime=1587230232658642672 tz="-0500" policyid=26 sessionid=543234 srcip=192.168.2.1 srcport=54788 srcintf="port1" srcintfrole="lan" dstip=8.8.8.8 dstport=53 dstintf="wan1" dstintfrole="wan" proto=17 profile="elastictest" xid=235 qname="elastic.co" qtype="A" qtypeval=1 qclass="IN" +<189>date=2020-04-23 time=13:15:18 devname="testswitch2" devid="someotherid" logid="1700062001" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="notice" vd="root" eventtime=1587230118838592454 tz="-0400" policyid=12 sessionid=42346234 service="HTTPS" user="elasticuser2" group="elasticgroup2" profile="somecerts" srcip=192.168.2.1 srcport=59726 dstip=8.8.4.4 dstport=443 srcintf="LAN" srcintfrole="lan" dstintf="wan1" dstintfrole="wan" proto=6 action="passthrough" msg="Server certificate passed" reason="untrusted-cert" +<190>date=2019-05-15 time=18:03:36 logid="1059028704" type="utm" subtype="app-ctrl" eventtype="app-ctrl-all" level="information" vd="root" eventtime=1557968615 appid=40568 srcip=10.1.100.22 dstip=195.8.215.136 srcport=50798 dstport=443 srcintf="port10" srcintfrole="lan" dstintf="port9" dstintfrole="wan" proto=6 service="HTTPS" direction="outgoing" policyid=1 sessionid=4414 applist="block-social.media" appcat="Web.Client" app="HTTPS.BROWSER" action="pass" hostname="www.dailymotion.com" incidentserialno=1962906680 url="/" msg="Web.Client: HTTPS.BROWSER," apprisk="medium" scertcname="*.dailymotion.com" scertissuer="DigiCert SHA2 High Assurance Server CA" +<190>date=2019-05-13 time=11:45:03 logid="0211008192" type="utm" subtype="virus" eventtype="infected" level="warning" vd="vdom1" eventtime=1557773103767393505 msg="File is infected." action="blocked" service="HTTP" sessionid=359260 srcip=10.1.100.11 dstip=172.16.200.55 srcport=60446 dstport=80 srcintf="port12" srcintfrole="undefined" dstintf="port11" dstintfrole="undefined" policyid=4 proto=6 direction="incoming" filename="eicar.com" quarskip="File-was-not-quarantined." virus="EICAR_TEST_FILE" dtype="Virus" ref="http://www.fortinet.com/ve?vn=EICAR_TEST_FILE" virusid=2172 url="http://172.16.200.55/virus/eicar.com" profile="g-default" agent="curl/7.47.0" analyticscksum="275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f" analyticssubmit="false" crscore=50 craction=2 crlevel="critical" +<189>date=2019-05-13 time=16:29:45 logid="0316013056" type="utm" subtype="webfilter" eventtype="ftgd_blk" level="warning" vd="vdom1" eventtime=1557790184975119738 policyid=1 sessionid=381780 srcip=10.1.100.11 srcport=44258 srcintf="port12" srcintfrole="undefined" dstip=185.244.31.158 dstport=80 dstintf="port11" dstintfrole="undefined" proto=6 service="HTTP" hostname="morrishittu.ddns.net" profile="test-webfilter" action="blocked" reqtype="direct" url="/" sentbyte=84 rcvdbyte=0 direction="outgoing" msg="URL belongs to a denied category in policy" method="domain" cat=26 catdesc="Malicious Websites" crscore=30 craction=4194304 crlevel="high" +<189>date=2019-05-15 time=17:56:41 logid="0419016384" type="utm" subtype="ips" eventtype="signature" level="alert" vd="root" eventtime=1557968201 severity="critical" srcip=10.1.100.22 srccountry="Reserved" dstip=172.16.200.55 srcintf="port10" srcintfrole="lan" dstintf="port9" dstintfrole="wan" sessionid=4017 action="dropped" proto=6 service="HTTP" policyid=1 attack="Adobe.Flash.newfunction.Handling.Code.Execution" srcport=46810 dstport=80 hostname="172.16.200.55" url="/ips/sig1.pdf" direction="incoming" attackid=23305 profile="block-critical-ips" ref="http://www.fortinet.com/ids/VID23305" incidentserialno=582633933 msg="applications3: Adobe.Flash.newfunction.Handling.Code.Execution," crscore=50 craction=4096 crlevel="critical" +<189>date=2019-05-13 time=17:05:59 logid="0720018433" type="utm" subtype="anomaly" eventtype="anomaly" level="alert" vd="vdom1" eventtime=1557792359461869329 severity="critical" srcip=10.1.100.11 srccountry="Reserved" dstip=172.16.200.55 srcintf="port12" srcintfrole="undefined" sessionid=0 action="clear_session" proto=1 service="PING" count=1 attack="icmp_flood" icmpid="0x1474" icmptype="0x08" icmpcode="0x00" attackid=16777316 policyid=1 policytype="DoS-policy" ref="http://www.fortinet.com/ids/VID16777316" msg="anomaly: icmp_flood, 51 > threshold 50" crscore=50 craction=4096 crlevel="critical" +<189>date=2019-05-15 time=17:45:30 logid="0954024576" type="utm" subtype="dlp" eventtype="dlp" level="warning" vd="root" eventtime=1557967528 filteridx=1 dlpextra="dlp-file-size11" filtertype="file-type" filtercat="file" severity="medium" policyid=1 sessionid=3423 epoch=1740880646 eventid=0 srcip=10.1.100.22 srcport=50354 srcintf="port10" srcintfrole="lan" dstip=52.216.177.83 dstport=443 dstintf="port9" dstintfrole="wan" proto=6 service="HTTPS" filetype="pdf" direction="incoming" action="block" hostname="fortinetweb.s3.amazonaws.com" url="/docs.fortinet.com/v2/attachments/be3d0e3d-4b62-11e9-94bf-00505692583a/FortiOS_6.2.0_Log_Reference.pdf" agent="Wget/1.17.1" filename="FortiOS_6.2.0_Log_Reference.pdf" filesize=16360 profile="dlp-file-type-test" +<189>date=2019-05-15 time=16:18:17 logid="1601061010" type="utm" subtype="ssh" eventtype="ssh-channel" level="warning" vd="vdom1" eventtime=1557962296 policyid=1 sessionid=344 profile="ssh-deepscan" srcip=10.1.100.11 srcport=43580 dstip=172.16.200.44 dstport=22 srcintf="port21" srcintfrole="undefined" dstintf="port23" dstintfrole="undefined" proto=6 action="blocked" direction="outgoing" login="root" channeltype="shell" +<189>date=2019-03-28 time=10:44:53 logid="1700062002" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553795092 policyid=1 sessionid=10796 service="HTTPS" srcip=10.1.100.66 srcport=43602 dstip=104.154.89.105 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="blocked" msg="Server certificate blocked" reason="block-cert-invalid" +<189>date=2019-03-28 time=10:51:17 logid="1700062002" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553795476 policyid=1 sessionid=11110 service="HTTPS" srcip=10.1.100.66 srcport=49076 dstip=172.16.200.99 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="blocked" msg="Server certificate blocked" reason="block-cert-untrusted" +<189>date=2019-03-28 time=10:55:43 logid="1700062002" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553795742 policyid=1 sessionid=11334 service="HTTPS" srcip=10.1.100.66 srcport=49082 dstip=172.16.200.99 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="blocked" msg="Server certificate blocked" reason="block-cert-req" +<189>date=2019-03-28 time=10:57:42 logid="1700062053" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553795861 policyid=1 sessionid=11424 service="SMTPS" profile="block-unsupported-ssl" srcip=10.1.100.66 srcport=41296 dstip=172.16.200.99 dstport=8080 srcintf="port2" srcintfrole="undefined" dstintf=unknown-0 dstintfrole="undefined" proto=6 action="blocked" msg="Connection is blocked due to unsupported SSL traffic" reason="malformed input" +<189>date=2019-03-28 time=11:00:17 logid="1700062002" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553796016 policyid=1 sessionid=11554 service="HTTPS" srcip=10.1.100.66 srcport=49088 dstip=172.16.200.99 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="blocked" msg="Server certificate blocked" reason="block-cert-sni-mismatch" +<189>date=2019-03-28 time=11:02:07 logid="1700062000" type="utm" subtype="ssl" eventtype="ssl-anomalies" level="warning" vd="vdom1" eventtime=1553796126 policyid=1 sessionid=11667 service="HTTPS" srcip=10.1.100.66 srcport=49096 dstip=172.16.200.99 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="blocked" msg="Certificate blacklisted" certhash="1115ec1857ed7f937301ff5e02f6b0681cf2ec4e" reason="Other" +<189>date=2019-03-28 time=11:06:05 logid="1701062003" type="utm" subtype="ssl" eventtype="ssl-exempt" level="notice" vd="vdom1" eventtime=1553796363 policyid=1 sessionid=11871 service="HTTPS" srcip=10.1.100.66 srcport=47384 dstip=50.18.221.132 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="exempt" msg="SSL connection exempted" reason="exempt-whitelist" +<189>date=2019-03-28 time=11:09:14 logid="1701062003" type="utm" subtype="ssl" eventtype="ssl-exempt" level="notice" vd="vdom1" eventtime=1553796553 policyid=1 sessionid=12079 service="HTTPS" srcip=10.1.100.66 srcport=49102 dstip=172.16.200.99 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="exempt" msg="SSL connection exempted" reason="exempt-addr" +<189>date=2019-03-28 time=11:10:55 logid="1701062003" type="utm" subtype="ssl" eventtype="ssl-exempt" level="notice" vd="vdom1" eventtime=1553796654 policyid=1 sessionid=12171 service="HTTPS" srcip=10.1.100.66 srcport=47390 dstip=50.18.221.132 dstport=443 srcintf="port2" srcintfrole="undefined" dstintf="port3" dstintfrole="undefined" proto=6 action="exempt" msg="SSL connection exempted" reason="exempt-ftgd-cat" +<189>date=2019-05-15 time=16:28:17 logid="1800063000" type="utm" subtype="cifs" eventtype="cifs-filefilter" level="warning" vd="vdom1" eventtime=1557962895 msg="File was blocked by file filter." direction="incoming" action="blocked" service="CIFS" srcip=10.1.100.11 dstip=172.16.200.44 srcport=56348 dstport=445 srcintf="port21" srcintfrole="undefined" dstintf="port23" dstintfrole="undefined" policyid=1 proto=16 profile="cifs" filesize="13824" filename="sample\\test.xls" filtername="1" filetype="msoffice" +<189>date=2021-03-30 time=14:04:58 devname="htd-Kfgt1" devid="FGT50EXXXXXXXXXX" logid="0211008192" type="utm" subtype="virus" eventtype="infected" level="warning" vd="root" eventtime=1617080699214283280 tz="+0900" policyid=5 msg="File is infected." action="blocked" service="HTTP" sessionid=20572875 srcip=192.168.2.1 dstip=150.95.25.17 srcport=54987 dstport=80 srcintf="port10" srcintfrole="undefined" dstintf="wan1" dstintfrole="wan" proto=6 direction="incoming" filename="eicar_test_virus.zip" quarskip="File-was-not-quarantined." virus="EICAR_TEST_FILE" dtype="Virus" ref="http://www.fortinet.com/ve?vn=EICAR_TEST_FILE" virusid=2172 url="http://lhsp.s206.xrea.com/download/eicar_test_virus.zip" profile="default" agent="Chrome/89.0.4389.90" analyticscksum="8a18d44ed122e6257863169d9a219946f4229f57b1d49ca0493b8366338230e8" analyticssubmit="false" crscore=50 craction=2 crlevel="critical" diff --git a/x-pack/filebeat/module/fortinet/firewall/test/utm.log-expected.json b/x-pack/filebeat/module/fortinet/firewall/test/utm.log-expected.json new file mode 100644 index 00000000000..0d1729a6ceb --- /dev/null +++ b/x-pack/filebeat/module/fortinet/firewall/test/utm.log-expected.json @@ -0,0 +1,1894 @@ +[ + { + "@timestamp": "2020-04-23T12:17:48.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 1130, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "0316013056", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:49.052-05:00", + "event.timezone": "-0500", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.authserver": "elasticauth", + "fortinet.firewall.cat": "76", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "ftgd_blk", + "fortinet.firewall.method": "domain", + "fortinet.firewall.reqtype": "direct", + "fortinet.firewall.sessionid": "1234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "webfilter", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "warning", + "log.offset": 0, + "message": "URL belongs to a denied category in policy", + "network.bytes": 2282, + "network.community_id": "1:jkPSHzqUyADbT5XNqPV58Do0VVg=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Internet Telephony", + "rule.id": "100602", + "rule.ruleset": "elasticruleset", + "service.type": "fortinet", + "source.bytes": 1152, + "source.ip": "192.168.2.1", + "source.port": 61930, + "source.user.group.name": "elasticgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "elastic.co", + "url.original": "/config/", + "url.path": "/config/" + }, + { + "@timestamp": "2020-04-23T12:17:45.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.bytes": 6812, + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 443, + "event.action": "passthrough", + "event.category": [ + "network" + ], + "event.code": "0317013312", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:46.314-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "passthrough", + "fortinet.firewall.authserver": "elasticauth", + "fortinet.firewall.cat": "23", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "ftgd_allow", + "fortinet.firewall.method": "domain", + "fortinet.firewall.reqtype": "direct", + "fortinet.firewall.sessionid": "543234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "webfilter", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 707, + "message": "URL belongs to an allowed category in policy", + "network.bytes": 10357, + "network.community_id": "1:6x4JdfgMVssswnIG5C8mkIbszLU=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Web-based Email", + "rule.id": "38", + "rule.ruleset": "elasticruleset", + "service.type": "fortinet", + "source.bytes": 3545, + "source.ip": "192.168.2.1", + "source.port": 65236, + "source.user.group.name": "elasticgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "elastic.co", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2020-04-23T13:17:35.000-04:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 443, + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1059028704", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T13:17:35.061-04:00", + "event.timezone": "-0400", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.appid": "40568", + "fortinet.firewall.apprisk": "medium", + "fortinet.firewall.authserver": "elasticauth", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "signature", + "fortinet.firewall.incidentserialno": "23465", + "fortinet.firewall.sessionid": "453234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "app-ctrl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 1409, + "message": "Web.Client: HTTPS.BROWSER,", + "network.application": "HTTPS.BROWSER", + "network.community_id": "1:jz8Ul9WJmuEeHGbclqOri0hlDwI=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "ssl", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "LAN", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Web-Client", + "rule.id": "12", + "rule.ruleset": "elasticruleset", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 59790, + "source.user.group.name": "elasticgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "tls.server.x509.subject.common_name": "test.elastic.co", + "url.domain": "elastic.co", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2020-04-23T13:17:35.000-04:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 443, + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1059028704", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-06-10T07:26:31.000-04:00", + "event.timezone": "-0400", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.appid": "40568", + "fortinet.firewall.apprisk": "medium", + "fortinet.firewall.authserver": "elasticauth", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "signature", + "fortinet.firewall.incidentserialno": "23465", + "fortinet.firewall.sessionid": "453234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "app-ctrl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 2112, + "message": "Web.Client: HTTPS.BROWSER,", + "network.application": "HTTPS.BROWSER", + "network.community_id": "1:jz8Ul9WJmuEeHGbclqOri0hlDwI=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "ssl", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "LAN", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Web-Client", + "rule.id": "12", + "rule.ruleset": "elasticruleset", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 59790, + "source.user.group.name": "elasticgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "tls.server.x509.subject.common_name": "test.elastic.co", + "url.domain": "elastic.co", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2020-04-23T12:17:29.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 53, + "dns.id": "2234", + "dns.question.class": "IN", + "dns.question.name": "elastic.example.com", + "dns.question.type": "A", + "dns.resolved_ip": [ + "8.8.8.8" + ], + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1501054802", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:29.360-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "info" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.cat": "23", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "dns-response", + "fortinet.firewall.qtypeval": "1", + "fortinet.firewall.sessionid": "543234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "dns", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 2806, + "message": "Domain is monitored", + "network.community_id": "1:TAkI/Dqjd84P0/IOYFsZ/dciGyk=", + "network.iana_number": "17", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.hosts": [ + "elastic.example.com" + ], + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "rule.category": "Web-based Email", + "rule.id": "26", + "rule.ruleset": "test", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 53430, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:17:29.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 53, + "dns.id": "2234", + "dns.question.class": "IN", + "dns.question.name": "elastic.example.com", + "dns.question.type": "A", + "dns.resolved_ip": [ + "8.8.4.4", + "8.8.8.8" + ], + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1501054802", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:29.360-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "info" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.cat": "23", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "dns-response", + "fortinet.firewall.qtypeval": "1", + "fortinet.firewall.sessionid": "543234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "dns", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 3356, + "message": "Domain is monitored", + "network.community_id": "1:TAkI/Dqjd84P0/IOYFsZ/dciGyk=", + "network.iana_number": "17", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.hosts": [ + "elastic.example.com" + ], + "related.ip": [ + "192.168.2.1", + "8.8.4.4", + "8.8.8.8" + ], + "rule.category": "Web-based Email", + "rule.id": "26", + "rule.ruleset": "test", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 53430, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:17:11.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 443, + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1059028704", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:12.148-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.appid": "40568", + "fortinet.firewall.apprisk": "medium", + "fortinet.firewall.authserver": "elasticauth", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "signature", + "fortinet.firewall.incidentserialno": "54323", + "fortinet.firewall.sessionid": "543234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "app-ctrl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 3915, + "message": "Web.Client: HTTPS.BROWSER,", + "network.application": "HTTPS.BROWSER", + "network.community_id": "1:SnL1O7SJ70dFEAbmKNOL/cs7Yis=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "ssl", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "related.user": [ + "elasticuser" + ], + "rule.category": "Web-Client", + "rule.id": "100602", + "rule.ruleset": "elasticruleset", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 63012, + "source.user.group.name": "elasticgroup", + "source.user.name": "elasticuser", + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "elastic.no", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2020-04-23T12:17:04.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 53, + "dns.id": "2352", + "dns.question.class": "IN", + "dns.question.name": "elastic.co", + "dns.question.type": "A", + "dns.resolved_ip": [ + "8.8.8.8" + ], + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1501054802", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2020-04-18T12:17:04.712-05:00", + "event.timezone": "-0500", + "event.type": [ + "allowed", + "info" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.cat": "93", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "dns-response", + "fortinet.firewall.qtypeval": "1", + "fortinet.firewall.sessionid": "5432", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "dns", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 4595, + "message": "Domain is monitored", + "network.community_id": "1:oi4FzZ6cP1JOcUzJW8FLs4MB4BM=", + "network.iana_number": "17", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.hosts": [ + "elastic.co" + ], + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "rule.category": "Remote Access", + "rule.id": "26", + "rule.ruleset": "elastictest", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 54438, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T12:17:12.000-05:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.8.8", + "destination.port": 53, + "dns.id": "235", + "dns.question.class": "IN", + "dns.question.name": "elastic.co", + "dns.question.type": "A", + "event.category": [ + "network" + ], + "event.code": "1500054000", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.start": "2020-04-18T12:17:12.658-05:00", + "event.timezone": "-0500", + "event.type": [ + "info" + ], + "fileset.name": "firewall", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "dns-query", + "fortinet.firewall.qtypeval": "1", + "fortinet.firewall.sessionid": "543234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "dns", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 5139, + "network.community_id": "1:2iITe7baBXn6W2kcSCMlLR6YGNw=", + "network.iana_number": "17", + "network.transport": "udp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port1", + "observer.name": "testswitch1", + "observer.product": "Fortigate", + "observer.serial_number": "somerouterid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.hosts": [ + "elastic.co" + ], + "related.ip": [ + "192.168.2.1", + "8.8.8.8" + ], + "rule.id": "26", + "rule.ruleset": "elastictest", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 54788, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2020-04-23T13:15:18.000-04:00", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.751, + "destination.geo.location.lon": -97.822, + "destination.ip": "8.8.4.4", + "destination.port": 443, + "event.action": "passthrough", + "event.category": [ + "network" + ], + "event.code": "1700062001", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "untrusted-cert", + "event.start": "2020-04-18T13:15:18.838-04:00", + "event.timezone": "-0400", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "passthrough", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "42346234", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "notice", + "log.offset": 5598, + "message": "Server certificate passed", + "network.community_id": "1:DPYPEQ6CL+DsivLJV6otkkVV6S8=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "LAN", + "observer.name": "testswitch2", + "observer.product": "Fortigate", + "observer.serial_number": "someotherid", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "192.168.2.1", + "8.8.4.4" + ], + "related.user": [ + "elasticuser2" + ], + "rule.id": "12", + "rule.ruleset": "somecerts", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 59726, + "source.user.group.name": "elasticgroup2", + "source.user.name": "elasticuser2", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-15T18:03:36.000Z", + "destination.as.number": 41690, + "destination.as.organization.name": "Dailymotion S.A.", + "destination.geo.continent_name": "Europe", + "destination.geo.country_iso_code": "FR", + "destination.geo.country_name": "France", + "destination.geo.location.lat": 48.8582, + "destination.geo.location.lon": 2.3387, + "destination.ip": "195.8.215.136", + "destination.port": 443, + "event.action": "pass", + "event.category": [ + "network" + ], + "event.code": "1059028704", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-16T01:03:35.000Z", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "pass", + "fortinet.firewall.appid": "40568", + "fortinet.firewall.apprisk": "medium", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "app-ctrl-all", + "fortinet.firewall.incidentserialno": "1962906680", + "fortinet.firewall.sessionid": "4414", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "app-ctrl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "information", + "log.offset": 6128, + "message": "Web.Client: HTTPS.BROWSER,", + "network.application": "HTTPS.BROWSER", + "network.community_id": "1:IOM2CCpAacVSdldWr1f2al8LJv4=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port9", + "observer.ingress.interface.name": "port10", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.22", + "195.8.215.136" + ], + "rule.category": "Web-Client", + "rule.id": "1", + "rule.ruleset": "block-social.media", + "service.type": "fortinet", + "source.ip": "10.1.100.22", + "source.port": 50798, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "tls.server.issuer": "DigiCert SHA2 High Assurance Server CA", + "tls.server.x509.issuer.common_name": "DigiCert SHA2 High Assurance Server CA", + "tls.server.x509.subject.common_name": "*.dailymotion.com", + "url.domain": "www.dailymotion.com", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2019-05-13T11:45:03.000Z", + "destination.ip": "172.16.200.55", + "destination.port": 80, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "0211008192", + "event.dataset": "fortinet.firewall", + "event.kind": "alert", + "event.module": "fortinet", + "event.outcome": "success", + "event.reference": "http://www.fortinet.com/ve?vn=EICAR_TEST_FILE", + "event.start": "2019-05-13T18:45:03.767Z", + "event.type": [ + "denied" + ], + "file.name": "eicar.com", + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.analyticscksum": "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f", + "fortinet.firewall.analyticssubmit": "false", + "fortinet.firewall.craction": "2", + "fortinet.firewall.crlevel": "critical", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.eventtype": "infected", + "fortinet.firewall.quarskip": "File-was-not-quarantined.", + "fortinet.firewall.sessionid": "359260", + "fortinet.firewall.subtype": "virus", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "fortinet.firewall.virus": "EICAR_TEST_FILE", + "fortinet.firewall.virusid": "2172", + "input.type": "log", + "log.level": "warning", + "log.offset": 6788, + "message": "File is infected.", + "network.community_id": "1:mS2/WPDX46+WauGLEZvCIQ/IKK0=", + "network.direction": "inbound", + "network.iana_number": "6", + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port11", + "observer.ingress.interface.name": "port12", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.55" + ], + "rule.id": "4", + "rule.ruleset": "g-default", + "service.type": "fortinet", + "source.ip": "10.1.100.11", + "source.port": 60446, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "172.16.200.55", + "url.extension": "com", + "url.original": "http://172.16.200.55/virus/eicar.com", + "url.path": "/virus/eicar.com", + "url.scheme": "http", + "user_agent.device.name": "Other", + "user_agent.name": "curl", + "user_agent.original": "curl/7.47.0", + "user_agent.version": "7.47.0", + "vulnerability.category": "Virus" + }, + { + "@timestamp": "2019-05-13T16:29:45.000Z", + "destination.as.number": 42831, + "destination.as.organization.name": "UK Dedicated Servers Limited", + "destination.bytes": 0, + "destination.geo.city_name": "Coventry", + "destination.geo.continent_name": "Europe", + "destination.geo.country_iso_code": "GB", + "destination.geo.country_name": "United Kingdom", + "destination.geo.location.lat": 52.382, + "destination.geo.location.lon": -1.5874, + "destination.geo.region_iso_code": "GB-COV", + "destination.geo.region_name": "Coventry", + "destination.ip": "185.244.31.158", + "destination.port": 80, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "0316013056", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-13T23:29:44.975Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.cat": "26", + "fortinet.firewall.craction": "4194304", + "fortinet.firewall.crlevel": "high", + "fortinet.firewall.crscore": "30", + "fortinet.firewall.eventtype": "ftgd_blk", + "fortinet.firewall.method": "domain", + "fortinet.firewall.reqtype": "direct", + "fortinet.firewall.sessionid": "381780", + "fortinet.firewall.subtype": "webfilter", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 7596, + "message": "URL belongs to a denied category in policy", + "network.bytes": 84, + "network.community_id": "1:6Q3s77giRtaDlbjtG7Qfum6LzEk=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port11", + "observer.ingress.interface.name": "port12", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "185.244.31.158" + ], + "rule.category": "Malicious Websites", + "rule.id": "1", + "rule.ruleset": "test-webfilter", + "service.type": "fortinet", + "source.bytes": 84, + "source.ip": "10.1.100.11", + "source.port": 44258, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "morrishittu.ddns.net", + "url.original": "/", + "url.path": "/" + }, + { + "@timestamp": "2019-05-15T17:56:41.000Z", + "destination.ip": "172.16.200.55", + "destination.port": 80, + "event.action": "dropped", + "event.category": [ + "intrusion_detection", + "network" + ], + "event.code": "0419016384", + "event.dataset": "fortinet.firewall", + "event.kind": "alert", + "event.module": "fortinet", + "event.outcome": "success", + "event.reference": "http://www.fortinet.com/ids/VID23305", + "event.start": "2019-05-16T00:56:41.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "dropped", + "fortinet.firewall.attack": "Adobe.Flash.newfunction.Handling.Code.Execution", + "fortinet.firewall.attackid": "23305", + "fortinet.firewall.craction": "4096", + "fortinet.firewall.crlevel": "critical", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "signature", + "fortinet.firewall.incidentserialno": "582633933", + "fortinet.firewall.sessionid": "4017", + "fortinet.firewall.severity": "critical", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "ips", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "alert", + "log.offset": 8243, + "message": "applications3: Adobe.Flash.newfunction.Handling.Code.Execution,", + "network.community_id": "1:h1lO9dsjUlBQibNPDwk2LSH5uV4=", + "network.direction": "inbound", + "network.iana_number": "6", + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port9", + "observer.ingress.interface.name": "port10", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.22", + "172.16.200.55" + ], + "rule.id": "1", + "rule.ruleset": "block-critical-ips", + "service.type": "fortinet", + "source.ip": "10.1.100.22", + "source.port": 46810, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "172.16.200.55", + "url.extension": "pdf", + "url.original": "/ips/sig1.pdf", + "url.path": "/ips/sig1.pdf" + }, + { + "@timestamp": "2019-05-13T17:05:59.000Z", + "destination.ip": "172.16.200.55", + "event.action": "clear_session", + "event.category": [ + "network" + ], + "event.code": "0720018433", + "event.dataset": "fortinet.firewall", + "event.kind": "alert", + "event.module": "fortinet", + "event.outcome": "success", + "event.reference": "http://www.fortinet.com/ids/VID16777316", + "event.start": "2019-05-14T00:05:59.461Z", + "fileset.name": "firewall", + "fortinet.firewall.action": "clear_session", + "fortinet.firewall.attack": "icmp_flood", + "fortinet.firewall.attackid": "16777316", + "fortinet.firewall.count": "1", + "fortinet.firewall.craction": "4096", + "fortinet.firewall.crlevel": "critical", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.eventtype": "anomaly", + "fortinet.firewall.icmpcode": "0x00", + "fortinet.firewall.icmpid": "0x1474", + "fortinet.firewall.icmptype": "0x08", + "fortinet.firewall.policytype": "DoS-policy", + "fortinet.firewall.sessionid": "0", + "fortinet.firewall.severity": "critical", + "fortinet.firewall.srccountry": "Reserved", + "fortinet.firewall.subtype": "anomaly", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "alert", + "log.offset": 8980, + "message": "anomaly: icmp_flood, 51 > threshold 50", + "network.community_id": "1:/EwPCnPnhunCBJc8C73Iy8WlrhM=", + "network.iana_number": "1", + "network.protocol": "ping", + "network.transport": "icmp", + "network.type": "ipv4", + "observer.ingress.interface.name": "port12", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.55" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.11", + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-15T17:45:30.000Z", + "destination.as.number": 16509, + "destination.as.organization.name": "Amazon.com, Inc.", + "destination.geo.city_name": "Ashburn", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 39.0481, + "destination.geo.location.lon": -77.4728, + "destination.geo.region_iso_code": "US-VA", + "destination.geo.region_name": "Virginia", + "destination.ip": "52.216.177.83", + "destination.port": 443, + "event.action": "block", + "event.category": [ + "network" + ], + "event.code": "0954024576", + "event.dataset": "fortinet.firewall", + "event.id": "0", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-16T00:45:28.000Z", + "event.type": [ + "denied" + ], + "file.extension": "pdf", + "file.name": "FortiOS_6.2.0_Log_Reference.pdf", + "file.size": 16360, + "fileset.name": "firewall", + "fortinet.firewall.action": "block", + "fortinet.firewall.dlpextra": "dlp-file-size11", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.epoch": "1740880646", + "fortinet.firewall.eventtype": "dlp", + "fortinet.firewall.filtercat": "file", + "fortinet.firewall.filteridx": "1", + "fortinet.firewall.filtertype": "file-type", + "fortinet.firewall.sessionid": "3423", + "fortinet.firewall.severity": "medium", + "fortinet.firewall.srcintfrole": "lan", + "fortinet.firewall.subtype": "dlp", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "input.type": "log", + "log.level": "warning", + "log.offset": 9581, + "network.community_id": "1:J2etn+6EN21BXHPPJZQeRpj+C3k=", + "network.direction": "inbound", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port9", + "observer.ingress.interface.name": "port10", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.22", + "52.216.177.83" + ], + "rule.id": "1", + "rule.ruleset": "dlp-file-type-test", + "service.type": "fortinet", + "source.ip": "10.1.100.22", + "source.port": 50354, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "fortinetweb.s3.amazonaws.com", + "url.extension": "pdf", + "url.original": "/docs.fortinet.com/v2/attachments/be3d0e3d-4b62-11e9-94bf-00505692583a/FortiOS_6.2.0_Log_Reference.pdf", + "url.path": "/docs.fortinet.com/v2/attachments/be3d0e3d-4b62-11e9-94bf-00505692583a/FortiOS_6.2.0_Log_Reference.pdf", + "user_agent.device.name": "Other", + "user_agent.name": "Wget", + "user_agent.original": "Wget/1.17.1", + "user_agent.version": "1.17.1" + }, + { + "@timestamp": "2019-05-15T16:18:17.000Z", + "destination.ip": "172.16.200.44", + "destination.port": 22, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1601061010", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-15T23:18:16.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.channeltype": "shell", + "fortinet.firewall.eventtype": "ssh-channel", + "fortinet.firewall.login": "root", + "fortinet.firewall.sessionid": "344", + "fortinet.firewall.subtype": "ssh", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 10337, + "network.community_id": "1:EfgLxImMmBMDbP6vbTV8jZe5r64=", + "network.direction": "outbound", + "network.iana_number": "6", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port23", + "observer.ingress.interface.name": "port21", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.44" + ], + "rule.id": "1", + "rule.ruleset": "ssh-deepscan", + "service.type": "fortinet", + "source.ip": "10.1.100.11", + "source.port": 43580, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T10:44:53.000Z", + "destination.as.number": 15169, + "destination.as.organization.name": "Google LLC", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 38.6583, + "destination.geo.location.lon": -77.2481, + "destination.geo.region_iso_code": "US-VA", + "destination.geo.region_name": "Virginia", + "destination.ip": "104.154.89.105", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062002", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "block-cert-invalid", + "event.start": "2019-03-28T17:44:52.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "10796", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 10760, + "message": "Server certificate blocked", + "network.community_id": "1:3JAdUt0lSMifcZEPoVJn1SC8tdE=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "104.154.89.105" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 43602, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T10:51:17.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062002", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "block-cert-untrusted", + "event.start": "2019-03-28T17:51:16.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "11110", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 11187, + "message": "Server certificate blocked", + "network.community_id": "1:+CuXSKFw5mhoSjpYrUOYxAYOzaU=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 49076, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T10:55:43.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062002", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "block-cert-req", + "event.start": "2019-03-28T17:55:42.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "11334", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 11615, + "message": "Server certificate blocked", + "network.community_id": "1:xeLbgVy2CNJ3q/bxUWxBBt6cGKM=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 49082, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T10:57:42.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 8080, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062053", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "malformed input", + "event.start": "2019-03-28T17:57:41.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "11424", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 12037, + "message": "Connection is blocked due to unsupported SSL traffic", + "network.community_id": "1:PohXhOT4cmeI1agRXluSxRuXkvM=", + "network.iana_number": "6", + "network.protocol": "smtps", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "unknown-0", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "rule.ruleset": "block-unsupported-ssl", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 41296, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T11:00:17.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062002", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "block-cert-sni-mismatch", + "event.start": "2019-03-28T18:00:16.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "11554", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 12521, + "message": "Server certificate blocked", + "network.community_id": "1:gg6I8tZchtWCopsLdNDN7E84ZbU=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 49088, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T11:02:07.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 443, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1700062000", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "Other", + "event.start": "2019-03-28T18:02:06.000Z", + "event.type": [ + "denied" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.certhash": "1115ec1857ed7f937301ff5e02f6b0681cf2ec4e", + "fortinet.firewall.eventtype": "ssl-anomalies", + "fortinet.firewall.sessionid": "11667", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 12952, + "message": "Certificate blacklisted", + "network.community_id": "1:/tDtPynm8PUjA7+AXhG5maLXczU=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 49096, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T11:06:05.000Z", + "destination.as.number": 16509, + "destination.as.organization.name": "Amazon.com, Inc.", + "destination.geo.city_name": "San Jose", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.3388, + "destination.geo.location.lon": -121.8914, + "destination.geo.region_iso_code": "US-CA", + "destination.geo.region_name": "California", + "destination.ip": "50.18.221.132", + "destination.port": 443, + "event.action": "exempt", + "event.category": [ + "network" + ], + "event.code": "1701062003", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "exempt-whitelist", + "event.start": "2019-03-28T18:06:03.000Z", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "exempt", + "fortinet.firewall.eventtype": "ssl-exempt", + "fortinet.firewall.sessionid": "11871", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "notice", + "log.offset": 13414, + "message": "SSL connection exempted", + "network.community_id": "1:o4PokgFFuw7PzgWghlu55zAVFAQ=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "50.18.221.132" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 47384, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T11:09:14.000Z", + "destination.ip": "172.16.200.99", + "destination.port": 443, + "event.action": "exempt", + "event.category": [ + "network" + ], + "event.code": "1701062003", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "exempt-addr", + "event.start": "2019-03-28T18:09:13.000Z", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "exempt", + "fortinet.firewall.eventtype": "ssl-exempt", + "fortinet.firewall.sessionid": "12079", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "notice", + "log.offset": 13830, + "message": "SSL connection exempted", + "network.community_id": "1:q6lEK+V8YAiHWchN6gVt5i1lbm8=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "172.16.200.99" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 49102, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-03-28T11:10:55.000Z", + "destination.as.number": 16509, + "destination.as.organization.name": "Amazon.com, Inc.", + "destination.geo.city_name": "San Jose", + "destination.geo.continent_name": "North America", + "destination.geo.country_iso_code": "US", + "destination.geo.country_name": "United States", + "destination.geo.location.lat": 37.3388, + "destination.geo.location.lon": -121.8914, + "destination.geo.region_iso_code": "US-CA", + "destination.geo.region_name": "California", + "destination.ip": "50.18.221.132", + "destination.port": 443, + "event.action": "exempt", + "event.category": [ + "network" + ], + "event.code": "1701062003", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.reason": "exempt-ftgd-cat", + "event.start": "2019-03-28T18:10:54.000Z", + "event.type": [ + "allowed" + ], + "fileset.name": "firewall", + "fortinet.firewall.action": "exempt", + "fortinet.firewall.eventtype": "ssl-exempt", + "fortinet.firewall.sessionid": "12171", + "fortinet.firewall.subtype": "ssl", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "notice", + "log.offset": 14241, + "message": "SSL connection exempted", + "network.community_id": "1:fc1FAipY32n2Km+Fczx/L3cxBPE=", + "network.iana_number": "6", + "network.protocol": "https", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "port3", + "observer.ingress.interface.name": "port2", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.66", + "50.18.221.132" + ], + "rule.id": "1", + "service.type": "fortinet", + "source.ip": "10.1.100.66", + "source.port": 47390, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2019-05-15T16:28:17.000Z", + "destination.ip": "172.16.200.44", + "destination.port": 445, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "1800063000", + "event.dataset": "fortinet.firewall", + "event.kind": "event", + "event.module": "fortinet", + "event.outcome": "success", + "event.start": "2019-05-15T23:28:15.000Z", + "event.type": [ + "denied" + ], + "file.extension": "msoffice", + "file.name": "sample\\\\test.xls", + "file.size": 13824, + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.eventtype": "cifs-filefilter", + "fortinet.firewall.filtername": "1", + "fortinet.firewall.subtype": "cifs", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "vdom1", + "input.type": "log", + "log.level": "warning", + "log.offset": 14656, + "message": "File was blocked by file filter.", + "network.direction": "inbound", + "network.iana_number": "16", + "network.protocol": "cifs", + "network.type": "ipv4", + "observer.egress.interface.name": "port23", + "observer.ingress.interface.name": "port21", + "observer.product": "Fortigate", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "10.1.100.11", + "172.16.200.44" + ], + "rule.id": "1", + "rule.ruleset": "cifs", + "service.type": "fortinet", + "source.ip": "10.1.100.11", + "source.port": 56348, + "tags": [ + "fortinet-firewall", + "forwarded" + ] + }, + { + "@timestamp": "2021-03-30T14:04:58.000+09:00", + "destination.as.number": 135161, + "destination.as.organization.name": "GMO-Z com NetDesign Holdings Co., Ltd.", + "destination.geo.continent_name": "Asia", + "destination.geo.country_iso_code": "SG", + "destination.geo.country_name": "Singapore", + "destination.geo.location.lat": 1.3667, + "destination.geo.location.lon": 103.8, + "destination.ip": "150.95.25.17", + "destination.port": 80, + "event.action": "blocked", + "event.category": [ + "network" + ], + "event.code": "0211008192", + "event.dataset": "fortinet.firewall", + "event.kind": "alert", + "event.module": "fortinet", + "event.outcome": "success", + "event.reference": "http://www.fortinet.com/ve?vn=EICAR_TEST_FILE", + "event.start": "2021-03-30T14:04:59.214+09:00", + "event.timezone": "+0900", + "event.type": [ + "denied" + ], + "file.name": "eicar_test_virus.zip", + "fileset.name": "firewall", + "fortinet.firewall.action": "blocked", + "fortinet.firewall.analyticscksum": "8a18d44ed122e6257863169d9a219946f4229f57b1d49ca0493b8366338230e8", + "fortinet.firewall.analyticssubmit": "false", + "fortinet.firewall.craction": "2", + "fortinet.firewall.crlevel": "critical", + "fortinet.firewall.crscore": "50", + "fortinet.firewall.dstintfrole": "wan", + "fortinet.firewall.eventtype": "infected", + "fortinet.firewall.quarskip": "File-was-not-quarantined.", + "fortinet.firewall.sessionid": "20572875", + "fortinet.firewall.subtype": "virus", + "fortinet.firewall.type": "utm", + "fortinet.firewall.vd": "root", + "fortinet.firewall.virus": "EICAR_TEST_FILE", + "fortinet.firewall.virusid": "2172", + "input.type": "log", + "log.level": "warning", + "log.offset": 15165, + "message": "File is infected.", + "network.community_id": "1:YYsQyWVI+C/2EYyLGlhTY/RydM8=", + "network.direction": "inbound", + "network.iana_number": "6", + "network.protocol": "http", + "network.transport": "tcp", + "network.type": "ipv4", + "observer.egress.interface.name": "wan1", + "observer.ingress.interface.name": "port10", + "observer.name": "htd-Kfgt1", + "observer.product": "Fortigate", + "observer.serial_number": "FGT50EXXXXXXXXXX", + "observer.type": "firewall", + "observer.vendor": "Fortinet", + "related.ip": [ + "150.95.25.17", + "192.168.2.1" + ], + "rule.id": "5", + "rule.ruleset": "default", + "service.type": "fortinet", + "source.ip": "192.168.2.1", + "source.port": 54987, + "tags": [ + "fortinet-firewall", + "forwarded" + ], + "url.domain": "lhsp.s206.xrea.com", + "url.extension": "zip", + "url.original": "http://lhsp.s206.xrea.com/download/eicar_test_virus.zip", + "url.path": "/download/eicar_test_virus.zip", + "url.scheme": "http", + "user_agent.device.name": "Other", + "user_agent.name": "Chrome", + "user_agent.original": "Chrome/89.0.4389.90", + "user_agent.version": "89.0.4389.90", + "vulnerability.category": "Virus" + } +] \ No newline at end of file diff --git a/x-pack/filebeat/module/fortinet/fortimail/ingest/pipeline.yml b/x-pack/filebeat/module/fortinet/fortimail/ingest/pipeline.yml index e4ed20982ec..817ec9d3e14 100644 --- a/x-pack/filebeat/module/fortinet/fortimail/ingest/pipeline.yml +++ b/x-pack/filebeat/module/fortinet/fortimail/ingest/pipeline.yml @@ -10,6 +10,11 @@ processors: - user_agent: field: user_agent.original ignore_missing: true + # Serial Number + - set: + field: observer.serial_number + value: "{{rsa.misc.hardware_id}}" + ignore_empty_value: true # IP Geolocation Lookup - geoip: field: source.ip diff --git a/x-pack/filebeat/module/fortinet/fortimail/test/generated.log-expected.json b/x-pack/filebeat/module/fortinet/fortimail/test/generated.log-expected.json index 767991be1fa..74bbff2c61a 100644 --- a/x-pack/filebeat/module/fortinet/fortimail/test/generated.log-expected.json +++ b/x-pack/filebeat/module/fortinet/fortimail/test/generated.log-expected.json @@ -11,6 +11,7 @@ "log.level": "high", "log.offset": 0, "observer.product": "FortiMail", + "observer.serial_number": "pexe", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "boNemoe", @@ -42,6 +43,7 @@ "log.level": "very-high", "log.offset": 117, "observer.product": "FortiMail", + "observer.serial_number": "ehend", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -85,6 +87,7 @@ "log.level": "low", "log.offset": 355, "observer.product": "FortiMail", + "observer.serial_number": "doeiu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -127,6 +130,7 @@ "log.level": "high", "log.offset": 534, "observer.product": "FortiMail", + "observer.serial_number": "uipexea", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -167,6 +171,7 @@ "log.level": "very-high", "log.offset": 706, "observer.product": "FortiMail", + "observer.serial_number": "itati", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -207,6 +212,7 @@ "log.level": "high", "log.offset": 873, "observer.product": "FortiMail", + "observer.serial_number": "llamcorp", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -247,6 +253,7 @@ "log.level": "very-high", "log.offset": 1039, "observer.product": "FortiMail", + "observer.serial_number": "enimad", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -284,6 +291,7 @@ "log.level": "low", "log.offset": 1206, "observer.product": "FortiMail", + "observer.serial_number": "taliqu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -327,6 +335,7 @@ "log.level": "very-high", "log.offset": 1442, "observer.product": "FortiMail", + "observer.serial_number": "smo", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -367,6 +376,7 @@ "log.level": "low", "log.offset": 1619, "observer.product": "FortiMail", + "observer.serial_number": "ntutl", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "edquiano", @@ -399,6 +409,7 @@ "log.offset": 1745, "network.direction": "inbound", "observer.product": "FortiMail", + "observer.serial_number": "idestla", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -441,6 +452,7 @@ "log.level": "high", "log.offset": 2075, "observer.product": "FortiMail", + "observer.serial_number": "amvolup", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -487,6 +499,7 @@ "log.level": "low", "log.offset": 2254, "observer.product": "FortiMail", + "observer.serial_number": "estiae", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -524,6 +537,7 @@ "log.level": "medium", "log.offset": 2424, "observer.product": "FortiMail", + "observer.serial_number": "oluptas", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "equat", @@ -555,6 +569,7 @@ "log.level": "high", "log.offset": 2546, "observer.product": "FortiMail", + "observer.serial_number": "abi", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "veniamq", @@ -590,6 +605,7 @@ "log.offset": 2668, "network.direction": "inbound", "observer.product": "FortiMail", + "observer.serial_number": "orem", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -641,6 +657,7 @@ "log.level": "very-high", "log.offset": 3053, "observer.product": "FortiMail", + "observer.serial_number": "didunt", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -680,6 +697,7 @@ "log.level": "high", "log.offset": 3256, "observer.product": "FortiMail", + "observer.serial_number": "tvolu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -718,6 +736,7 @@ "log.level": "very-high", "log.offset": 3450, "observer.product": "FortiMail", + "observer.serial_number": "stru", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -754,6 +773,7 @@ "log.level": "high", "log.offset": 3632, "observer.product": "FortiMail", + "observer.serial_number": "uatD", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -795,6 +815,7 @@ "log.level": "very-high", "log.offset": 3829, "observer.product": "FortiMail", + "observer.serial_number": "tenimad", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -837,6 +858,7 @@ "log.level": "high", "log.offset": 4059, "observer.product": "FortiMail", + "observer.serial_number": "intoc", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -880,6 +902,7 @@ "log.level": "high", "log.offset": 4286, "observer.product": "FortiMail", + "observer.serial_number": "quamqua", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -921,6 +944,7 @@ "log.level": "high", "log.offset": 4458, "observer.product": "FortiMail", + "observer.serial_number": "dolore", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -960,6 +984,7 @@ "log.level": "low", "log.offset": 4705, "observer.product": "FortiMail", + "observer.serial_number": "uaUten", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1005,6 +1030,7 @@ "log.level": "low", "log.offset": 4884, "observer.product": "FortiMail", + "observer.serial_number": "aec", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1048,6 +1074,7 @@ "log.level": "very-high", "log.offset": 5130, "observer.product": "FortiMail", + "observer.serial_number": "amcor", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1089,6 +1116,7 @@ "log.level": "very-high", "log.offset": 5319, "observer.product": "FortiMail", + "observer.serial_number": "tpersp", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1135,6 +1163,7 @@ "log.level": "very-high", "log.offset": 5501, "observer.product": "FortiMail", + "observer.serial_number": "dipisci", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1175,6 +1204,7 @@ "log.level": "low", "log.offset": 5672, "observer.product": "FortiMail", + "observer.serial_number": "nte", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1214,6 +1244,7 @@ "log.level": "very-high", "log.offset": 5854, "observer.product": "FortiMail", + "observer.serial_number": "ptateve", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1259,6 +1290,7 @@ "log.offset": 6048, "network.direction": "inbound", "observer.product": "FortiMail", + "observer.serial_number": "atione", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1312,6 +1344,7 @@ "log.level": "medium", "log.offset": 6484, "observer.product": "FortiMail", + "observer.serial_number": "liquide", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1359,6 +1392,7 @@ "log.level": "very-high", "log.offset": 6680, "observer.product": "FortiMail", + "observer.serial_number": "taedict", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1400,6 +1434,7 @@ "log.level": "very-high", "log.offset": 6869, "observer.product": "FortiMail", + "observer.serial_number": "occ", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1439,6 +1474,7 @@ "log.level": "very-high", "log.offset": 7062, "observer.product": "FortiMail", + "observer.serial_number": "temUten", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1480,6 +1516,7 @@ "log.level": "medium", "log.offset": 7254, "observer.product": "FortiMail", + "observer.serial_number": "quide", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1517,6 +1554,7 @@ "log.level": "medium", "log.offset": 7432, "observer.product": "FortiMail", + "observer.serial_number": "inrepr", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1563,6 +1601,7 @@ "log.level": "very-high", "log.offset": 7619, "observer.product": "FortiMail", + "observer.serial_number": "riosa", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1609,6 +1648,7 @@ "log.level": "medium", "log.offset": 7804, "observer.product": "FortiMail", + "observer.serial_number": "undeom", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1649,6 +1689,7 @@ "log.level": "medium", "log.offset": 7970, "observer.product": "FortiMail", + "observer.serial_number": "edictasu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1689,6 +1730,7 @@ "log.level": "low", "log.offset": 8144, "observer.product": "FortiMail", + "observer.serial_number": "lumqu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1729,6 +1771,7 @@ "log.level": "low", "log.offset": 8301, "observer.product": "FortiMail", + "observer.serial_number": "uamqu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.email.email_dst": "emUte", @@ -1760,6 +1803,7 @@ "log.level": "very-high", "log.offset": 8447, "observer.product": "FortiMail", + "observer.serial_number": "umS", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1806,6 +1850,7 @@ "log.level": "low", "log.offset": 8642, "observer.product": "FortiMail", + "observer.serial_number": "urau", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1848,6 +1893,7 @@ "log.level": "very-high", "log.offset": 8825, "observer.product": "FortiMail", + "observer.serial_number": "upta", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "exerci", @@ -1879,6 +1925,7 @@ "log.level": "medium", "log.offset": 8954, "observer.product": "FortiMail", + "observer.serial_number": "mmodoco", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -1925,6 +1972,7 @@ "log.level": "medium", "log.offset": 9146, "observer.product": "FortiMail", + "observer.serial_number": "porinc", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -1966,6 +2014,7 @@ "log.level": "high", "log.offset": 9328, "observer.product": "FortiMail", + "observer.serial_number": "itse", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2009,6 +2058,7 @@ "log.level": "medium", "log.offset": 9547, "observer.product": "FortiMail", + "observer.serial_number": "iciade", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2049,6 +2099,7 @@ "log.level": "high", "log.offset": 9718, "observer.product": "FortiMail", + "observer.serial_number": "colabori", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2090,6 +2141,7 @@ "log.level": "high", "log.offset": 9919, "observer.product": "FortiMail", + "observer.serial_number": "atcupid", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2127,6 +2179,7 @@ "log.level": "low", "log.offset": 10141, "observer.product": "FortiMail", + "observer.serial_number": "gna", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2167,6 +2220,7 @@ "log.level": "high", "log.offset": 10309, "observer.product": "FortiMail", + "observer.serial_number": "uiineavo", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2210,6 +2264,7 @@ "log.level": "low", "log.offset": 10537, "observer.product": "FortiMail", + "observer.serial_number": "lupta", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.email.email_dst": "ulapa", @@ -2242,6 +2297,7 @@ "log.level": "low", "log.offset": 10701, "observer.product": "FortiMail", + "observer.serial_number": "obeataev", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2278,6 +2334,7 @@ "log.level": "very-high", "log.offset": 10876, "observer.product": "FortiMail", + "observer.serial_number": "inim", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2318,6 +2375,7 @@ "log.level": "low", "log.offset": 11044, "observer.product": "FortiMail", + "observer.serial_number": "itaedict", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "ptatemse", @@ -2349,6 +2407,7 @@ "log.level": "low", "log.offset": 11167, "observer.product": "FortiMail", + "observer.serial_number": "eleumi", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2389,6 +2448,7 @@ "log.level": "very-high", "log.offset": 11329, "observer.product": "FortiMail", + "observer.serial_number": "nimadmin", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "tocca", @@ -2420,6 +2480,7 @@ "log.level": "very-high", "log.offset": 11455, "observer.product": "FortiMail", + "observer.serial_number": "usant", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2462,6 +2523,7 @@ "log.level": "very-high", "log.offset": 11652, "observer.product": "FortiMail", + "observer.serial_number": "conseq", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2505,6 +2567,7 @@ "log.level": "very-high", "log.offset": 11887, "observer.product": "FortiMail", + "observer.serial_number": "ugiatqu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2548,6 +2611,7 @@ "log.level": "medium", "log.offset": 12120, "observer.product": "FortiMail", + "observer.serial_number": "Bonoru", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2594,6 +2658,7 @@ "log.level": "very-high", "log.offset": 12305, "observer.product": "FortiMail", + "observer.serial_number": "mquameiu", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2634,6 +2699,7 @@ "log.level": "medium", "log.offset": 12481, "observer.product": "FortiMail", + "observer.serial_number": "rumetMa", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2677,6 +2743,7 @@ "log.offset": 12656, "network.direction": "inbound", "observer.product": "FortiMail", + "observer.serial_number": "audant", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2730,6 +2797,7 @@ "log.level": "medium", "log.offset": 13066, "observer.product": "FortiMail", + "observer.serial_number": "emipsumq", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2776,6 +2844,7 @@ "log.level": "medium", "log.offset": 13249, "observer.product": "FortiMail", + "observer.serial_number": "lauda", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2816,6 +2885,7 @@ "log.level": "low", "log.offset": 13439, "observer.product": "FortiMail", + "observer.serial_number": "inibus", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -2852,6 +2922,7 @@ "log.level": "low", "log.offset": 13612, "observer.product": "FortiMail", + "observer.serial_number": "naaliq", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2899,6 +2970,7 @@ "log.level": "high", "log.offset": 13788, "observer.product": "FortiMail", + "observer.serial_number": "dolo", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2938,6 +3010,7 @@ "log.level": "high", "log.offset": 14016, "observer.product": "FortiMail", + "observer.serial_number": "imipsam", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -2988,6 +3061,7 @@ "log.offset": 14269, "network.protocol": "ipv6-icmp", "observer.product": "FortiMail", + "observer.serial_number": "econ", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3039,6 +3113,7 @@ "log.level": "very-high", "log.offset": 14586, "observer.product": "FortiMail", + "observer.serial_number": "atevelit", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3080,6 +3155,7 @@ "log.level": "low", "log.offset": 14795, "observer.product": "FortiMail", + "observer.serial_number": "ddo", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3128,6 +3204,7 @@ "log.offset": 15048, "network.direction": "internal", "observer.product": "FortiMail", + "observer.serial_number": "odit", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3181,6 +3258,7 @@ "log.level": "very-high", "log.offset": 15464, "observer.product": "FortiMail", + "observer.serial_number": "orsit", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3232,6 +3310,7 @@ "log.offset": 15674, "network.direction": "internal", "observer.product": "FortiMail", + "observer.serial_number": "quidol", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3285,6 +3364,7 @@ "log.level": "high", "log.offset": 16096, "observer.product": "FortiMail", + "observer.serial_number": "evelite", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "dolor", @@ -3316,6 +3396,7 @@ "log.level": "medium", "log.offset": 16221, "observer.product": "FortiMail", + "observer.serial_number": "itse", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "exeaco", @@ -3347,6 +3428,7 @@ "log.level": "medium", "log.offset": 16342, "observer.product": "FortiMail", + "observer.serial_number": "emvele", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3385,6 +3467,7 @@ "log.level": "very-high", "log.offset": 16528, "observer.product": "FortiMail", + "observer.serial_number": "aliq", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -3425,6 +3508,7 @@ "log.level": "high", "log.offset": 16695, "observer.product": "FortiMail", + "observer.serial_number": "pariatur", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3472,6 +3556,7 @@ "log.level": "low", "log.offset": 16891, "observer.product": "FortiMail", + "observer.serial_number": "imaven", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -3512,6 +3597,7 @@ "log.level": "medium", "log.offset": 17055, "observer.product": "FortiMail", + "observer.serial_number": "iade", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3559,6 +3645,7 @@ "log.level": "low", "log.offset": 17252, "observer.product": "FortiMail", + "observer.serial_number": "conse", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3605,6 +3692,7 @@ "log.level": "very-high", "log.offset": 17430, "observer.product": "FortiMail", + "observer.serial_number": "nvol", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "labor", @@ -3636,6 +3724,7 @@ "log.level": "medium", "log.offset": 17552, "observer.product": "FortiMail", + "observer.serial_number": "mwritte", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.user": [ @@ -3672,6 +3761,7 @@ "log.level": "high", "log.offset": 17731, "observer.product": "FortiMail", + "observer.serial_number": "vel", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "edutpers", @@ -3704,6 +3794,7 @@ "log.level": "medium", "log.offset": 17851, "observer.product": "FortiMail", + "observer.serial_number": "sBonoru", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3743,6 +3834,7 @@ "log.level": "medium", "log.offset": 18079, "observer.product": "FortiMail", + "observer.serial_number": "cid", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3790,6 +3882,7 @@ "log.level": "high", "log.offset": 18282, "observer.product": "FortiMail", + "observer.serial_number": "icta", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3839,6 +3932,7 @@ "log.level": "high", "log.offset": 18470, "observer.product": "FortiMail", + "observer.serial_number": "quaturve", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3886,6 +3980,7 @@ "log.offset": 18728, "network.direction": "unknown", "observer.product": "FortiMail", + "observer.serial_number": "eprehen", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3926,6 +4021,7 @@ "log.level": "low", "log.offset": 19025, "observer.product": "FortiMail", + "observer.serial_number": "tiumtot", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -3974,6 +4070,7 @@ "log.level": "medium", "log.offset": 19231, "observer.product": "FortiMail", + "observer.serial_number": "equ", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ @@ -4012,6 +4109,7 @@ "log.level": "very-high", "log.offset": 19466, "observer.product": "FortiMail", + "observer.serial_number": "sunt", "observer.type": "Firewall", "observer.vendor": "Fortinet", "rsa.internal.event_desc": "pta", @@ -4046,6 +4144,7 @@ "log.offset": 19589, "network.protocol": "igmp", "observer.product": "FortiMail", + "observer.serial_number": "ntutlabo", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.hosts": [ @@ -4097,6 +4196,7 @@ "log.level": "medium", "log.offset": 19902, "observer.product": "FortiMail", + "observer.serial_number": "int", "observer.type": "Firewall", "observer.vendor": "Fortinet", "related.ip": [ diff --git a/x-pack/filebeat/module/fortinet/fortimanager/ingest/pipeline.yml b/x-pack/filebeat/module/fortinet/fortimanager/ingest/pipeline.yml index b423b2203e4..146ed98dc9a 100644 --- a/x-pack/filebeat/module/fortinet/fortimanager/ingest/pipeline.yml +++ b/x-pack/filebeat/module/fortinet/fortimanager/ingest/pipeline.yml @@ -10,6 +10,11 @@ processors: - user_agent: field: user_agent.original ignore_missing: true + # Serial Number + - set: + field: observer.serial_number + value: "{{rsa.misc.hardware_id}}" + ignore_empty_value: true # URL - uri_parts: field: url.original diff --git a/x-pack/filebeat/module/fortinet/fortimanager/test/generated.log-expected.json b/x-pack/filebeat/module/fortinet/fortimanager/test/generated.log-expected.json index 8c635f632f8..19c8aaf4af0 100644 --- a/x-pack/filebeat/module/fortinet/fortimanager/test/generated.log-expected.json +++ b/x-pack/filebeat/module/fortinet/fortimanager/test/generated.log-expected.json @@ -22,6 +22,7 @@ "observer.egress.interface.name": "enp0s3068", "observer.ingress.interface.name": "eth5722", "observer.product": "FortiManager", + "observer.serial_number": "olab", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -90,6 +91,7 @@ "observer.egress.interface.name": "enp0s2581", "observer.ingress.interface.name": "enp0s208", "observer.product": "FortiManager", + "observer.serial_number": "tur", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.410", @@ -190,6 +192,7 @@ "observer.egress.interface.name": "enp0s3491", "observer.ingress.interface.name": "eth4496", "observer.product": "FortiManager", + "observer.serial_number": "olorema", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -257,6 +260,7 @@ "observer.egress.interface.name": "eth3391", "observer.ingress.interface.name": "eth3676", "observer.product": "FortiManager", + "observer.serial_number": "emq", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -326,6 +330,7 @@ "observer.egress.interface.name": "eth6096", "observer.ingress.interface.name": "lo1567", "observer.product": "FortiManager", + "observer.serial_number": "atuse", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.5670", @@ -427,6 +432,7 @@ "observer.egress.interface.name": "lo1120", "observer.ingress.interface.name": "enp0s33", "observer.product": "FortiManager", + "observer.serial_number": "ivelits", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.152", @@ -528,6 +534,7 @@ "observer.egress.interface.name": "enp0s1462", "observer.ingress.interface.name": "lo2857", "observer.product": "FortiManager", + "observer.serial_number": "remagn", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4059", @@ -628,6 +635,7 @@ "observer.egress.interface.name": "lo821", "observer.ingress.interface.name": "eth2591", "observer.product": "FortiManager", + "observer.serial_number": "ctetura", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -696,6 +704,7 @@ "observer.egress.interface.name": "lo1616", "observer.ingress.interface.name": "eth6448", "observer.product": "FortiManager", + "observer.serial_number": "stlabo", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.3917", @@ -797,6 +806,7 @@ "observer.egress.interface.name": "lo4901", "observer.ingress.interface.name": "eth4502", "observer.product": "FortiManager", + "observer.serial_number": "adip", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2580", @@ -897,6 +907,7 @@ "observer.egress.interface.name": "lo7114", "observer.ingress.interface.name": "lo4249", "observer.product": "FortiManager", + "observer.serial_number": "tquov", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -964,6 +975,7 @@ "observer.egress.interface.name": "lo2438", "observer.ingress.interface.name": "enp0s4046", "observer.product": "FortiManager", + "observer.serial_number": "tse", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1032,6 +1044,7 @@ "observer.egress.interface.name": "lo4367", "observer.ingress.interface.name": "eth651", "observer.product": "FortiManager", + "observer.serial_number": "eFi", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.3319", @@ -1132,6 +1145,7 @@ "observer.egress.interface.name": "lo5047", "observer.ingress.interface.name": "eth267", "observer.product": "FortiManager", + "observer.serial_number": "nBCSedut", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1200,6 +1214,7 @@ "observer.egress.interface.name": "eth4392", "observer.ingress.interface.name": "eth5968", "observer.product": "FortiManager", + "observer.serial_number": "ate", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.225", @@ -1300,6 +1315,7 @@ "observer.egress.interface.name": "enp0s3449", "observer.ingress.interface.name": "lo1208", "observer.product": "FortiManager", + "observer.serial_number": "atisund", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1367,6 +1383,7 @@ "observer.egress.interface.name": "enp0s2700", "observer.ingress.interface.name": "lo3642", "observer.product": "FortiManager", + "observer.serial_number": "item", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -1435,6 +1452,7 @@ "observer.egress.interface.name": "lo7672", "observer.ingress.interface.name": "eth4185", "observer.product": "FortiManager", + "observer.serial_number": "siuta", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1847", @@ -1536,6 +1554,7 @@ "observer.egress.interface.name": "eth3862", "observer.ingress.interface.name": "enp0s3071", "observer.product": "FortiManager", + "observer.serial_number": "hitec", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.760", @@ -1637,6 +1656,7 @@ "observer.egress.interface.name": "lo1586", "observer.ingress.interface.name": "eth7713", "observer.product": "FortiManager", + "observer.serial_number": "utaliqu", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4450", @@ -1738,6 +1758,7 @@ "observer.egress.interface.name": "eth1247", "observer.ingress.interface.name": "lo154", "observer.product": "FortiManager", + "observer.serial_number": "vol", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.7544", @@ -1839,6 +1860,7 @@ "observer.egress.interface.name": "lo3057", "observer.ingress.interface.name": "lo653", "observer.product": "FortiManager", + "observer.serial_number": "remips", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1710", @@ -1940,6 +1962,7 @@ "observer.egress.interface.name": "lo3472", "observer.ingress.interface.name": "eth2940", "observer.product": "FortiManager", + "observer.serial_number": "cor", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.5380", @@ -2041,6 +2064,7 @@ "observer.egress.interface.name": "lo3706", "observer.ingress.interface.name": "lo7416", "observer.product": "FortiManager", + "observer.serial_number": "min", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2110,6 +2134,7 @@ "observer.egress.interface.name": "enp0s3903", "observer.ingress.interface.name": "eth5767", "observer.product": "FortiManager", + "observer.serial_number": "eddoei", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2208", @@ -2212,6 +2237,7 @@ "observer.egress.interface.name": "enp0s1732", "observer.ingress.interface.name": "lo2990", "observer.product": "FortiManager", + "observer.serial_number": "itametco", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.3402", @@ -2313,6 +2339,7 @@ "observer.egress.interface.name": "enp0s3067", "observer.ingress.interface.name": "enp0s4064", "observer.product": "FortiManager", + "observer.serial_number": "oluptat", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.91", @@ -2414,6 +2441,7 @@ "observer.egress.interface.name": "enp0s5908", "observer.ingress.interface.name": "eth62", "observer.product": "FortiManager", + "observer.serial_number": "Duisa", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.7278", @@ -2514,6 +2542,7 @@ "observer.egress.interface.name": "lo6533", "observer.ingress.interface.name": "enp0s6659", "observer.product": "FortiManager", + "observer.serial_number": "mexercit", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2581,6 +2610,7 @@ "observer.egress.interface.name": "enp0s5873", "observer.ingress.interface.name": "enp0s7649", "observer.product": "FortiManager", + "observer.serial_number": "nesci", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2649,6 +2679,7 @@ "observer.egress.interface.name": "eth1576", "observer.ingress.interface.name": "lo6539", "observer.product": "FortiManager", + "observer.serial_number": "nturmag", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.5978", @@ -2749,6 +2780,7 @@ "observer.egress.interface.name": "enp0s7799", "observer.ingress.interface.name": "eth6814", "observer.product": "FortiManager", + "observer.serial_number": "mexer", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2816,6 +2848,7 @@ "observer.egress.interface.name": "eth1882", "observer.ingress.interface.name": "lo497", "observer.product": "FortiManager", + "observer.serial_number": "unt", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2883,6 +2916,7 @@ "observer.egress.interface.name": "eth1188", "observer.ingress.interface.name": "lo4891", "observer.product": "FortiManager", + "observer.serial_number": "nost", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -2950,6 +2984,7 @@ "observer.egress.interface.name": "lo1800", "observer.ingress.interface.name": "lo3230", "observer.product": "FortiManager", + "observer.serial_number": "teturad", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3018,6 +3053,7 @@ "observer.egress.interface.name": "lo4581", "observer.ingress.interface.name": "eth4543", "observer.product": "FortiManager", + "observer.serial_number": "conseq", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4713", @@ -3119,6 +3155,7 @@ "observer.egress.interface.name": "enp0s7442", "observer.ingress.interface.name": "enp0s2282", "observer.product": "FortiManager", + "observer.serial_number": "umiurer", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4481", @@ -3221,6 +3258,7 @@ "observer.egress.interface.name": "enp0s4580", "observer.ingress.interface.name": "enp0s4429", "observer.product": "FortiManager", + "observer.serial_number": "uredol", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4442", @@ -3322,6 +3360,7 @@ "observer.egress.interface.name": "enp0s6960", "observer.ingress.interface.name": "enp0s7206", "observer.product": "FortiManager", + "observer.serial_number": "xeaco", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.3804", @@ -3422,6 +3461,7 @@ "observer.egress.interface.name": "eth855", "observer.ingress.interface.name": "eth3784", "observer.product": "FortiManager", + "observer.serial_number": "saute", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3489,6 +3529,7 @@ "observer.egress.interface.name": "lo2402", "observer.ingress.interface.name": "lo6750", "observer.product": "FortiManager", + "observer.serial_number": "metMa", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3545,6 +3586,7 @@ "log.level": "low", "log.offset": 45638, "observer.product": "FortiManager", + "observer.serial_number": "roinBCS", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3604,6 +3646,7 @@ "observer.egress.interface.name": "enp0s5799", "observer.ingress.interface.name": "eth1805", "observer.product": "FortiManager", + "observer.serial_number": "enim", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.7318", @@ -3705,6 +3748,7 @@ "observer.egress.interface.name": "enp0s4999", "observer.ingress.interface.name": "lo1719", "observer.product": "FortiManager", + "observer.serial_number": "quipex", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4895", @@ -3805,6 +3849,7 @@ "observer.egress.interface.name": "enp0s7861", "observer.ingress.interface.name": "enp0s7374", "observer.product": "FortiManager", + "observer.serial_number": "boreetdo", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3872,6 +3917,7 @@ "observer.egress.interface.name": "enp0s1294", "observer.ingress.interface.name": "lo2867", "observer.product": "FortiManager", + "observer.serial_number": "tiumd", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -3939,6 +3985,7 @@ "observer.egress.interface.name": "enp0s6143", "observer.ingress.interface.name": "eth575", "observer.product": "FortiManager", + "observer.serial_number": "periam", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -4007,6 +4054,7 @@ "observer.egress.interface.name": "enp0s4446", "observer.ingress.interface.name": "lo259", "observer.product": "FortiManager", + "observer.serial_number": "amq", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4493", @@ -4108,6 +4156,7 @@ "observer.egress.interface.name": "enp0s20", "observer.ingress.interface.name": "lo7727", "observer.product": "FortiManager", + "observer.serial_number": "aliqu", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.6506", @@ -4208,6 +4257,7 @@ "observer.egress.interface.name": "lo7156", "observer.ingress.interface.name": "enp0s6940", "observer.product": "FortiManager", + "observer.serial_number": "onproid", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -4275,6 +4325,7 @@ "observer.egress.interface.name": "enp0s3868", "observer.ingress.interface.name": "lo6718", "observer.product": "FortiManager", + "observer.serial_number": "imadm", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -4343,6 +4394,7 @@ "observer.egress.interface.name": "enp0s2918", "observer.ingress.interface.name": "enp0s2674", "observer.product": "FortiManager", + "observer.serial_number": "tati", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.409", @@ -4444,6 +4496,7 @@ "observer.egress.interface.name": "enp0s1238", "observer.ingress.interface.name": "lo4523", "observer.product": "FortiManager", + "observer.serial_number": "ecatcu", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.5475", @@ -4545,6 +4598,7 @@ "observer.egress.interface.name": "eth7500", "observer.ingress.interface.name": "eth2121", "observer.product": "FortiManager", + "observer.serial_number": "henderi", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.142", @@ -4646,6 +4700,7 @@ "observer.egress.interface.name": "eth2068", "observer.ingress.interface.name": "eth6552", "observer.product": "FortiManager", + "observer.serial_number": "ius", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1789", @@ -4747,6 +4802,7 @@ "observer.egress.interface.name": "lo5084", "observer.ingress.interface.name": "enp0s7638", "observer.product": "FortiManager", + "observer.serial_number": "uunturm", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -4815,6 +4871,7 @@ "observer.egress.interface.name": "enp0s4144", "observer.ingress.interface.name": "enp0s1897", "observer.product": "FortiManager", + "observer.serial_number": "ctas", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.6905", @@ -4916,6 +4973,7 @@ "observer.egress.interface.name": "enp0s390", "observer.ingress.interface.name": "enp0s3638", "observer.product": "FortiManager", + "observer.serial_number": "olab", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1353", @@ -5016,6 +5074,7 @@ "observer.egress.interface.name": "enp0s4444", "observer.ingress.interface.name": "lo5821", "observer.product": "FortiManager", + "observer.serial_number": "BCSedut", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5083,6 +5142,7 @@ "observer.egress.interface.name": "eth1592", "observer.ingress.interface.name": "lo1752", "observer.product": "FortiManager", + "observer.serial_number": "amre", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5151,6 +5211,7 @@ "observer.egress.interface.name": "lo299", "observer.ingress.interface.name": "eth5742", "observer.product": "FortiManager", + "observer.serial_number": "dolorsit", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4261", @@ -5252,6 +5313,7 @@ "observer.egress.interface.name": "lo2390", "observer.ingress.interface.name": "enp0s1531", "observer.product": "FortiManager", + "observer.serial_number": "nderit", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.491", @@ -5352,6 +5414,7 @@ "observer.egress.interface.name": "lo7502", "observer.ingress.interface.name": "eth4741", "observer.product": "FortiManager", + "observer.serial_number": "vel", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5419,6 +5482,7 @@ "observer.egress.interface.name": "lo3385", "observer.ingress.interface.name": "lo1640", "observer.product": "FortiManager", + "observer.serial_number": "tot", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5487,6 +5551,7 @@ "observer.egress.interface.name": "lo105", "observer.ingress.interface.name": "eth2707", "observer.product": "FortiManager", + "observer.serial_number": "tdolorem", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.979", @@ -5576,6 +5641,7 @@ "log.level": "high", "log.offset": 71594, "observer.product": "FortiManager", + "observer.serial_number": "henderi", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5635,6 +5701,7 @@ "observer.egress.interface.name": "lo6200", "observer.ingress.interface.name": "lo5820", "observer.product": "FortiManager", + "observer.serial_number": "oremquel", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4342", @@ -5736,6 +5803,7 @@ "observer.egress.interface.name": "enp0s7520", "observer.ingress.interface.name": "enp0s4931", "observer.product": "FortiManager", + "observer.serial_number": "remagna", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.6452", @@ -5836,6 +5904,7 @@ "observer.egress.interface.name": "lo1813", "observer.ingress.interface.name": "eth725", "observer.product": "FortiManager", + "observer.serial_number": "ittenbyC", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5903,6 +5972,7 @@ "observer.egress.interface.name": "lo1291", "observer.ingress.interface.name": "eth1273", "observer.product": "FortiManager", + "observer.serial_number": "xcepte", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -5971,6 +6041,7 @@ "observer.egress.interface.name": "lo1570", "observer.ingress.interface.name": "eth4425", "observer.product": "FortiManager", + "observer.serial_number": "olorinr", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.5718", @@ -6072,6 +6143,7 @@ "observer.egress.interface.name": "enp0s1526", "observer.ingress.interface.name": "enp0s6255", "observer.product": "FortiManager", + "observer.serial_number": "uipexea", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.6603", @@ -6173,6 +6245,7 @@ "observer.egress.interface.name": "lo368", "observer.ingress.interface.name": "lo2279", "observer.product": "FortiManager", + "observer.serial_number": "tempora", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2052", @@ -6274,6 +6347,7 @@ "observer.egress.interface.name": "enp0s7388", "observer.ingress.interface.name": "eth4604", "observer.product": "FortiManager", + "observer.serial_number": "avolup", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2691", @@ -6374,6 +6448,7 @@ "observer.egress.interface.name": "enp0s454", "observer.ingress.interface.name": "lo4518", "observer.product": "FortiManager", + "observer.serial_number": "ori", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6442,6 +6517,7 @@ "observer.egress.interface.name": "eth5820", "observer.ingress.interface.name": "lo568", "observer.product": "FortiManager", + "observer.serial_number": "onn", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.3052", @@ -6542,6 +6618,7 @@ "observer.egress.interface.name": "lo5835", "observer.ingress.interface.name": "lo7680", "observer.product": "FortiManager", + "observer.serial_number": "iusmodte", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6609,6 +6686,7 @@ "observer.egress.interface.name": "enp0s2353", "observer.ingress.interface.name": "eth2546", "observer.product": "FortiManager", + "observer.serial_number": "sitametc", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6677,6 +6755,7 @@ "observer.egress.interface.name": "eth7640", "observer.ingress.interface.name": "lo3023", "observer.product": "FortiManager", + "observer.serial_number": "maccusan", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.95", @@ -6777,6 +6856,7 @@ "observer.egress.interface.name": "lo5438", "observer.ingress.interface.name": "lo1917", "observer.product": "FortiManager", + "observer.serial_number": "itatio", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6844,6 +6924,7 @@ "observer.egress.interface.name": "lo5287", "observer.ingress.interface.name": "enp0s11", "observer.product": "FortiManager", + "observer.serial_number": "lorsita", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6911,6 +6992,7 @@ "observer.egress.interface.name": "lo2445", "observer.ingress.interface.name": "enp0s1885", "observer.product": "FortiManager", + "observer.serial_number": "uptasnul", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -6978,6 +7060,7 @@ "observer.egress.interface.name": "eth6468", "observer.ingress.interface.name": "eth1833", "observer.product": "FortiManager", + "observer.serial_number": "mquae", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7046,6 +7129,7 @@ "observer.egress.interface.name": "enp0s7218", "observer.ingress.interface.name": "lo1215", "observer.product": "FortiManager", + "observer.serial_number": "ant", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1028", @@ -7147,6 +7231,7 @@ "observer.egress.interface.name": "eth2435", "observer.ingress.interface.name": "lo3887", "observer.product": "FortiManager", + "observer.serial_number": "ulapari", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4195", @@ -7247,6 +7332,7 @@ "observer.egress.interface.name": "lo4266", "observer.ingress.interface.name": "eth297", "observer.product": "FortiManager", + "observer.serial_number": "exercita", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7314,6 +7400,7 @@ "observer.egress.interface.name": "eth5315", "observer.ingress.interface.name": "enp0s5429", "observer.product": "FortiManager", + "observer.serial_number": "trud", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7381,6 +7468,7 @@ "observer.egress.interface.name": "enp0s7159", "observer.ingress.interface.name": "enp0s4820", "observer.product": "FortiManager", + "observer.serial_number": "iad", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7448,6 +7536,7 @@ "observer.egress.interface.name": "eth614", "observer.ingress.interface.name": "eth4759", "observer.product": "FortiManager", + "observer.serial_number": "isnos", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7516,6 +7605,7 @@ "observer.egress.interface.name": "enp0s5497", "observer.ingress.interface.name": "enp0s2181", "observer.product": "FortiManager", + "observer.serial_number": "msequine", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2682", @@ -7616,6 +7706,7 @@ "observer.egress.interface.name": "lo6072", "observer.ingress.interface.name": "eth434", "observer.product": "FortiManager", + "observer.serial_number": "bori", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7672,6 +7763,7 @@ "log.level": "high", "log.offset": 97381, "observer.product": "FortiManager", + "observer.serial_number": "tena", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7730,6 +7822,7 @@ "observer.egress.interface.name": "enp0s1127", "observer.ingress.interface.name": "enp0s2388", "observer.product": "FortiManager", + "observer.serial_number": "alorumw", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7797,6 +7890,7 @@ "observer.egress.interface.name": "eth4236", "observer.ingress.interface.name": "enp0s5828", "observer.product": "FortiManager", + "observer.serial_number": "elaudan", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7864,6 +7958,7 @@ "observer.egress.interface.name": "enp0s2100", "observer.ingress.interface.name": "lo7358", "observer.product": "FortiManager", + "observer.serial_number": "rittenby", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -7931,6 +8026,7 @@ "observer.egress.interface.name": "lo7861", "observer.ingress.interface.name": "lo3071", "observer.product": "FortiManager", + "observer.serial_number": "ipsa", "observer.type": "Configuration", "observer.vendor": "Fortinet", "related.hosts": [ @@ -8000,6 +8096,7 @@ "observer.egress.interface.name": "eth1762", "observer.ingress.interface.name": "enp0s1127", "observer.product": "FortiManager", + "observer.serial_number": "uamqu", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.802", @@ -8101,6 +8198,7 @@ "observer.egress.interface.name": "enp0s1149", "observer.ingress.interface.name": "eth5256", "observer.product": "FortiManager", + "observer.serial_number": "riamea", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.2314", @@ -8202,6 +8300,7 @@ "observer.egress.interface.name": "enp0s5751", "observer.ingress.interface.name": "lo3094", "observer.product": "FortiManager", + "observer.serial_number": "reetdo", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.4674", @@ -8303,6 +8402,7 @@ "observer.egress.interface.name": "enp0s6106", "observer.ingress.interface.name": "lo5632", "observer.product": "FortiManager", + "observer.serial_number": "ameius", "observer.type": "Configuration", "observer.vendor": "Fortinet", "observer.version": "1.1386", From c40d505ac44e2bce7766ed4263e21bfb77e97fc2 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 29 Jun 2021 18:02:31 +0200 Subject: [PATCH 11/25] Update golang.org/x/crypto (#26448) --- NOTICE.txt | 8 ++++---- go.mod | 4 ++-- go.sum | 8 +++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 34785c7cbdb..35e8d9ec736 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -16717,11 +16717,11 @@ THE SOFTWARE. -------------------------------------------------------------------------------- Dependency : golang.org/x/crypto -Version: v0.0.0-20200820211705-5c72a883971a +Version: v0.0.0-20210616213533-5ff15b29337e Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.0.0-20200820211705-5c72a883971a/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.0.0-20210616213533-5ff15b29337e/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -16902,11 +16902,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/sys -Version: v0.0.0-20210308170721-88b6017d0656 +Version: v0.0.0-20210615035016-665e8c7367d1 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.0.0-20210308170721-88b6017d0656/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.0.0-20210615035016-665e8c7367d1/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. diff --git a/go.mod b/go.mod index 14cc32f6042..5b989515af4 100644 --- a/go.mod +++ b/go.mod @@ -165,12 +165,12 @@ require ( go.uber.org/atomic v1.5.0 go.uber.org/multierr v1.3.0 go.uber.org/zap v1.14.0 - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a + golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e golang.org/x/lint v0.0.0-20200130185559-910be7a94367 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - golang.org/x/sys v0.0.0-20210308170721-88b6017d0656 + golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 golang.org/x/text v0.3.5 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6 diff --git a/go.sum b/go.sum index 3ae57107801..bf42234d17a 100644 --- a/go.sum +++ b/go.sum @@ -776,8 +776,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -882,8 +883,9 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210308170721-88b6017d0656 h1:FuBaiPCiXkq4v+JY5JEGPU/HwEZwpVyDbu/KBz9fU+4= -golang.org/x/sys v0.0.0-20210308170721-88b6017d0656/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 2f873a23467b10c2ec1d173ae74308d9ef53c6ee Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 29 Jun 2021 18:02:56 +0200 Subject: [PATCH 12/25] Update urllib to 1.26.5. (#26380) --- libbeat/tests/system/requirements.txt | 6 +++--- .../module/kubernetes/_meta/terraform/eks/requirements.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libbeat/tests/system/requirements.txt b/libbeat/tests/system/requirements.txt index 72b2af54192..924a78cee8c 100644 --- a/libbeat/tests/system/requirements.txt +++ b/libbeat/tests/system/requirements.txt @@ -31,11 +31,11 @@ pycodestyle==2.6.0 pyparsing==2.4.7 pyrsistent==0.16.0 pytest==6.2.4 -pytest-timeout==1.4.2 pytest-rerunfailures==9.1.1 +pytest-timeout==1.4.2 PyYAML==5.3.1 redis==2.10.6 -requests==2.20.0 +requests==2.25.1 semver==2.8.1 setuptools==47.3.2 six==1.15.0 @@ -43,7 +43,7 @@ stomp.py==4.1.22 termcolor==1.1.0 texttable==0.9.1 toml==0.10.1 -urllib3==1.24.2 +urllib3==1.26.5 wcwidth==0.2.5 websocket-client==0.47.0 zipp>=1.2.0,<=3.1.0 diff --git a/metricbeat/module/kubernetes/_meta/terraform/eks/requirements.txt b/metricbeat/module/kubernetes/_meta/terraform/eks/requirements.txt index 6a408591661..c926ba0082d 100644 --- a/metricbeat/module/kubernetes/_meta/terraform/eks/requirements.txt +++ b/metricbeat/module/kubernetes/_meta/terraform/eks/requirements.txt @@ -9,4 +9,4 @@ PyYAML==5.4.1 rsa==4.7.2 s3transfer==0.3.3 six==1.14.0 -urllib3==1.25.9 +urllib3==1.26.5 From 1f2b913764c428cc9acfe3ee1d89e8f4342560c3 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 29 Jun 2021 10:46:13 -0700 Subject: [PATCH 13/25] [Docs] Fixed metricbeat redis exported field CPU descriptions (#25846) (#26496) * Fixed redis CPU descriptions These were mixed up. * Make changes to fields.yml in meta dir Co-authored-by: dedemorton Co-authored-by: Joost De Cock --- metricbeat/docs/fields.asciidoc | 4 ++-- metricbeat/module/redis/fields.go | 2 +- metricbeat/module/redis/info/_meta/fields.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 6dda8fcef33..6d0d48c3dca 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -47698,7 +47698,7 @@ type: scaled_float *`redis.info.cpu.used.sys_children`*:: + -- -User CPU consumed by the Redis server. +System CPU consumed by the background processes. type: scaled_float @@ -47708,7 +47708,7 @@ type: scaled_float *`redis.info.cpu.used.user`*:: + -- -System CPU consumed by the background processes. +User CPU consumed by the Redis server. type: scaled_float diff --git a/metricbeat/module/redis/fields.go b/metricbeat/module/redis/fields.go index ccdb515cba3..a703692c940 100644 --- a/metricbeat/module/redis/fields.go +++ b/metricbeat/module/redis/fields.go @@ -32,5 +32,5 @@ func init() { // AssetRedis returns asset data. // This is the base64 encoded gzipped contents of module/redis. func AssetRedis() string { - return "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" + return "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" } diff --git a/metricbeat/module/redis/info/_meta/fields.yml b/metricbeat/module/redis/info/_meta/fields.yml index ff3c7322294..9e05567329f 100644 --- a/metricbeat/module/redis/info/_meta/fields.yml +++ b/metricbeat/module/redis/info/_meta/fields.yml @@ -58,11 +58,11 @@ - name: used.sys_children type: scaled_float description: > - User CPU consumed by the Redis server. + System CPU consumed by the background processes. - name: used.user type: scaled_float description: > - System CPU consumed by the background processes. + User CPU consumed by the Redis server. - name: used.user_children type: scaled_float description: > From d41dee54c3d3d084122688c27d2a3dd5e04866ac Mon Sep 17 00:00:00 2001 From: Luca Belluccini Date: Tue, 29 Jun 2021 19:20:27 +0100 Subject: [PATCH 14/25] docs: Hint for the error "Error extracting container id" (#25824) --- filebeat/docs/faq.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/filebeat/docs/faq.asciidoc b/filebeat/docs/faq.asciidoc index 4547e165fb9..ddcdb6a8898 100644 --- a/filebeat/docs/faq.asciidoc +++ b/filebeat/docs/faq.asciidoc @@ -5,6 +5,13 @@ 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]. +[[filebeat-kubernetes-metadata-error-extracting-container-id]] +=== Error extracting container id while using Kubernetes metadata + +The `add_kubernetes_metadata` processor might throw the error `Error extracting container id - source value does not contain matcher's logs_path`. +There might be some issues with the matchers definitions or the location of `logs_path`. +Please verify the Kubernetes pod is healthy. + [[filebeat-network-volumes]] === Can't read log files from network volumes From beaa972eeea557fb4f34e442c13a845be8a40f89 Mon Sep 17 00:00:00 2001 From: Lee Hinman <57081003+leehinman@users.noreply.github.com> Date: Tue, 29 Jun 2021 14:52:04 -0500 Subject: [PATCH 15/25] [Filebeat] change multiline configuration in awss3 input to parsers (#25873) * change multiline configuration in awss3 input to parsers - switches multiline configuration to parsers - JSON parsing is independent Closes #25249 --- CHANGELOG.next.asciidoc | 2 +- .../docs/inputs/input-aws-s3.asciidoc | 44 +++++++++++++++---- x-pack/filebeat/input/awss3/collector.go | 8 +--- x-pack/filebeat/input/awss3/config.go | 12 ++--- x-pack/filebeat/input/awss3/config_test.go | 6 +++ .../input/awss3/s3_integration_test.go | 12 +++-- 6 files changed, 58 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 7c5ca82d7dd..1092d2a4a8f 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -813,7 +813,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Update PanOS module to parse Global Protect & User ID logs. {issue}24722[24722] {issue}24724[24724] {pull}24927[24927] - Add HMAC signature validation support for http_endpoint input. {pull}24918[24918] - Add new grok pattern for iptables module for Ubiquiti UDM {issue}25615[25615] {pull}25616[25616] -- Add multiline support to aws-s3 input. {issue}25249[25249] {pull}25710[25710] +- Add multiline support to aws-s3 input. {issue}25249[25249] {pull}25710[25710] {pull}25873[25873] - Add monitoring metrics to the `aws-s3` input. {pull}25711[25711] - Added `network.direction` fields to Zeek and Suricata modules using the `add_network_direction` processor {pull}24620[24620] - Add Content-Type override to aws-s3 input. {issue}25697[25697] {pull}25772[25772] diff --git a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc index 91645bdf733..9de827de26e 100644 --- a/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-aws-s3.asciidoc @@ -112,10 +112,10 @@ setting. If `file_selectors` is given, then any global `expand_event_list_from_field` value is ignored in favor of the ones specified in the `file_selectors`. Regex syntax is the same as the Go language. Files that don't match one of the regexes won't be -processed. <>, <>, -<>, <>, -<>, and <> may also be set for -each file selector. +processed. <>, <>, +<>,<>, +<>, and <> may also +be set for each file selector. ["source", "yml"] ---- @@ -166,15 +166,43 @@ The maximum number of messages to return. Amazon SQS never returns more messages than this value (however, fewer messages might be returned). Valid values: 1 to 10. Default: 5. -[id="input-{type}-multiline"] +[id="input-{type}-parsers"] [float] -==== `multiline` +==== `parsers` + +beta[] + +This option expects a list of parsers that non-JSON logs go through. + +Available parsers: + +* `multiline` + +In this example, {beatname_uc} is reading multiline messages that +consist of XML that start with the `` tag. + +["source","yaml",subs="attributes"] +---- +{beatname_lc}.inputs: +- type: {type} + ... + parsers: + - multiline: + pattern: "^> -for more information about configuring multiline options. +multiple lines. See <> for more information about +configuring multiline options. [float] ==== `queue_url` diff --git a/x-pack/filebeat/input/awss3/collector.go b/x-pack/filebeat/input/awss3/collector.go index 179adac1fba..addcd0ea29b 100644 --- a/x-pack/filebeat/input/awss3/collector.go +++ b/x-pack/filebeat/input/awss3/collector.go @@ -32,7 +32,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/reader" - "github.com/elastic/beats/v7/libbeat/reader/multiline" "github.com/elastic/beats/v7/libbeat/reader/readfile" "github.com/elastic/beats/v7/libbeat/reader/readfile/encoding" "github.com/elastic/go-concert/unison" @@ -438,12 +437,7 @@ func (c *s3Collector) createEventsFromS3Info(svc s3iface.ClientAPI, info s3Info, } r = readfile.NewStripNewline(r, info.LineTerminator) - if info.Multiline != nil { - r, err = multiline.New(r, "\n", int(info.MaxBytes), info.Multiline) - if err != nil { - return fmt.Errorf("error setting up multiline: %v", err) - } - } + r = info.Parsers.Create(r) r = readfile.NewLimitReader(r, int(info.MaxBytes)) diff --git a/x-pack/filebeat/input/awss3/config.go b/x-pack/filebeat/input/awss3/config.go index b06cb848a1c..cc850ef2aab 100644 --- a/x-pack/filebeat/input/awss3/config.go +++ b/x-pack/filebeat/input/awss3/config.go @@ -12,7 +12,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/cfgtype" "github.com/elastic/beats/v7/libbeat/common/match" - "github.com/elastic/beats/v7/libbeat/reader/multiline" + "github.com/elastic/beats/v7/libbeat/reader/parser" "github.com/elastic/beats/v7/libbeat/reader/readfile" awscommon "github.com/elastic/beats/v7/x-pack/libbeat/common/aws" ) @@ -66,14 +66,14 @@ type fileSelectorConfig struct { // readerConfig defines the options for reading the content of an S3 object. type readerConfig struct { - ExpandEventListFromField string `config:"expand_event_list_from_field"` BufferSize cfgtype.ByteSize `config:"buffer_size"` - MaxBytes cfgtype.ByteSize `config:"max_bytes"` - Multiline *multiline.Config `config:"multiline"` - LineTerminator readfile.LineTerminator `config:"line_terminator"` - Encoding string `config:"encoding"` ContentType string `config:"content_type"` + Encoding string `config:"encoding"` + ExpandEventListFromField string `config:"expand_event_list_from_field"` IncludeS3Metadata []string `config:"include_s3_metadata"` + LineTerminator readfile.LineTerminator `config:"line_terminator"` + MaxBytes cfgtype.ByteSize `config:"max_bytes"` + Parsers parser.Config `config:",inline"` } func (f *readerConfig) Validate() error { diff --git a/x-pack/filebeat/input/awss3/config_test.go b/x-pack/filebeat/input/awss3/config_test.go index aa40f8c6e12..7328467fc14 100644 --- a/x-pack/filebeat/input/awss3/config_test.go +++ b/x-pack/filebeat/input/awss3/config_test.go @@ -13,6 +13,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/match" + "github.com/elastic/beats/v7/libbeat/reader/parser" "github.com/elastic/beats/v7/libbeat/reader/readfile" ) @@ -21,6 +22,10 @@ func TestConfig(t *testing.T) { makeConfig := func() config { // Have a separate copy of defaults in the test to make it clear when // anyone changes the defaults. + cfg := common.MustNewConfigFrom("") + c := parser.Config{} + err := c.Unpack(cfg) + assert.Nil(t, err) return config{ QueueURL: queueURL, APITimeout: 120 * time.Second, @@ -31,6 +36,7 @@ func TestConfig(t *testing.T) { BufferSize: 16 * humanize.KiByte, MaxBytes: 10 * humanize.MiByte, LineTerminator: readfile.AutoLineTerminator, + Parsers: c, }, } } diff --git a/x-pack/filebeat/input/awss3/s3_integration_test.go b/x-pack/filebeat/input/awss3/s3_integration_test.go index be91319b6c9..4966bed6084 100644 --- a/x-pack/filebeat/input/awss3/s3_integration_test.go +++ b/x-pack/filebeat/input/awss3/s3_integration_test.go @@ -86,10 +86,14 @@ func defaultTestConfig() *common.Config { { "regex": strings.Replace(fileName2, ".", "\\.", -1), "max_bytes": 4096, - "multiline": common.MapStr{ - "pattern": "^ Date: Tue, 29 Jun 2021 22:15:46 +0200 Subject: [PATCH 16/25] Introduce httpcommon package in libbeat (add support for Proxy) (#25219) --- CHANGELOG.next.asciidoc | 2 + dev-tools/cmd/dashboards/export_dashboards.go | 19 +- filebeat/fileset/modules_integration_test.go | 3 +- filebeat/fileset/pipelines_test.go | 7 +- heartbeat/docs/monitors/monitor-http.asciidoc | 6 + heartbeat/monitors/active/dialchain/tls.go | 6 +- heartbeat/monitors/active/http/config.go | 54 +-- heartbeat/monitors/active/http/http.go | 51 +-- heartbeat/monitors/active/http/http_test.go | 44 +- heartbeat/monitors/active/http/task.go | 10 +- libbeat/common/transport/client.go | 4 +- .../common/transport/httpcommon/httpcommon.go | 382 ++++++++++++++++++ libbeat/common/transport/httpcommon/proxy.go | 102 +++++ libbeat/common/transport/tls.go | 6 +- libbeat/common/transport/tlscommon/config.go | 11 +- .../transport/tlscommon/server_config.go | 4 +- libbeat/common/transport/tlscommon/tls.go | 2 +- .../common/transport/tlscommon/tls_config.go | 5 +- libbeat/common/transport/tlscommon/types.go | 104 +++-- libbeat/common/transport/transport.go | 2 +- libbeat/esleg/eslegclient/api_test.go | 3 +- .../esleg/eslegclient/bulkapi_mock_test.go | 1 - libbeat/esleg/eslegclient/config.go | 28 +- libbeat/esleg/eslegclient/connection.go | 105 ++--- .../connection_integration_test.go | 7 +- .../ilm/client_handler_integration_test.go | 5 +- libbeat/kibana/client.go | 27 +- libbeat/kibana/client_config.go | 35 +- .../elastic_fetcher_integration_test.go | 6 +- libbeat/licenser/elastic_fetcher_test.go | 4 +- .../monitoring/report/elasticsearch/config.go | 6 +- .../report/elasticsearch/elasticsearch.go | 32 +- libbeat/outputs/elasticsearch/client.go | 49 ++- .../elasticsearch/client_proxy_test.go | 13 +- libbeat/outputs/elasticsearch/config.go | 20 +- .../elasticsearch/docs/elasticsearch.asciidoc | 12 + .../outputs/elasticsearch/elasticsearch.go | 24 +- .../logstash/logstash_integration_test.go | 11 +- libbeat/template/load_integration_test.go | 5 +- metricbeat/helper/config.go | 11 +- metricbeat/helper/http.go | 32 +- metricbeat/helper/http_test.go | 2 +- .../module/apache/status/status_test.go | 4 +- .../module/elasticsearch/index/data_test.go | 5 +- .../module/envoyproxy/server/server_test.go | 4 +- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../application/pipeline/stream/factory.go | 18 +- .../application/upgrade/step_download.go | 13 +- .../elastic-agent/pkg/agent/cmd/container.go | 6 +- .../elastic-agent/pkg/agent/cmd/enroll_cmd.go | 13 +- x-pack/elastic-agent/pkg/artifact/config.go | 19 +- .../pkg/artifact/download/fs/verifier_test.go | 9 +- .../pkg/artifact/download/http/downloader.go | 16 +- .../artifact/download/http/elastic_test.go | 9 +- .../pkg/artifact/download/http/verifier.go | 16 +- .../download/localremote/downloader.go | 11 +- .../artifact/download/snapshot/downloader.go | 16 +- x-pack/elastic-agent/pkg/remote/client.go | 32 +- x-pack/elastic-agent/pkg/remote/config.go | 40 +- .../elastic-agent/pkg/remote/config_test.go | 6 +- x-pack/filebeat/input/httpjson/config.go | 5 +- x-pack/filebeat/input/httpjson/input.go | 42 +- .../filebeat/input/httpjson/input_cursor.go | 24 +- .../input/httpjson/input_stateless.go | 16 +- x-pack/filebeat/input/httpjson/input_test.go | 4 +- .../input/httpjson/internal/v2/config.go | 10 +- .../httpjson/internal/v2/config_request.go | 38 +- .../input/httpjson/internal/v2/input.go | 47 +-- .../httpjson/internal/v2/input_cursor.go | 23 +- .../httpjson/internal/v2/input_stateless.go | 12 +- .../httpjson/internal/v2/request_test.go | 2 +- x-pack/libbeat/common/cloudfoundry/config.go | 19 +- x-pack/libbeat/common/cloudfoundry/hub.go | 22 +- .../openmetrics/collector/_meta/data.json | 2 +- .../prometheus/collector/_meta/data.json | 16 +- 75 files changed, 1044 insertions(+), 738 deletions(-) create mode 100644 libbeat/common/transport/httpcommon/httpcommon.go create mode 100644 libbeat/common/transport/httpcommon/proxy.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1092d2a4a8f..e3912d5805f 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -598,6 +598,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Improve ES output error insights. {pull}25825[25825] - Add orchestrator.cluster.name/url fields as k8s metadata {pull}26056[26056] - Libbeat: report beat version to monitoring. {pull}26214[26214] +- Ensure common proxy settings support in HTTP clients: proxy_disabled, proxy_url, proxy_headers and typical environment variables HTTP_PROXY, HTTPS_PROXY, NOPROXY. {pull}25219[25219] *Auditbeat* @@ -845,6 +846,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Heartbeat* - Add mime type detection for http responses. {pull}22976[22976] +- Add `proxy_headers` to HTTP monitor. {pull}25219[25219] *Journalbeat* diff --git a/dev-tools/cmd/dashboards/export_dashboards.go b/dev-tools/cmd/dashboards/export_dashboards.go index eeae6773a96..a3fe4429aab 100644 --- a/dev-tools/cmd/dashboards/export_dashboards.go +++ b/dev-tools/cmd/dashboards/export_dashboards.go @@ -29,6 +29,7 @@ import ( "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/dashboards" "github.com/elastic/beats/v7/libbeat/kibana" ) @@ -64,14 +65,18 @@ func main() { user = u.User.Username() pass, _ = u.User.Password() } + + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = kibanaTimeout + client, err := kibana.NewClientWithConfig(&kibana.ClientConfig{ - Protocol: u.Scheme, - Host: u.Host, - Username: user, - Password: pass, - Path: u.Path, - SpaceID: *spaceID, - Timeout: kibanaTimeout, + Protocol: u.Scheme, + Host: u.Host, + Username: user, + Password: pass, + Path: u.Path, + SpaceID: *spaceID, + Transport: transport, }) if err != nil { log.Fatalf("Error while connecting to Kibana: %v", err) diff --git a/filebeat/fileset/modules_integration_test.go b/filebeat/fileset/modules_integration_test.go index b4b5c40bb75..7afd9bbb547 100644 --- a/filebeat/fileset/modules_integration_test.go +++ b/filebeat/fileset/modules_integration_test.go @@ -251,8 +251,7 @@ func TestLoadMultiplePipelinesWithRollback(t *testing.T) { func getTestingElasticsearch(t eslegtest.TestLogger) *eslegclient.Connection { conn, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ - URL: eslegtest.GetURL(), - Timeout: 0, + URL: eslegtest.GetURL(), }) if err != nil { t.Fatal(err) diff --git a/filebeat/fileset/pipelines_test.go b/filebeat/fileset/pipelines_test.go index 04d48c67f01..f3d9e2d5a07 100644 --- a/filebeat/fileset/pipelines_test.go +++ b/filebeat/fileset/pipelines_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/logp" ) @@ -91,8 +92,10 @@ func TestLoadPipelinesWithMultiPipelineFileset(t *testing.T) { defer testESServer.Close() testESClient, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ - URL: testESServer.URL, - Timeout: 90 * time.Second, + URL: testESServer.URL, + Transport: httpcommon.HTTPTransportSettings{ + Timeout: 90 * time.Second, + }, }) require.NoError(t, err) diff --git a/heartbeat/docs/monitors/monitor-http.asciidoc b/heartbeat/docs/monitors/monitor-http.asciidoc index bcae6f10b0f..2b02ba53563 100644 --- a/heartbeat/docs/monitors/monitor-http.asciidoc +++ b/heartbeat/docs/monitors/monitor-http.asciidoc @@ -41,6 +41,12 @@ that data will span multiple requests. Specifically the fields `http.rtt.content The HTTP proxy URL. This setting is optional. Example `http://proxy.mydomain.com:3128` +[float] +[[monitor-http-proxy-headers]] +==== `proxy_headers` + +Additional headers to send to proxies during CONNECT requests. + [float] [[monitor-http-username]] ==== `username` diff --git a/heartbeat/monitors/active/dialchain/tls.go b/heartbeat/monitors/active/dialchain/tls.go index b4b2c006dfb..5786d57e315 100644 --- a/heartbeat/monitors/active/dialchain/tls.go +++ b/heartbeat/monitors/active/dialchain/tls.go @@ -40,11 +40,7 @@ func TLSLayer(cfg *tlscommon.TLSConfig, to time.Duration) Layer { // This gets us the timestamp for when the TLS layer will start the handshake. next = startTimerAfterDial(&timer, next) - dialer, err := transport.TLSDialer(next, cfg, to) - if err != nil { - return nil, err - } - + dialer := transport.TLSDialer(next, cfg, to) return afterDial(dialer, func(conn net.Conn) (net.Conn, error) { tlsConn, ok := conn.(*cryptoTLS.Conn) if !ok { diff --git a/heartbeat/monitors/active/http/config.go b/heartbeat/monitors/active/http/config.go index 2a2c2c04965..85eda196d29 100644 --- a/heartbeat/monitors/active/http/config.go +++ b/heartbeat/monitors/active/http/config.go @@ -24,15 +24,13 @@ import ( "time" "github.com/elastic/beats/v7/heartbeat/monitors" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/conditions" ) type Config struct { URLs []string `config:"urls"` Hosts []string `config:"hosts"` - ProxyURL string `config:"proxy_url"` - Timeout time.Duration `config:"timeout"` MaxRedirects int `config:"max_redirects"` Response responseConfig `config:"response"` @@ -42,11 +40,10 @@ type Config struct { Username string `config:"username"` Password string `config:"password"` - // configure tls (if not configured HTTPS will use system defaults) - TLS *tlscommon.Config `config:"ssl"` - // http(s) ping validation Check checkConfig `config:"check"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } type responseConfig struct { @@ -90,27 +87,32 @@ type compressionConfig struct { Level int `config:"level"` } -var defaultConfig = Config{ - Timeout: 16 * time.Second, - MaxRedirects: 0, - Response: responseConfig{ - IncludeBody: "on_error", - IncludeBodyMaxBytes: 2048, - IncludeHeaders: true, - }, - Mode: monitors.DefaultIPSettings, - Check: checkConfig{ - Request: requestParameters{ - Method: "GET", - SendHeaders: nil, - SendBody: "", +func defaultConfig() Config { + cfg := Config{ + MaxRedirects: 0, + Response: responseConfig{ + IncludeBody: "on_error", + IncludeBodyMaxBytes: 2048, + IncludeHeaders: true, }, - Response: responseParameters{ - RecvHeaders: nil, - RecvBody: nil, - RecvJSON: nil, + Mode: monitors.DefaultIPSettings, + Check: checkConfig{ + Request: requestParameters{ + Method: "GET", + SendHeaders: nil, + SendBody: "", + }, + Response: responseParameters{ + RecvHeaders: nil, + RecvBody: nil, + RecvJSON: nil, + }, }, - }, + Transport: httpcommon.DefaultHTTPTransportSettings(), + } + cfg.Transport.Timeout = 16 * time.Second + + return cfg } // Validate validates of the responseConfig object is valid or not @@ -169,7 +171,7 @@ func (c *Config) Validate() error { // updateScheme looks at TLS config to decide if http or https should be used to update the host updateScheme := func(host string) string { - if c.TLS != nil && *c.TLS.Enabled == true { + if c.Transport.TLS != nil && c.Transport.TLS.IsEnabled() { return fmt.Sprint("https://", host) } return fmt.Sprint("http://", host) diff --git a/heartbeat/monitors/active/http/http.go b/heartbeat/monitors/active/http/http.go index 214ed8519d8..c02ae25943e 100644 --- a/heartbeat/monitors/active/http/http.go +++ b/heartbeat/monitors/active/http/http.go @@ -27,7 +27,7 @@ import ( "github.com/elastic/beats/v7/heartbeat/monitors/jobs" "github.com/elastic/beats/v7/heartbeat/monitors/wrappers" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport" + "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" ) @@ -43,16 +43,11 @@ func create( name string, cfg *common.Config, ) (p plugin.Plugin, err error) { - config := defaultConfig + config := defaultConfig() if err := cfg.Unpack(&config); err != nil { return plugin.Plugin{}, err } - tls, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return plugin.Plugin{}, err - } - var body []byte var enc contentEncoder @@ -84,8 +79,8 @@ func create( // In the event that a ProxyURL is present, or redirect support is enabled // we execute DNS resolution requests inline with the request, not running them as a separate job, and not returning // separate DNS rtt data. - if config.ProxyURL != "" || config.MaxRedirects > 0 { - transport, err := newRoundTripper(&config, tls) + if (config.Transport.Proxy.URL != nil && !config.Transport.Proxy.Disable) || config.MaxRedirects > 0 { + transport, err := newRoundTripper(&config) if err != nil { return plugin.Plugin{}, err } @@ -94,6 +89,13 @@ func create( return newHTTPMonitorHostJob(urlStr, &config, transport, enc, body, validator) } } else { + // preload TLS configuration + tls, err := tlscommon.LoadTLSConfig(config.Transport.TLS) + if err != nil { + return plugin.Plugin{}, err + } + config.Transport.TLS = nil + makeJob = func(urlStr string) (jobs.Job, error) { return newHTTPMonitorIPsJob(&config, urlStr, tls, enc, body, validator) } @@ -119,27 +121,12 @@ func create( return plugin.Plugin{Jobs: js, Close: nil, Endpoints: len(config.Hosts)}, nil } -func newRoundTripper(config *Config, tls *tlscommon.TLSConfig) (*http.Transport, error) { - var proxy func(*http.Request) (*url.URL, error) - if config.ProxyURL != "" { - url, err := url.Parse(config.ProxyURL) - if err != nil { - return nil, err - } - proxy = http.ProxyURL(url) - } - - dialer := transport.NetDialer(config.Timeout) - tlsDialer, err := transport.TLSDialer(dialer, tls, config.Timeout) - if err != nil { - return nil, err - } - - return &http.Transport{ - Proxy: proxy, - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - TLSClientConfig: tls.ToConfig(), - DisableKeepAlives: true, - }, nil +func newRoundTripper(config *Config) (http.RoundTripper, error) { + return config.Transport.RoundTripper( + httpcommon.WithAPMHTTPInstrumentation(), + httpcommon.WithoutProxyEnvironmentVariables(), + httpcommon.WithKeepaliveSettings{ + Disable: true, + }, + ) } diff --git a/heartbeat/monitors/active/http/http_test.go b/heartbeat/monitors/active/http/http_test.go index d862f745eb8..fc0c6fce63d 100644 --- a/heartbeat/monitors/active/http/http_test.go +++ b/heartbeat/monitors/active/http/http_test.go @@ -45,8 +45,6 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/file" - "github.com/elastic/beats/v7/libbeat/common/transport" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" btesting "github.com/elastic/beats/v7/libbeat/testing" "github.com/elastic/go-lookslike" "github.com/elastic/go-lookslike/isdef" @@ -408,7 +406,6 @@ func TestHTTPSServer(t *testing.T) { t.Skip("flaky test: https://github.com/elastic/beats/issues/25857") } server := httptest.NewTLSServer(hbtest.HelloWorldHandler(http.StatusOK)) - runHTTPSServerCheck(t, server, nil) } @@ -613,39 +610,6 @@ func TestNoHeaders(t *testing.T) { ) } -func TestNewRoundTripper(t *testing.T) { - configs := map[string]Config{ - "Plain": {Timeout: time.Second}, - "With Proxy": {Timeout: time.Second, ProxyURL: "http://localhost:1234"}, - } - - for name, config := range configs { - t.Run(name, func(t *testing.T) { - transp, err := newRoundTripper(&config, &tlscommon.TLSConfig{}) - require.NoError(t, err) - - if config.ProxyURL == "" { - require.Nil(t, transp.Proxy) - } else { - require.NotNil(t, transp.Proxy) - } - - // It's hard to compare func types in tests - require.NotNil(t, transp.Dial) - require.NotNil(t, transport.TLSDialer) - - expected := (&tlscommon.TLSConfig{}).ToConfig() - require.Equal(t, expected.InsecureSkipVerify, transp.TLSClientConfig.InsecureSkipVerify) - // When we remove support for the legacy common name treatment - // this test has to be adjusted, as we will not depend on our - // VerifyConnection callback. - require.NotNil(t, transp.TLSClientConfig.VerifyConnection) - require.True(t, transp.DisableKeepAlives) - }) - } - -} - func TestProxy(t *testing.T) { if runtime.GOOS == "windows" && bits.UintSize == 32 { t.Skip("flaky test: https://github.com/elastic/beats/issues/25857") @@ -705,3 +669,11 @@ func httpConnectTunnel(writer http.ResponseWriter, request *http.Request) { }() wg.Wait() } + +func mustParseURL(t *testing.T, url string) *url.URL { + parsed, err := common.ParseURL(url) + if err != nil { + t.Fatal(err) + } + return parsed +} diff --git a/heartbeat/monitors/active/http/task.go b/heartbeat/monitors/active/http/task.go index 02257a15e7d..630283c8bab 100644 --- a/heartbeat/monitors/active/http/task.go +++ b/heartbeat/monitors/active/http/task.go @@ -50,7 +50,7 @@ var userAgent = useragent.UserAgent("Heartbeat") func newHTTPMonitorHostJob( addr string, config *Config, - transport *http.Transport, + transport http.RoundTripper, enc contentEncoder, body []byte, validator multiValidator, @@ -61,17 +61,15 @@ func newHTTPMonitorHostJob( return nil, err } - timeout := config.Timeout - return jobs.MakeSimpleJob(func(event *beat.Event) error { var redirects []string client := &http.Client{ // Trace visited URLs when redirects occur CheckRedirect: makeCheckRedirect(config.MaxRedirects, &redirects), Transport: transport, - Timeout: config.Timeout, + Timeout: config.Transport.Timeout, } - _, _, err := execPing(event, client, request, body, timeout, validator, config.Response) + _, _, err := execPing(event, client, request, body, config.Transport.Timeout, validator, config.Response) if len(redirects) > 0 { event.PutValue("http.response.redirects", redirects) } @@ -112,7 +110,7 @@ func createPingFactory( body []byte, validator multiValidator, ) func(*net.IPAddr) jobs.Job { - timeout := config.Timeout + timeout := config.Transport.Timeout isTLS := request.URL.Scheme == "https" return monitors.MakePingIPFactory(func(event *beat.Event, ip *net.IPAddr) error { diff --git a/libbeat/common/transport/client.go b/libbeat/common/transport/client.go index 7027d1a3142..b59545bc607 100644 --- a/libbeat/common/transport/client.go +++ b/libbeat/common/transport/client.go @@ -224,8 +224,8 @@ func (c *Client) Test(d testing.Driver) { } else { d.Run("TLS", func(d testing.Driver) { netDialer := NetDialer(c.config.Timeout) - tlsDialer, err := TestTLSDialer(d, netDialer, c.config.TLS, c.config.Timeout) - _, err = tlsDialer.Dial("tcp", c.host) + tlsDialer := TestTLSDialer(d, netDialer, c.config.TLS, c.config.Timeout) + _, err := tlsDialer.Dial("tcp", c.host) d.Fatal("dial up", err) }) } diff --git a/libbeat/common/transport/httpcommon/httpcommon.go b/libbeat/common/transport/httpcommon/httpcommon.go new file mode 100644 index 00000000000..8f79f357183 --- /dev/null +++ b/libbeat/common/transport/httpcommon/httpcommon.go @@ -0,0 +1,382 @@ +// 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 httpcommon + +import ( + "net/http" + "time" + + "go.elastic.co/apm/module/apmhttp" + "golang.org/x/net/http2" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/transport" + "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/logp" +) + +// HTTPTransportSettings provides common HTTP settings for HTTP clients. +type HTTPTransportSettings struct { + // TLS provides ssl/tls setup settings + TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty" json:"ssl,omitempty"` + + // Timeout configures the `(http.Transport).Timeout`. + Timeout time.Duration `config:"timeout" yaml:"timeout,omitempty" json:"timeout,omitempty"` + + Proxy HTTPClientProxySettings `config:",inline" yaml:",inline"` + + // TODO: Add more settings: + // - DisableKeepAlive + // - MaxIdleConns + // - IdleConnTimeout + // - ResponseHeaderTimeout + // - ConnectionTimeout (currently 'Timeout' is used for both) +} + +// WithKeepaliveSettings options can be used to modify the Keepalive +type WithKeepaliveSettings struct { + Disable bool + MaxIdleConns int + MaxIdleConnsPerHost int + IdleConnTimeout time.Duration +} + +var _ httpTransportOption = WithKeepaliveSettings{} + +const defaultHTTPTimeout = 90 * time.Second + +type ( + // TransportOption are applied to the http.RoundTripper to be build + // from HTTPTransportSettings. + TransportOption interface{ sealTransportOption() } + + extraSettings struct { + logger *logp.Logger + http2 bool + } + + dialerOption interface { + TransportOption + baseDialer() transport.Dialer + } + dialerModOption interface { + TransportOption + applyDialer(*HTTPTransportSettings, transport.Dialer) transport.Dialer + } + httpTransportOption interface { + TransportOption + applyTransport(*HTTPTransportSettings, *http.Transport) + } + roundTripperOption interface { + TransportOption + applyRoundTripper(*HTTPTransportSettings, http.RoundTripper) http.RoundTripper + } + extraOption interface { + TransportOption + applyExtra(*extraSettings) + } +) + +type baseDialerFunc func() transport.Dialer + +var _ dialerOption = baseDialerFunc(nil) + +func (baseDialerFunc) sealTransportOption() {} +func (fn baseDialerFunc) baseDialer() transport.Dialer { + return fn() +} + +type dialerOptFunc func(transport.Dialer) transport.Dialer + +var _ dialerModOption = dialerOptFunc(nil) + +func (dialerOptFunc) sealTransportOption() {} +func (fn dialerOptFunc) applyDialer(_ *HTTPTransportSettings, d transport.Dialer) transport.Dialer { + return fn(d) + +} + +type transportOptFunc func(*HTTPTransportSettings, *http.Transport) + +var _ httpTransportOption = transportOptFunc(nil) + +func (transportOptFunc) sealTransportOption() {} +func (fn transportOptFunc) applyTransport(s *HTTPTransportSettings, t *http.Transport) { + fn(s, t) +} + +type rtOptFunc func(http.RoundTripper) http.RoundTripper + +var _ roundTripperOption = rtOptFunc(nil) + +func (rtOptFunc) sealTransportOption() {} +func (fn rtOptFunc) applyRoundTripper(_ *HTTPTransportSettings, rt http.RoundTripper) http.RoundTripper { + return fn(rt) +} + +type extraOptionFunc func(*extraSettings) + +func (extraOptionFunc) sealTransportOption() {} +func (fn extraOptionFunc) applyExtra(s *extraSettings) { fn(s) } + +// DefaultHTTPTransportSettings returns the default HTTP transport setting. +func DefaultHTTPTransportSettings() HTTPTransportSettings { + return HTTPTransportSettings{ + Proxy: DefaultHTTPClientProxySettings(), + Timeout: defaultHTTPTimeout, + } +} + +// Unpack reads a config object into the settings. +func (settings *HTTPTransportSettings) Unpack(cfg *common.Config) error { + tmp := struct { + TLS *tlscommon.Config `config:"ssl"` + Timeout time.Duration `config:"timeout"` + }{Timeout: settings.Timeout} + + if err := cfg.Unpack(&tmp); err != nil { + return err + } + + var proxy HTTPClientProxySettings + if err := cfg.Unpack(&proxy); err != nil { + return err + } + + _, err := tlscommon.LoadTLSConfig(tmp.TLS) + if err != nil { + return err + } + + *settings = HTTPTransportSettings{ + TLS: tmp.TLS, + Timeout: tmp.Timeout, + Proxy: proxy, + } + return nil +} + +// RoundTripper creates a http.RoundTripper for use with http.Client. +// +// The dialers will registers with stats if given. Stats is used to collect metrics for io errors, +// bytes in, and bytes out. +func (settings *HTTPTransportSettings) RoundTripper(opts ...TransportOption) (http.RoundTripper, error) { + var dialer transport.Dialer + + var extra extraSettings + for _, opt := range opts { + if opt, ok := opt.(extraOption); ok { + opt.applyExtra(&extra) + } + } + + for _, opt := range opts { + if dialOpt, ok := opt.(dialerOption); ok { + dialer = dialOpt.baseDialer() + } + } + + if dialer == nil { + dialer = transport.NetDialer(settings.Timeout) + } + + tls, err := tlscommon.LoadTLSConfig(settings.TLS) + if err != nil { + return nil, err + } + + tlsDialer := transport.TLSDialer(dialer, tls, settings.Timeout) + for _, opt := range opts { + if dialOpt, ok := opt.(dialerModOption); ok { + dialer = dialOpt.applyDialer(settings, dialer) + tlsDialer = dialOpt.applyDialer(settings, tlsDialer) + } + } + + if logger := extra.logger; logger != nil { + dialer = transport.LoggingDialer(dialer, logger) + tlsDialer = transport.LoggingDialer(tlsDialer, logger) + } + + var rt http.RoundTripper + if extra.http2 { + rt, err = settings.http2RoundTripper(tls, dialer, tlsDialer, opts...) + } else { + rt, err = settings.httpRoundTripper(tls, dialer, tlsDialer, opts...) + } + + for _, opt := range opts { + if rtOpt, ok := opt.(roundTripperOption); ok { + rt = rtOpt.applyRoundTripper(settings, rt) + } + } + return rt, nil +} + +func (settings *HTTPTransportSettings) httpRoundTripper( + tls *tlscommon.TLSConfig, + dialer, tlsDialer transport.Dialer, + opts ...TransportOption, +) (*http.Transport, error) { + t := http.DefaultTransport.(*http.Transport).Clone() + t.DialContext = nil + t.DialTLSContext = nil + t.Dial = dialer.Dial + t.DialTLS = tlsDialer.Dial + t.TLSClientConfig = tls.ToConfig() + t.ForceAttemptHTTP2 = false + t.Proxy = settings.Proxy.ProxyFunc() + t.ProxyConnectHeader = settings.Proxy.Headers + + // reset some internal timeouts to not change old Beats defaults + t.TLSHandshakeTimeout = 0 + t.ExpectContinueTimeout = 0 + + for _, opt := range opts { + if transportOpt, ok := opt.(httpTransportOption); ok { + transportOpt.applyTransport(settings, t) + } + } + + return t, nil +} + +func (settings *HTTPTransportSettings) http2RoundTripper( + tls *tlscommon.TLSConfig, + dialer, tlsDialer transport.Dialer, + opts ...TransportOption, +) (*http2.Transport, error) { + t1, err := settings.httpRoundTripper(tls, dialer, tlsDialer, opts...) + if err != nil { + return nil, err + } + + t2, err := http2.ConfigureTransports(t1) + if err != nil { + return nil, err + } + + t2.AllowHTTP = true + return t2, nil +} + +// Client creates a new http.Client with configured Transport. The transport is +// instrumented using apmhttp.WrapRoundTripper. +func (settings HTTPTransportSettings) Client(opts ...TransportOption) (*http.Client, error) { + rt, err := settings.RoundTripper(opts...) + if err != nil { + return nil, err + } + + return &http.Client{Transport: rt, Timeout: settings.Timeout}, nil +} + +func (opts WithKeepaliveSettings) sealTransportOption() {} +func (opts WithKeepaliveSettings) applyTransport(_ *HTTPTransportSettings, t *http.Transport) { + t.DisableKeepAlives = opts.Disable + if opts.IdleConnTimeout != 0 { + t.IdleConnTimeout = opts.IdleConnTimeout + } + if opts.MaxIdleConns != 0 { + t.MaxIdleConns = opts.MaxIdleConns + } + if opts.MaxIdleConnsPerHost != 0 { + t.MaxIdleConnsPerHost = opts.MaxIdleConnsPerHost + } +} + +// WithBaseDialer configures the dialer used for TCP and TLS connections. +func WithBaseDialer(d transport.Dialer) TransportOption { + return baseDialerFunc(func() transport.Dialer { + return d + }) +} + +// WithIOStats instruments the RoundTripper dialers with the given statser, such +// that bytes in, bytes out, and errors can be monitored. +func WithIOStats(stats transport.IOStatser) TransportOption { + return dialerOptFunc(func(d transport.Dialer) transport.Dialer { + if stats == nil { + return d + } + return transport.StatsDialer(d, stats) + }) +} + +// WithTransportFunc register a custom function that is used to apply +// custom changes to the net.Transport, when the Client is build. +func WithTransportFunc(fn func(*http.Transport)) TransportOption { + return transportOptFunc(func(_ *HTTPTransportSettings, t *http.Transport) { + fn(t) + }) +} + +// WithHTTP2Only will ensure that a HTTP 2 only roundtripper is created. +func WithHTTP2Only(b bool) TransportOption { + return extraOptionFunc(func(settings *extraSettings) { + settings.http2 = b + }) +} + +// WithForceAttemptHTTP2 sets the `http.Tansport.ForceAttemptHTTP2` field. +func WithForceAttemptHTTP2(b bool) TransportOption { + return transportOptFunc(func(settings *HTTPTransportSettings, t *http.Transport) { + t.ForceAttemptHTTP2 = b + }) +} + +// WithNOProxy disables the configured proxy. Proxy environment variables +// like HTTP_PROXY and HTTPS_PROXY will have no affect. +func WithNOProxy() TransportOption { + return transportOptFunc(func(s *HTTPTransportSettings, t *http.Transport) { + t.Proxy = nil + }) +} + +// WithoutProxyEnvironmentVariables disables support for the HTTP_PROXY, HTTPS_PROXY and +// NO_PROXY envionrment variables. Explicitely configured proxy URLs will still applied. +func WithoutProxyEnvironmentVariables() TransportOption { + return transportOptFunc(func(settings *HTTPTransportSettings, t *http.Transport) { + if settings.Proxy.Disable || settings.Proxy.URL == nil { + t.Proxy = nil + } + }) +} + +// WithModRoundtripper allows customization of the roundtipper. +func WithModRoundtripper(w func(http.RoundTripper) http.RoundTripper) TransportOption { + return rtOptFunc(w) +} + +var withAPMHTTPRountTripper = WithModRoundtripper(func(rt http.RoundTripper) http.RoundTripper { + return apmhttp.WrapRoundTripper(rt) +}) + +// WithAPMHTTPInstrumentation insruments the HTTP client via apmhttp.WrapRoundTripper. +// Custom APM round tripper wrappers can be configured via WithModRoundtripper. +func WithAPMHTTPInstrumentation() TransportOption { + return withAPMHTTPRountTripper +} + +// WithLogger sets the internal logger that will be used to log dial or TCP level errors. +// Logging at the connection level will only happen if the logger has been set. +func WithLogger(logger *logp.Logger) TransportOption { + return extraOptionFunc(func(s *extraSettings) { + s.logger = logger + }) +} diff --git a/libbeat/common/transport/httpcommon/proxy.go b/libbeat/common/transport/httpcommon/proxy.go new file mode 100644 index 00000000000..40275d04af5 --- /dev/null +++ b/libbeat/common/transport/httpcommon/proxy.go @@ -0,0 +1,102 @@ +// 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 httpcommon + +import ( + "net/http" + "net/url" + + "github.com/elastic/beats/v7/libbeat/common" +) + +// HTTPClientProxySettings provides common HTTP proxy setup support. +// +// Proxy usage will be disabled in general if Disable is set. +// If URL is not set, the proxy configuration will default +// to HTTP_PROXY, HTTPS_PPROXY, and NO_PROXY. +// +// The default (and zero) value of HTTPClientProxySettings has Proxy support +// enabled, and will select the proxy per URL based on the environment variables. +type HTTPClientProxySettings struct { + // Proxy URL to use for http connections. If the proxy url is configured, + // it is used for all connection attempts. All proxy related environment + // variables are ignored. + URL *url.URL `config:"proxy_url" yaml:"proxy_url,omitempty"` + + // Headers configures additonal headers that are send to the proxy + // during CONNECT requests. + Headers http.Header `config:"proxy_headers" yaml:"proxy_headers,omitempty"` + + // Disable HTTP proxy support. Configured URLs and environment variables + // are ignored. + Disable bool `config:"proxy_disable" yaml:"proxy_disable,omitempty"` +} + +// DefaultHTTPClientProxySettings returns the default HTTP proxy setting. +func DefaultHTTPClientProxySettings() HTTPClientProxySettings { + return HTTPClientProxySettings{} +} + +// Unpack sets the proxy settings from a config object. +// Note: Unpack is automatically used by the configuration system if `cfg.Unpack(&x)` is and X contains +// a field of type HTTPClientProxySettings. +func (settings *HTTPClientProxySettings) Unpack(cfg *common.Config) error { + tmp := struct { + URL string `config:"proxy_url"` + Disable bool `config:"proxy_disable"` + Headers map[string]string `config:"proxy_headers"` + }{} + + if err := cfg.Unpack(&tmp); err != nil { + return err + } + + url, err := common.ParseURL(tmp.URL) + if err != nil { + return err + } + + var headers http.Header + if len(tmp.Headers) > 0 { + headers = http.Header{} + for k, v := range tmp.Headers { + headers.Add(k, v) + } + } + + *settings = HTTPClientProxySettings{ + URL: url, + Disable: tmp.Disable, + Headers: headers, + } + return nil +} + +// ProxyFunc creates a function that can be used with http.Transport in order to +// configure the HTTP proxy functionality. +func (settings *HTTPClientProxySettings) ProxyFunc() func(*http.Request) (*url.URL, error) { + if settings.Disable { + return nil + } + + if settings.URL == nil { + return http.ProxyFromEnvironment + } + + return http.ProxyURL(settings.URL) +} diff --git a/libbeat/common/transport/tls.go b/libbeat/common/transport/tls.go index edef5a6ab9f..5f8ade67012 100644 --- a/libbeat/common/transport/tls.go +++ b/libbeat/common/transport/tls.go @@ -29,7 +29,7 @@ import ( "github.com/elastic/beats/v7/libbeat/testing" ) -func TLSDialer(forward Dialer, config *tlscommon.TLSConfig, timeout time.Duration) (Dialer, error) { +func TLSDialer(forward Dialer, config *tlscommon.TLSConfig, timeout time.Duration) Dialer { return TestTLSDialer(testing.NullDriver, forward, config, timeout) } @@ -38,7 +38,7 @@ func TestTLSDialer( forward Dialer, config *tlscommon.TLSConfig, timeout time.Duration, -) (Dialer, error) { +) Dialer { var lastTLSConfig *tls.Config var lastNetwork string var lastAddress string @@ -70,7 +70,7 @@ func TestTLSDialer( m.Unlock() return tlsDialWith(d, forward, network, address, timeout, tlsConfig, config) - }), nil + }) } type DialerH2 interface { diff --git a/libbeat/common/transport/tlscommon/config.go b/libbeat/common/transport/tlscommon/config.go index cebc251fd49..41d1ad6532c 100644 --- a/libbeat/common/transport/tlscommon/config.go +++ b/libbeat/common/transport/tlscommon/config.go @@ -33,11 +33,11 @@ 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 []tlsCipherSuite `config:"cipher_suites" yaml:"cipher_suites,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"` + Renegotiation TlsRenegotiationSupport `config:"renegotiation" yaml:"renegotiation"` CASha256 []string `config:"ca_sha256" yaml:"ca_sha256,omitempty"` } @@ -59,11 +59,6 @@ func LoadTLSConfig(config *Config) (*TLSConfig, error) { } } - var cipherSuites []uint16 - for _, suite := range config.CipherSuites { - cipherSuites = append(cipherSuites, uint16(suite)) - } - var curves []tls.CurveID for _, id := range config.CurveTypes { curves = append(curves, tls.CurveID(id)) @@ -91,7 +86,7 @@ func LoadTLSConfig(config *Config) (*TLSConfig, error) { Verification: config.VerificationMode, Certificates: certs, RootCAs: cas, - CipherSuites: cipherSuites, + CipherSuites: config.CipherSuites, CurvePreferences: curves, Renegotiation: tls.RenegotiationSupport(config.Renegotiation), CASha256: config.CASha256, diff --git a/libbeat/common/transport/tlscommon/server_config.go b/libbeat/common/transport/tlscommon/server_config.go index e85a0c409c3..cf7ab9a390a 100644 --- a/libbeat/common/transport/tlscommon/server_config.go +++ b/libbeat/common/transport/tlscommon/server_config.go @@ -30,7 +30,7 @@ type ServerConfig struct { Enabled *bool `config:"enabled"` VerificationMode TLSVerificationMode `config:"verification_mode"` // one of 'none', 'full', 'strict', 'certificate' Versions []TLSVersion `config:"supported_protocols"` - CipherSuites []tlsCipherSuite `config:"cipher_suites"` + CipherSuites []CipherSuite `config:"cipher_suites"` CAs []string `config:"certificate_authorities"` Certificate CertificateConfig `config:",inline"` CurveTypes []tlsCurveType `config:"curve_types"` @@ -86,7 +86,7 @@ func LoadTLSServerConfig(config *ServerConfig) (*TLSConfig, error) { Verification: config.VerificationMode, Certificates: certs, ClientCAs: cas, - CipherSuites: cipherSuites, + CipherSuites: config.CipherSuites, CurvePreferences: curves, ClientAuth: tls.ClientAuthType(config.ClientAuth), CASha256: config.CASha256, diff --git a/libbeat/common/transport/tlscommon/tls.go b/libbeat/common/transport/tlscommon/tls.go index e5388eaf8ce..9850546f221 100644 --- a/libbeat/common/transport/tlscommon/tls.go +++ b/libbeat/common/transport/tlscommon/tls.go @@ -202,7 +202,7 @@ func ResolveTLSVersion(v uint16) string { // ResolveCipherSuite takes the integer representation and return the cipher name. func ResolveCipherSuite(cipher uint16) string { - return tlsCipherSuite(cipher).String() + return CipherSuite(cipher).String() } // PEMReader allows to read a certificate in PEM format either through the disk or from a string. diff --git a/libbeat/common/transport/tlscommon/tls_config.go b/libbeat/common/transport/tlscommon/tls_config.go index 718dbe42db9..77c60f951f8 100644 --- a/libbeat/common/transport/tlscommon/tls_config.go +++ b/libbeat/common/transport/tlscommon/tls_config.go @@ -56,7 +56,7 @@ type TLSConfig struct { // List of supported cipher suites. If nil, a default list provided by the // implementation will be used. - CipherSuites []uint16 + CipherSuites []CipherSuite // Types of elliptic curves that will be used in an ECDHE handshake. If empty, // the implementation will choose a default. @@ -97,6 +97,7 @@ func (c *TLSConfig) ToConfig() *tls.Config { if c.Verification == VerifyNone { logp.NewLogger("tls").Warn("SSL/TLS verifications disabled.") } + return &tls.Config{ MinVersion: minVersion, MaxVersion: maxVersion, @@ -104,7 +105,7 @@ func (c *TLSConfig) ToConfig() *tls.Config { RootCAs: c.RootCAs, ClientCAs: c.ClientCAs, InsecureSkipVerify: insecure, - CipherSuites: c.CipherSuites, + CipherSuites: convCipherSuites(c.CipherSuites), CurvePreferences: c.CurvePreferences, Renegotiation: c.Renegotiation, ClientAuth: c.ClientAuth, diff --git a/libbeat/common/transport/tlscommon/types.go b/libbeat/common/transport/tlscommon/types.go index 29b11c92010..ed24138394d 100644 --- a/libbeat/common/transport/tlscommon/types.go +++ b/libbeat/common/transport/tlscommon/types.go @@ -35,44 +35,44 @@ var ( ErrCertificateUnspecified = errors.New("certificate file not configured") ) -var tlsCipherSuites = map[string]tlsCipherSuite{ +var tlsCipherSuites = map[string]CipherSuite{ // ECDHE-ECDSA - "ECDHE-ECDSA-AES-128-CBC-SHA": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), - "ECDHE-ECDSA-AES-128-CBC-SHA256": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), - "ECDHE-ECDSA-AES-128-GCM-SHA256": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), - "ECDHE-ECDSA-AES-256-CBC-SHA": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), - "ECDHE-ECDSA-AES-256-GCM-SHA384": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), - "ECDHE-ECDSA-CHACHA20-POLY1305": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305), - "ECDHE-ECDSA-RC4-128-SHA": tlsCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), + "ECDHE-ECDSA-AES-128-CBC-SHA": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), + "ECDHE-ECDSA-AES-128-CBC-SHA256": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), + "ECDHE-ECDSA-AES-128-GCM-SHA256": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), + "ECDHE-ECDSA-AES-256-CBC-SHA": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), + "ECDHE-ECDSA-AES-256-GCM-SHA384": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), + "ECDHE-ECDSA-CHACHA20-POLY1305": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305), + "ECDHE-ECDSA-RC4-128-SHA": CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), // ECDHE-RSA - "ECDHE-RSA-3DES-CBC3-SHA": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), - "ECDHE-RSA-AES-128-CBC-SHA": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), - "ECDHE-RSA-AES-128-CBC-SHA256": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), - "ECDHE-RSA-AES-128-GCM-SHA256": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), - "ECDHE-RSA-AES-256-CBC-SHA": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), - "ECDHE-RSA-AES-256-GCM-SHA384": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384), - "ECDHE-RSA-CHACHA20-POLY1205": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305), - "ECDHE-RSA-RC4-128-SHA": tlsCipherSuite(tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA), + "ECDHE-RSA-3DES-CBC3-SHA": CipherSuite(tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), + "ECDHE-RSA-AES-128-CBC-SHA": CipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), + "ECDHE-RSA-AES-128-CBC-SHA256": CipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), + "ECDHE-RSA-AES-128-GCM-SHA256": CipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), + "ECDHE-RSA-AES-256-CBC-SHA": CipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), + "ECDHE-RSA-AES-256-GCM-SHA384": CipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384), + "ECDHE-RSA-CHACHA20-POLY1205": CipherSuite(tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305), + "ECDHE-RSA-RC4-128-SHA": CipherSuite(tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA), // RSA-X - "RSA-RC4-128-SHA": tlsCipherSuite(tls.TLS_RSA_WITH_RC4_128_SHA), - "RSA-3DES-CBC3-SHA": tlsCipherSuite(tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA), + "RSA-RC4-128-SHA": CipherSuite(tls.TLS_RSA_WITH_RC4_128_SHA), + "RSA-3DES-CBC3-SHA": CipherSuite(tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA), // RSA-AES - "RSA-AES-128-CBC-SHA": tlsCipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA), - "RSA-AES-128-CBC-SHA256": tlsCipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA256), - "RSA-AES-128-GCM-SHA256": tlsCipherSuite(tls.TLS_RSA_WITH_AES_128_GCM_SHA256), - "RSA-AES-256-CBC-SHA": tlsCipherSuite(tls.TLS_RSA_WITH_AES_256_CBC_SHA), - "RSA-AES-256-GCM-SHA384": tlsCipherSuite(tls.TLS_RSA_WITH_AES_256_GCM_SHA384), - - "TLS-AES-128-GCM-SHA256": tlsCipherSuite(tls.TLS_AES_128_GCM_SHA256), - "TLS-AES-256-GCM-SHA384": tlsCipherSuite(tls.TLS_AES_256_GCM_SHA384), - "TLS-CHACHA20-POLY1305-SHA256": tlsCipherSuite(tls.TLS_CHACHA20_POLY1305_SHA256), + "RSA-AES-128-CBC-SHA": CipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA), + "RSA-AES-128-CBC-SHA256": CipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA256), + "RSA-AES-128-GCM-SHA256": CipherSuite(tls.TLS_RSA_WITH_AES_128_GCM_SHA256), + "RSA-AES-256-CBC-SHA": CipherSuite(tls.TLS_RSA_WITH_AES_256_CBC_SHA), + "RSA-AES-256-GCM-SHA384": CipherSuite(tls.TLS_RSA_WITH_AES_256_GCM_SHA384), + + "TLS-AES-128-GCM-SHA256": CipherSuite(tls.TLS_AES_128_GCM_SHA256), + "TLS-AES-256-GCM-SHA384": CipherSuite(tls.TLS_AES_256_GCM_SHA384), + "TLS-CHACHA20-POLY1305-SHA256": CipherSuite(tls.TLS_CHACHA20_POLY1305_SHA256), } -var tlsCipherSuitesInverse = make(map[tlsCipherSuite]string, len(tlsCipherSuites)) -var tlsRenegotiationSupportTypesInverse = make(map[tlsRenegotiationSupport]string, len(tlsRenegotiationSupportTypes)) +var tlsCipherSuitesInverse = make(map[CipherSuite]string, len(tlsCipherSuites)) +var tlsRenegotiationSupportTypesInverse = make(map[TlsRenegotiationSupport]string, len(tlsRenegotiationSupportTypes)) var tlsVerificationModesInverse = make(map[TLSVerificationMode]string, len(tlsVerificationModes)) // Init creates a inverse representation of the values mapping. @@ -97,10 +97,10 @@ var tlsCurveTypes = map[string]tlsCurveType{ "X25519": tlsCurveType(tls.X25519), } -var tlsRenegotiationSupportTypes = map[string]tlsRenegotiationSupport{ - "never": tlsRenegotiationSupport(tls.RenegotiateNever), - "once": tlsRenegotiationSupport(tls.RenegotiateOnceAsClient), - "freely": tlsRenegotiationSupport(tls.RenegotiateFreelyAsClient), +var tlsRenegotiationSupportTypes = map[string]TlsRenegotiationSupport{ + "never": TlsRenegotiationSupport(tls.RenegotiateNever), + "once": TlsRenegotiationSupport(tls.RenegotiateOnceAsClient), + "freely": TlsRenegotiationSupport(tls.RenegotiateFreelyAsClient), } type tlsClientAuth int @@ -194,9 +194,9 @@ func (m *tlsClientAuth) Unpack(in interface{}) error { return nil } -type tlsCipherSuite uint16 +type CipherSuite uint16 -func (cs *tlsCipherSuite) Unpack(s string) error { +func (cs *CipherSuite) Unpack(s string) error { suite, found := tlsCipherSuites[s] if !found { return fmt.Errorf("invalid tls cipher suite '%v'", s) @@ -206,7 +206,7 @@ func (cs *tlsCipherSuite) Unpack(s string) error { return nil } -func (cs tlsCipherSuite) String() string { +func (cs CipherSuite) String() string { if s, found := tlsCipherSuitesInverse[cs]; found { return s } @@ -225,9 +225,16 @@ func (ct *tlsCurveType) Unpack(s string) error { return nil } -type tlsRenegotiationSupport tls.RenegotiationSupport +type TlsRenegotiationSupport tls.RenegotiationSupport -func (r *tlsRenegotiationSupport) Unpack(s string) error { +func (r TlsRenegotiationSupport) String() string { + if t, found := tlsRenegotiationSupportTypesInverse[r]; found { + return t + } + return "" +} + +func (r *TlsRenegotiationSupport) Unpack(s string) error { t, found := tlsRenegotiationSupportTypes[s] if !found { return fmt.Errorf("invalid tls renegotiation type '%v'", s) @@ -237,7 +244,7 @@ func (r *tlsRenegotiationSupport) Unpack(s string) error { return nil } -func (r tlsRenegotiationSupport) MarshalText() ([]byte, error) { +func (r TlsRenegotiationSupport) MarshalText() ([]byte, error) { if t, found := tlsRenegotiationSupportTypesInverse[r]; found { return []byte(t), nil } @@ -245,6 +252,14 @@ func (r tlsRenegotiationSupport) MarshalText() ([]byte, error) { return nil, fmt.Errorf("could not marshal '%+v' to text", r) } +func (r TlsRenegotiationSupport) MarshalYAML() (interface{}, error) { + if t, found := tlsRenegotiationSupportTypesInverse[r]; found { + return t, nil + } + + return nil, fmt.Errorf("could not marshal '%+v' to text", r) +} + // CertificateConfig define a common set of fields for a certificate. type CertificateConfig struct { Certificate string `config:"certificate" yaml:"certificate,omitempty"` @@ -265,3 +280,14 @@ func (c *CertificateConfig) Validate() error { } return nil } + +func convCipherSuites(suites []CipherSuite) []uint16 { + if len(suites) == 0 { + return nil + } + cipherSuites := make([]uint16, len(suites)) + for i, s := range suites { + cipherSuites[i] = uint16(s) + } + return cipherSuites +} diff --git a/libbeat/common/transport/transport.go b/libbeat/common/transport/transport.go index 35b397c5876..db1f1fb908a 100644 --- a/libbeat/common/transport/transport.go +++ b/libbeat/common/transport/transport.go @@ -58,7 +58,7 @@ func MakeDialer(c Config) (Dialer, error) { } if c.TLS != nil { - return TLSDialer(dialer, c.TLS, c.Timeout) + return TLSDialer(dialer, c.TLS, c.Timeout), nil } return dialer, nil } diff --git a/libbeat/esleg/eslegclient/api_test.go b/libbeat/esleg/eslegclient/api_test.go index 21897b9c1a1..fb4e42e11b9 100644 --- a/libbeat/esleg/eslegclient/api_test.go +++ b/libbeat/esleg/eslegclient/api_test.go @@ -172,8 +172,7 @@ func TestReadSearchResult_invalid(t *testing.T) { func newTestConnection(url string) *Connection { conn, _ := NewConnection(ConnectionSettings{ - URL: url, - Timeout: 0, + URL: url, }) conn.Encoder = NewJSONEncoder(nil, false) return conn diff --git a/libbeat/esleg/eslegclient/bulkapi_mock_test.go b/libbeat/esleg/eslegclient/bulkapi_mock_test.go index 3d4e33c4271..3f5c48b731e 100644 --- a/libbeat/esleg/eslegclient/bulkapi_mock_test.go +++ b/libbeat/esleg/eslegclient/bulkapi_mock_test.go @@ -228,7 +228,6 @@ func TestEnforceParameters(t *testing.T) { client, _ := NewConnection(ConnectionSettings{ Parameters: test.preconfigured, URL: "http://localhost", - Timeout: 0, }) client.Encoder = NewJSONEncoder(nil, false) diff --git a/libbeat/esleg/eslegclient/config.go b/libbeat/esleg/eslegclient/config.go index d9a299d68c7..d442cc2de5d 100644 --- a/libbeat/esleg/eslegclient/config.go +++ b/libbeat/esleg/eslegclient/config.go @@ -19,11 +19,9 @@ package eslegclient import ( "fmt" - "time" - "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/transport/kerberos" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type config struct { @@ -33,45 +31,33 @@ type config struct { Params map[string]string `config:"parameters"` Headers map[string]string `config:"headers"` - TLS *tlscommon.Config `config:"ssl"` - Kerberos *kerberos.Config `config:"kerberos"` - - ProxyURL string `config:"proxy_url"` - ProxyDisable bool `config:"proxy_disable"` + Kerberos *kerberos.Config `config:"kerberos"` Username string `config:"username"` Password string `config:"password"` APIKey string `config:"api_key"` - CompressionLevel int `config:"compression_level" validate:"min=0, max=9"` - EscapeHTML bool `config:"escape_html"` - Timeout time.Duration `config:"timeout"` + CompressionLevel int `config:"compression_level" validate:"min=0, max=9"` + EscapeHTML bool `config:"escape_html"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } func defaultConfig() config { return config{ Protocol: "", Path: "", - ProxyURL: "", - ProxyDisable: false, Params: nil, Username: "", Password: "", APIKey: "", - Timeout: 90 * time.Second, CompressionLevel: 0, EscapeHTML: false, - TLS: nil, + Transport: httpcommon.DefaultHTTPTransportSettings(), } } func (c *config) Validate() error { - if c.ProxyURL != "" && !c.ProxyDisable { - if _, err := common.ParseURL(c.ProxyURL); err != nil { - return err - } - } - if c.APIKey != "" && (c.Username != "" || c.Password != "") { return fmt.Errorf("cannot set both api_key and username/password") } diff --git a/libbeat/esleg/eslegclient/connection.go b/libbeat/esleg/eslegclient/connection.go index 6cc64bca263..795c8c94186 100644 --- a/libbeat/esleg/eslegclient/connection.go +++ b/libbeat/esleg/eslegclient/connection.go @@ -31,6 +31,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/transport" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/transport/kerberos" "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/elastic/beats/v7/libbeat/logp" @@ -56,16 +57,13 @@ type Connection struct { // ConnectionSettings are the settings needed for a Connection type ConnectionSettings struct { - URL string - Proxy *url.URL - ProxyDisable bool + URL string Username string Password string APIKey string // Raw API key, NOT base64-encoded Headers map[string]string - TLS *tlscommon.TLSConfig Kerberos *kerberos.Config OnConnectCallback func() error @@ -75,12 +73,15 @@ type ConnectionSettings struct { CompressionLevel int EscapeHTML bool - Timeout time.Duration IdleConnTimeout time.Duration + + Transport httpcommon.HTTPTransportSettings } // NewConnection returns a new Elasticsearch client func NewConnection(s ConnectionSettings) (*Connection, error) { + logger := logp.NewLogger("esclientleg") + s = settingsWithDefaults(s) u, err := url.Parse(s.URL) @@ -96,24 +97,7 @@ func NewConnection(s ConnectionSettings) (*Connection, error) { // Re-write URL without credentials. s.URL = u.String() } - logp.Info("elasticsearch url: %s", s.URL) - - // TODO: add socks5 proxy support - var dialer, tlsDialer transport.Dialer - - dialer = transport.NetDialer(s.Timeout) - tlsDialer, err = transport.TLSDialer(dialer, s.TLS, s.Timeout) - if err != nil { - return nil, err - } - - if st := s.Observer; st != nil { - dialer = transport.StatsDialer(dialer, st) - tlsDialer = transport.StatsDialer(tlsDialer, st) - } - logger := logp.NewLogger("esclientleg") - dialer = transport.LoggingDialer(dialer, logger) - tlsDialer = transport.LoggingDialer(tlsDialer, logger) + logger.Infof("elasticsearch url: %s", s.URL) var encoder BodyEncoder compression := s.CompressionLevel @@ -126,36 +110,23 @@ func NewConnection(s ConnectionSettings) (*Connection, error) { } } - var proxy func(*http.Request) (*url.URL, error) - if !s.ProxyDisable { - proxy = http.ProxyFromEnvironment - if s.Proxy != nil { - proxy = http.ProxyURL(s.Proxy) - } - } - - // when dropping the legacy client in favour of the official Go client, it should be instrumented - // eg, like in https://github.com/elastic/apm-server/blob/7.7/elasticsearch/client.go - transp := apmelasticsearch.WrapRoundTripper(&http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - TLSClientConfig: s.TLS.ToConfig(), - Proxy: proxy, - IdleConnTimeout: s.IdleConnTimeout, - }) - - var httpClient esHTTPClient - httpClient = &http.Client{ - Transport: transp, - Timeout: s.Timeout, + httpClient, err := s.Transport.Client( + httpcommon.WithLogger(logger), + httpcommon.WithIOStats(s.Observer), + httpcommon.WithKeepaliveSettings{IdleConnTimeout: s.IdleConnTimeout}, + httpcommon.WithModRoundtripper(func(rt http.RoundTripper) http.RoundTripper { + // when dropping the legacy client in favour of the official Go client, it should be instrumented + // eg, like in https://github.com/elastic/apm-server/blob/7.7/elasticsearch/client.go + return apmelasticsearch.WrapRoundTripper(rt) + }), + ) + if err != nil { + return nil, err } + esClient := esHTTPClient(httpClient) if s.Kerberos.IsEnabled() { - c := &http.Client{ - Transport: transp, - Timeout: s.Timeout, - } - httpClient, err = kerberos.NewClient(s.Kerberos, c, s.URL) + esClient, err = kerberos.NewClient(s.Kerberos, httpClient, s.URL) if err != nil { return nil, err } @@ -164,7 +135,7 @@ func NewConnection(s ConnectionSettings) (*Connection, error) { conn := Connection{ ConnectionSettings: s, - HTTP: httpClient, + HTTP: esClient, Encoder: encoder, log: logger, } @@ -195,20 +166,8 @@ func NewClients(cfg *common.Config) ([]Connection, error) { return nil, err } - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return nil, err - } - - var proxyURL *url.URL - if !config.ProxyDisable { - proxyURL, err = common.ParseURL(config.ProxyURL) - if err != nil { - return nil, err - } - if proxyURL != nil { - logp.Info("using proxy URL: %s", proxyURL) - } + if proxyURL := config.Transport.Proxy.URL; proxyURL != nil { + logp.Info("using proxy URL: %s", proxyURL) } params := config.Params @@ -226,17 +185,14 @@ func NewClients(cfg *common.Config) ([]Connection, error) { client, err := NewConnection(ConnectionSettings{ URL: esURL, - Proxy: proxyURL, - ProxyDisable: config.ProxyDisable, - TLS: tlsConfig, Kerberos: config.Kerberos, Username: config.Username, Password: config.Password, APIKey: config.APIKey, Parameters: params, Headers: config.Headers, - Timeout: config.Timeout, CompressionLevel: config.CompressionLevel, + Transport: config.Transport, }) if err != nil { return clients, err @@ -332,7 +288,7 @@ func (conn *Connection) Test(d testing.Driver) { address := u.Host d.Run("connection", func(d testing.Driver) { - netDialer := transport.TestNetDialer(d, conn.Timeout) + netDialer := transport.TestNetDialer(d, conn.Transport.Timeout) _, err = netDialer.Dial("tcp", address) d.Fatal("dial up", err) }) @@ -341,8 +297,13 @@ func (conn *Connection) Test(d testing.Driver) { d.Warn("TLS", "secure connection disabled") } else { d.Run("TLS", func(d testing.Driver) { - netDialer := transport.NetDialer(conn.Timeout) - tlsDialer, err := transport.TestTLSDialer(d, netDialer, conn.TLS, conn.Timeout) + tls, err := tlscommon.LoadTLSConfig(conn.Transport.TLS) + if err != nil { + d.Fatal("load tls config", err) + } + + netDialer := transport.NetDialer(conn.Transport.Timeout) + tlsDialer := transport.TestTLSDialer(d, netDialer, tls, conn.Transport.Timeout) _, err = tlsDialer.Dial("tcp", address) d.Fatal("dial up", err) }) diff --git a/libbeat/esleg/eslegclient/connection_integration_test.go b/libbeat/esleg/eslegclient/connection_integration_test.go index 225edd6f36c..25fef0ca24e 100644 --- a/libbeat/esleg/eslegclient/connection_integration_test.go +++ b/libbeat/esleg/eslegclient/connection_integration_test.go @@ -111,14 +111,14 @@ func connectTestEs(t *testing.T, cfg interface{}) (*Connection, error) { URL: hosts, Username: username, Password: password, - Timeout: time.Duration(timeout) * time.Second, CompressionLevel: 3, } + s.Transport.Timeout = time.Duration(timeout) * time.Second if proxy != "" { p, err := url.Parse(proxy) require.NoError(t, err) - s.Proxy = p + s.Transport.Proxy.URL = p } return NewConnection(s) @@ -130,9 +130,10 @@ func getTestingElasticsearch(t eslegtest.TestLogger) *Connection { URL: eslegtest.GetURL(), Username: eslegtest.GetUser(), Password: eslegtest.GetPass(), - Timeout: 60 * time.Second, CompressionLevel: 3, }) + conn.Transport.Timeout = 60 * time.Second + eslegtest.InitConnection(t, conn, err) return conn } diff --git a/libbeat/idxmgmt/ilm/client_handler_integration_test.go b/libbeat/idxmgmt/ilm/client_handler_integration_test.go index 9471da7c9cf..4d1e6f5ed64 100644 --- a/libbeat/idxmgmt/ilm/client_handler_integration_test.go +++ b/libbeat/idxmgmt/ilm/client_handler_integration_test.go @@ -31,6 +31,7 @@ import ( "github.com/stretchr/testify/require" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/idxmgmt/ilm" "github.com/elastic/beats/v7/libbeat/version" @@ -209,12 +210,14 @@ func newESClientHandler(t *testing.T) ilm.ClientHandler { } func newRawESClient(t *testing.T) ilm.ESClient { + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = 60 * time.Second client, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ URL: getURL(), Username: getUser(), Password: getPass(), - Timeout: 60 * time.Second, CompressionLevel: 3, + Transport: transport, }) if err != nil { t.Fatal(err) diff --git a/libbeat/kibana/client.go b/libbeat/kibana/client.go index c2ced9d864d..f12c49129ca 100644 --- a/libbeat/kibana/client.go +++ b/libbeat/kibana/client.go @@ -32,8 +32,6 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/elastic/beats/v7/libbeat/logp" ) @@ -125,38 +123,23 @@ func NewClientWithConfigDefault(config *ClientConfig, defaultPort int) (*Client, log := logp.NewLogger("kibana") log.Infof("Kibana url: %s", kibanaURL) - var dialer, tlsDialer transport.Dialer - - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return nil, fmt.Errorf("fail to load the TLS config: %v", err) + headers := make(http.Header) + for k, v := range config.Headers { + headers.Set(k, v) } - dialer = transport.NetDialer(config.Timeout) - tlsDialer, err = transport.TLSDialer(dialer, tlsConfig, config.Timeout) + rt, err := config.Transport.Client() if err != nil { return nil, err } - headers := make(http.Header) - for k, v := range config.Headers { - headers.Set(k, v) - } - client := &Client{ Connection: Connection{ URL: kibanaURL, Username: username, Password: password, Headers: headers, - HTTP: &http.Client{ - Transport: &http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - TLSClientConfig: tlsConfig.ToConfig(), - }, - Timeout: config.Timeout, - }, + HTTP: rt, }, log: log, } diff --git a/libbeat/kibana/client_config.go b/libbeat/kibana/client_config.go index 09709e3d81d..a10a8031242 100644 --- a/libbeat/kibana/client_config.go +++ b/libbeat/kibana/client_config.go @@ -18,38 +18,35 @@ package kibana import ( - "time" - - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) // ClientConfig to connect to Kibana type ClientConfig struct { - Protocol string `config:"protocol" yaml:"protocol,omitempty"` - Host string `config:"host" yaml:"host,omitempty"` - Path string `config:"path" yaml:"path,omitempty"` - SpaceID string `config:"space.id" yaml:"space.id,omitempty"` - Username string `config:"username" yaml:"username,omitempty"` - Password string `config:"password" yaml:"password,omitempty"` - TLS *tlscommon.Config `config:"ssl" yaml:"ssl"` - Timeout time.Duration `config:"timeout" yaml:"timeout"` + Protocol string `config:"protocol" yaml:"protocol,omitempty"` + Host string `config:"host" yaml:"host,omitempty"` + Path string `config:"path" yaml:"path,omitempty"` + SpaceID string `config:"space.id" yaml:"space.id,omitempty"` + Username string `config:"username" yaml:"username,omitempty"` + Password string `config:"password" yaml:"password,omitempty"` // Headers holds headers to include in every request sent to Kibana. Headers map[string]string `config:"headers" yaml:"headers,omitempty"` IgnoreVersion bool + + Transport httpcommon.HTTPTransportSettings `config:",inline" yaml:",inline"` } // DefaultClientConfig connects to a locally running kibana over HTTP func DefaultClientConfig() ClientConfig { return ClientConfig{ - Protocol: "http", - Host: "localhost:5601", - Path: "", - SpaceID: "", - Username: "", - Password: "", - Timeout: 90 * time.Second, - TLS: nil, + Protocol: "http", + Host: "localhost:5601", + Path: "", + SpaceID: "", + Username: "", + Password: "", + Transport: httpcommon.DefaultHTTPTransportSettings(), } } diff --git a/libbeat/licenser/elastic_fetcher_integration_test.go b/libbeat/licenser/elastic_fetcher_integration_test.go index 031a9b18b2e..ba1dd21a630 100644 --- a/libbeat/licenser/elastic_fetcher_integration_test.go +++ b/libbeat/licenser/elastic_fetcher_integration_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/elastic/beats/v7/libbeat/common/cli" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" ) @@ -35,13 +36,16 @@ const ( ) func getTestClient() *eslegclient.Connection { + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = 60 * time.Second + host := "http://" + cli.GetEnvOr("ES_HOST", elasticsearchHost) + ":" + cli.GetEnvOr("ES_POST", elasticsearchPort) client, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ URL: host, Username: "myelastic", // NOTE: I will refactor this in a followup PR Password: "changeme", CompressionLevel: 3, - Timeout: 60 * time.Second, + Transport: transport, }) if err != nil { diff --git a/libbeat/licenser/elastic_fetcher_test.go b/libbeat/licenser/elastic_fetcher_test.go index 3daa88a2d1a..731bf5c0618 100644 --- a/libbeat/licenser/elastic_fetcher_test.go +++ b/libbeat/licenser/elastic_fetcher_test.go @@ -24,7 +24,6 @@ import ( "os" "path/filepath" "testing" - "time" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" @@ -38,8 +37,7 @@ func newServerClientPair(t *testing.T, handler http.HandlerFunc) (*httptest.Serv server := httptest.NewServer(mux) client, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ - URL: server.URL, - Timeout: 90 * time.Second, + URL: server.URL, }) if err != nil { t.Fatalf("could not create the elasticsearch client, error: %s", err) diff --git a/libbeat/monitoring/report/elasticsearch/config.go b/libbeat/monitoring/report/elasticsearch/config.go index 8712bf1a88b..6cb30e47d3d 100644 --- a/libbeat/monitoring/report/elasticsearch/config.go +++ b/libbeat/monitoring/report/elasticsearch/config.go @@ -21,7 +21,7 @@ import ( "fmt" "time" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) // config is subset of libbeat/outputs/elasticsearch config tailored @@ -36,9 +36,7 @@ type config struct { APIKey string `config:"api_key"` ProxyURL string `config:"proxy_url"` CompressionLevel int `config:"compression_level" validate:"min=0, max=9"` - TLS *tlscommon.Config `config:"ssl"` MaxRetries int `config:"max_retries"` - Timeout time.Duration `config:"timeout"` MetricsPeriod time.Duration `config:"metrics.period"` StatePeriod time.Duration `config:"state.period"` BulkMaxSize int `config:"bulk_max_size" validate:"min=0"` @@ -46,6 +44,8 @@ type config struct { Tags []string `config:"tags"` Backoff backoff `config:"backoff"` ClusterUUID string `config:"cluster_uuid"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } type backoff struct { diff --git a/libbeat/monitoring/report/elasticsearch/elasticsearch.go b/libbeat/monitoring/report/elasticsearch/elasticsearch.go index 8913264a779..dddb2c53a00 100644 --- a/libbeat/monitoring/report/elasticsearch/elasticsearch.go +++ b/libbeat/monitoring/report/elasticsearch/elasticsearch.go @@ -21,13 +21,12 @@ import ( "errors" "io" "math/rand" - "net/url" "strconv" "time" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/monitoring" @@ -75,9 +74,7 @@ func defaultConfig(settings report.Settings) config { APIKey: "", ProxyURL: "", CompressionLevel: 0, - TLS: nil, MaxRetries: 3, - Timeout: 60 * time.Second, MetricsPeriod: 10 * time.Second, StatePeriod: 1 * time.Minute, BulkMaxSize: 50, @@ -88,6 +85,7 @@ func defaultConfig(settings report.Settings) config { Max: 60 * time.Second, }, ClusterUUID: settings.ClusterUUID, + Transport: httpcommon.DefaultHTTPTransportSettings(), } if settings.DefaultUsername != "" { @@ -117,18 +115,6 @@ func makeReporter(beat beat.Info, settings report.Settings, cfg *common.Config) windowSize = 1 } - proxyURL, err := common.ParseURL(config.ProxyURL) - if err != nil { - return nil, err - } - if proxyURL != nil { - log.Infof("Using proxy URL: %s", proxyURL) - } - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return nil, err - } - params := makeClientParams(config) hosts, err := outputs.ReadHostList(cfg) @@ -141,7 +127,7 @@ func makeReporter(beat beat.Info, settings report.Settings, cfg *common.Config) var clients []outputs.NetworkClient for _, host := range hosts { - client, err := makeClient(host, params, proxyURL, tlsConfig, &config) + client, err := makeClient(host, params, &config) if err != nil { return nil, err } @@ -305,13 +291,7 @@ func (r *reporter) snapshotLoop(namespace, prefix string, period time.Duration, } } -func makeClient( - host string, - params map[string]string, - proxyURL *url.URL, - tlsConfig *tlscommon.TLSConfig, - config *config, -) (outputs.NetworkClient, error) { +func makeClient(host string, params map[string]string, config *config) (outputs.NetworkClient, error) { url, err := common.MakeURL(config.Protocol, "", host, 9200) if err != nil { return nil, err @@ -319,15 +299,13 @@ func makeClient( esClient, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ URL: url, - Proxy: proxyURL, - TLS: tlsConfig, Username: config.Username, Password: config.Password, APIKey: config.APIKey, Parameters: params, Headers: config.Headers, - Timeout: config.Timeout, CompressionLevel: config.CompressionLevel, + Transport: config.Transport, }) if err != nil { return nil, err diff --git a/libbeat/outputs/elasticsearch/client.go b/libbeat/outputs/elasticsearch/client.go index 0794ee1c13b..b388001aeec 100644 --- a/libbeat/outputs/elasticsearch/client.go +++ b/libbeat/outputs/elasticsearch/client.go @@ -86,15 +86,12 @@ func NewClient( Password: s.Password, APIKey: s.APIKey, Headers: s.Headers, - TLS: s.TLS, Kerberos: s.Kerberos, - Proxy: s.Proxy, - ProxyDisable: s.ProxyDisable, Observer: s.Observer, Parameters: s.Parameters, CompressionLevel: s.CompressionLevel, EscapeHTML: s.EscapeHTML, - Timeout: s.Timeout, + Transport: s.Transport, }) if err != nil { return nil, err @@ -144,31 +141,31 @@ func (client *Client) Clone() *Client { // client's close is for example generated for topology-map support. With params // most likely containing the ingest node pipeline and default callback trying to // create install a template, we don't want these to be included in the clone. + connection := eslegclient.ConnectionSettings{ + URL: client.conn.URL, + Kerberos: client.conn.Kerberos, + Username: client.conn.Username, + Password: client.conn.Password, + APIKey: client.conn.APIKey, + Parameters: nil, // XXX: do not pass params? + Headers: client.conn.Headers, + CompressionLevel: client.conn.CompressionLevel, + OnConnectCallback: nil, + Observer: nil, + EscapeHTML: false, + Transport: client.conn.Transport, + } + + // Without the following nil check on proxyURL, a nil Proxy field will try + // reloading proxy settings from the environment instead of leaving them + // empty. + client.conn.Transport.Proxy.Disable = client.conn.Transport.Proxy.URL == nil c, _ := NewClient( ClientSettings{ - ConnectionSettings: eslegclient.ConnectionSettings{ - URL: client.conn.URL, - Proxy: client.conn.Proxy, - // Without the following nil check on proxyURL, a nil Proxy field will try - // reloading proxy settings from the environment instead of leaving them - // empty. - ProxyDisable: client.conn.Proxy == nil, - TLS: client.conn.TLS, - Kerberos: client.conn.Kerberos, - Username: client.conn.Username, - Password: client.conn.Password, - APIKey: client.conn.APIKey, - Parameters: nil, // XXX: do not pass params? - Headers: client.conn.Headers, - Timeout: client.conn.Timeout, - CompressionLevel: client.conn.CompressionLevel, - OnConnectCallback: nil, - Observer: nil, - EscapeHTML: false, - }, - Index: client.index, - Pipeline: client.pipeline, + ConnectionSettings: connection, + Index: client.index, + Pipeline: client.pipeline, }, nil, // XXX: do not pass connection callback? ) diff --git a/libbeat/outputs/elasticsearch/client_proxy_test.go b/libbeat/outputs/elasticsearch/client_proxy_test.go index 1e368d234ea..6dfe48fc183 100644 --- a/libbeat/outputs/elasticsearch/client_proxy_test.go +++ b/libbeat/outputs/elasticsearch/client_proxy_test.go @@ -34,6 +34,7 @@ import ( "github.com/stretchr/testify/require" "github.com/elastic/beats/v7/libbeat/common/atomic" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/outputs/outil" ) @@ -186,16 +187,20 @@ func doClientPing(t *testing.T) { proxyDisable := os.Getenv("TEST_PROXY_DISABLE") clientSettings := ClientSettings{ ConnectionSettings: eslegclient.ConnectionSettings{ - URL: serverURL, - Headers: map[string]string{headerTestField: headerTestValue}, - ProxyDisable: proxyDisable != "", + URL: serverURL, + Headers: map[string]string{headerTestField: headerTestValue}, + Transport: httpcommon.HTTPTransportSettings{ + Proxy: httpcommon.HTTPClientProxySettings{ + Disable: proxyDisable != "", + }, + }, }, Index: outil.MakeSelector(outil.ConstSelectorExpr("test", outil.SelectorLowerCase)), } if proxy != "" { proxyURL, err := url.Parse(proxy) require.NoError(t, err) - clientSettings.Proxy = proxyURL + clientSettings.Transport.Proxy.URL = proxyURL } client, err := NewClient(clientSettings, nil) require.NoError(t, err) diff --git a/libbeat/outputs/elasticsearch/config.go b/libbeat/outputs/elasticsearch/config.go index d094f005df5..bf2f7932fba 100644 --- a/libbeat/outputs/elasticsearch/config.go +++ b/libbeat/outputs/elasticsearch/config.go @@ -21,9 +21,8 @@ import ( "fmt" "time" - "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/transport/kerberos" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type elasticsearchConfig struct { @@ -34,17 +33,15 @@ type elasticsearchConfig struct { Username string `config:"username"` Password string `config:"password"` APIKey string `config:"api_key"` - ProxyURL string `config:"proxy_url"` - ProxyDisable bool `config:"proxy_disable"` LoadBalance bool `config:"loadbalance"` CompressionLevel int `config:"compression_level" validate:"min=0, max=9"` EscapeHTML bool `config:"escape_html"` - TLS *tlscommon.Config `config:"ssl"` Kerberos *kerberos.Config `config:"kerberos"` BulkMaxSize int `config:"bulk_max_size"` MaxRetries int `config:"max_retries"` - Timeout time.Duration `config:"timeout"` Backoff Backoff `config:"backoff"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } type Backoff struct { @@ -60,33 +57,24 @@ var ( defaultConfig = elasticsearchConfig{ Protocol: "", Path: "", - ProxyURL: "", - ProxyDisable: false, Params: nil, Username: "", Password: "", APIKey: "", - Timeout: 90 * time.Second, MaxRetries: 3, CompressionLevel: 0, EscapeHTML: false, - TLS: nil, Kerberos: nil, LoadBalance: true, Backoff: Backoff{ Init: 1 * time.Second, Max: 60 * time.Second, }, + Transport: httpcommon.DefaultHTTPTransportSettings(), } ) func (c *elasticsearchConfig) Validate() error { - if c.ProxyURL != "" && !c.ProxyDisable { - if _, err := common.ParseURL(c.ProxyURL); err != nil { - return err - } - } - if c.APIKey != "" && (c.Username != "" || c.Password != "") { return fmt.Errorf("cannot set both api_key and username/password") } diff --git a/libbeat/outputs/elasticsearch/docs/elasticsearch.asciidoc b/libbeat/outputs/elasticsearch/docs/elasticsearch.asciidoc index fbe9a918db3..80b2bb36879 100644 --- a/libbeat/outputs/elasticsearch/docs/elasticsearch.asciidoc +++ b/libbeat/outputs/elasticsearch/docs/elasticsearch.asciidoc @@ -170,6 +170,13 @@ output.elasticsearch.headers: It is possible to specify multiple header values for the same header name by separating them with a comma. + +===== `proxy_disable` + +If set to `true` all proxy settings, including `HTTP_PROXY` and `HTTPS_PROXY` +variables are ignored. + + ===== `proxy_url` The URL of the proxy to use when connecting to the Elasticsearch servers. The @@ -179,6 +186,11 @@ then proxy environment variables are used. See the https://golang.org/pkg/net/http/#ProxyFromEnvironment[Go documentation] for more information about the environment variables. + +===== `proxy_headers` + +Additional headers to send to proxies during CONNECT requests. + [[index-option-es]] ===== `index` diff --git a/libbeat/outputs/elasticsearch/elasticsearch.go b/libbeat/outputs/elasticsearch/elasticsearch.go index bf1f9bd378e..682d0e5a41e 100644 --- a/libbeat/outputs/elasticsearch/elasticsearch.go +++ b/libbeat/outputs/elasticsearch/elasticsearch.go @@ -18,11 +18,8 @@ package elasticsearch import ( - "net/url" - "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/libbeat/outputs" @@ -61,20 +58,8 @@ func makeES( return outputs.Fail(err) } - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return outputs.Fail(err) - } - - var proxyURL *url.URL - if !config.ProxyDisable { - proxyURL, err = common.ParseURL(config.ProxyURL) - if err != nil { - return outputs.Fail(err) - } - if proxyURL != nil { - log.Infof("Using proxy URL: %s", proxyURL) - } + if proxyURL := config.Transport.Proxy.URL; proxyURL != nil && !config.Transport.Proxy.Disable { + log.Infof("Using proxy URL: %s", proxyURL) } params := config.Params @@ -94,19 +79,16 @@ func makeES( client, err = NewClient(ClientSettings{ ConnectionSettings: eslegclient.ConnectionSettings{ URL: esURL, - Proxy: proxyURL, - ProxyDisable: config.ProxyDisable, - TLS: tlsConfig, Kerberos: config.Kerberos, Username: config.Username, Password: config.Password, APIKey: config.APIKey, Parameters: params, Headers: config.Headers, - Timeout: config.Timeout, CompressionLevel: config.CompressionLevel, Observer: observer, EscapeHTML: config.EscapeHTML, + Transport: config.Transport, }, Index: index, Pipeline: pipeline, diff --git a/libbeat/outputs/logstash/logstash_integration_test.go b/libbeat/outputs/logstash/logstash_integration_test.go index 9fdbd11d875..23db3b37614 100644 --- a/libbeat/outputs/logstash/logstash_integration_test.go +++ b/libbeat/outputs/logstash/logstash_integration_test.go @@ -33,6 +33,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/fmtstr" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/idxmgmt" "github.com/elastic/beats/v7/libbeat/outputs" @@ -102,11 +103,13 @@ func esConnect(t *testing.T, index string) *esConnection { username := os.Getenv("ES_USER") password := os.Getenv("ES_PASS") + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = 60 * time.Second client, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ - URL: host, - Username: username, - Password: password, - Timeout: 60 * time.Second, + URL: host, + Username: username, + Password: password, + Transport: transport, }) if err != nil { t.Fatal(err) diff --git a/libbeat/template/load_integration_test.go b/libbeat/template/load_integration_test.go index 528b87a445f..186c0070c5d 100644 --- a/libbeat/template/load_integration_test.go +++ b/libbeat/template/load_integration_test.go @@ -34,6 +34,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/esleg/eslegtest" "github.com/elastic/beats/v7/libbeat/version" @@ -404,8 +405,8 @@ func path(t *testing.T, fileElems []string) string { func getTestingElasticsearch(t eslegtest.TestLogger) *eslegclient.Connection { conn, err := eslegclient.NewConnection(eslegclient.ConnectionSettings{ - URL: eslegtest.GetURL(), - Timeout: 0, + URL: eslegtest.GetURL(), + Transport: httpcommon.DefaultHTTPTransportSettings(), }) if err != nil { t.Fatal(err) diff --git a/metricbeat/helper/config.go b/metricbeat/helper/config.go index 8581c45a015..d97e9248245 100644 --- a/metricbeat/helper/config.go +++ b/metricbeat/helper/config.go @@ -20,21 +20,24 @@ package helper import ( "time" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) // Config for an HTTP helper type Config struct { - TLS *tlscommon.Config `config:"ssl"` ConnectTimeout time.Duration `config:"connect_timeout"` - Timeout time.Duration `config:"timeout"` Headers map[string]string `config:"headers"` BearerTokenFile string `config:"bearer_token_file"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } func defaultConfig() Config { + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = 10 * time.Second + return Config{ ConnectTimeout: 2 * time.Second, - Timeout: 10 * time.Second, + Transport: transport, } } diff --git a/metricbeat/helper/http.go b/metricbeat/helper/http.go index 9fe541ffeea..ba53a0e42ea 100644 --- a/metricbeat/helper/http.go +++ b/metricbeat/helper/http.go @@ -28,8 +28,7 @@ import ( "github.com/pkg/errors" - "github.com/elastic/beats/v7/libbeat/common/transport" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/metricbeat/helper/dialer" "github.com/elastic/beats/v7/metricbeat/mb" ) @@ -74,11 +73,6 @@ func NewHTTPFromConfig(config Config, hostData mb.HostData) (*HTTP, error) { headers.Set("Authorization", header) } - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return nil, err - } - // Ensure backward compatibility builder := hostData.Transport if builder == nil { @@ -90,27 +84,21 @@ func NewHTTPFromConfig(config Config, hostData mb.HostData) (*HTTP, error) { return nil, err } - var tlsDialer transport.Dialer - tlsDialer, err = transport.TLSDialer(dialer, tlsConfig, config.ConnectTimeout) + client, err := config.Transport.Client( + httpcommon.WithBaseDialer(dialer), + httpcommon.WithAPMHTTPInstrumentation(), + ) if err != nil { return nil, err } return &HTTP{ hostData: hostData, - client: &http.Client{ - Transport: &http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - TLSClientConfig: tlsConfig.ToConfig(), - Proxy: http.ProxyFromEnvironment, - }, - Timeout: config.Timeout, - }, - headers: headers, - method: "GET", - uri: hostData.SanitizedURI, - body: nil, + client: client, + headers: headers, + method: "GET", + uri: hostData.SanitizedURI, + body: nil, }, nil } diff --git a/metricbeat/helper/http_test.go b/metricbeat/helper/http_test.go index 808147bebf0..a88ae4796fa 100644 --- a/metricbeat/helper/http_test.go +++ b/metricbeat/helper/http_test.go @@ -92,7 +92,7 @@ func TestTimeout(t *testing.T) { defer ts.Close() cfg := defaultConfig() - cfg.Timeout = 1 * time.Millisecond + cfg.Transport.Timeout = 1 * time.Millisecond hostData := mb.HostData{ URI: ts.URL, SanitizedURI: ts.URL, diff --git a/metricbeat/module/apache/status/status_test.go b/metricbeat/module/apache/status/status_test.go index c7346278c9e..464defd4623 100644 --- a/metricbeat/module/apache/status/status_test.go +++ b/metricbeat/module/apache/status/status_test.go @@ -178,12 +178,12 @@ func TestFetchTimeout(t *testing.T) { elapsed := time.Since(start) var found bool for _, err := range errs { - if strings.Contains(err.Error(), "context deadline exceeded (Client.Timeout exceeded") { + if strings.Contains(err.Error(), "Client.Timeout exceeded") { found = true } } if !found { - assert.Failf(t, "", "expected an error containing 'context deadline exceeded (Client.Timeout exceeded'. Got %v", errs) + assert.Failf(t, "", "expected an error containing 'Client.Timeout exceeded'. Got %v", errs) } // Elapsed should be ~50ms, sometimes it can be up to 1s diff --git a/metricbeat/module/elasticsearch/index/data_test.go b/metricbeat/module/elasticsearch/index/data_test.go index d85ec77aca3..7008e181712 100644 --- a/metricbeat/module/elasticsearch/index/data_test.go +++ b/metricbeat/module/elasticsearch/index/data_test.go @@ -29,6 +29,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/metricbeat/helper" "github.com/elastic/beats/v7/metricbeat/mb" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" @@ -50,7 +51,9 @@ func TestMapper(t *testing.T) { httpClient, err := helper.NewHTTPFromConfig(helper.Config{ ConnectTimeout: 30 * time.Second, - Timeout: 30 * time.Second, + Transport: httpcommon.HTTPTransportSettings{ + Timeout: 30 * time.Second, + }, }, mb.HostData{ URI: server.URL, SanitizedURI: server.URL, diff --git a/metricbeat/module/envoyproxy/server/server_test.go b/metricbeat/module/envoyproxy/server/server_test.go index df3b00886c9..50bed4bb107 100644 --- a/metricbeat/module/envoyproxy/server/server_test.go +++ b/metricbeat/module/envoyproxy/server/server_test.go @@ -184,12 +184,12 @@ func TestFetchTimeout(t *testing.T) { elapsed := time.Since(start) var found bool for _, err := range errs { - if strings.Contains(err.Error(), "context deadline exceeded (Client.Timeout exceeded") { + if strings.Contains(err.Error(), "Client.Timeout exceeded") { found = true } } if !found { - assert.Failf(t, "", "expected an error containing 'context deadline exceeded (Client.Timeout exceeded'. Got %v", errs) + assert.Failf(t, "", "expected an error containing '(Client.Timeout exceeded'. Got %v", errs) } assert.True(t, elapsed < 5*time.Second, "elapsed time: %s", elapsed.String()) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 7fe323a0b64..ffd8febf29c 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -115,5 +115,6 @@ - Use `filestream` input for internal log collection. {pull}25660[25660] - Enable agent to send custom headers to kibana/ES {pull}26275[26275] - Set `agent.id` to the Fleet Agent ID in events published from inputs backed by Beats. {issue}21121[21121] {pull}26394[26394] +- Add proxy support to artifact downloader and communication with fleet server. {pull}25219[25219] - Enable configuring monitoring namespace {issue}26439[26439] - Communicate with Fleet Server over HTTP2. {pull}26474[26474] diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/factory.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/factory.go index 70258ed1794..238be8228d7 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/factory.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/factory.go @@ -40,8 +40,22 @@ func Factory(ctx context.Context, agentInfo *info.AgentInfo, cfg *configuration. } } -func newOperator(ctx context.Context, log *logger.Logger, agentInfo *info.AgentInfo, id pipeline.RoutingKey, config *configuration.SettingsConfig, srv *server.Server, r state.Reporter, m monitoring.Monitor, statusController status.Controller) (*operation.Operator, error) { - fetcher := downloader.NewDownloader(log, config.DownloadConfig) +func newOperator( + ctx context.Context, + log *logger.Logger, + agentInfo *info.AgentInfo, + id pipeline.RoutingKey, + config *configuration.SettingsConfig, + srv *server.Server, + r state.Reporter, + m monitoring.Monitor, + statusController status.Controller, +) (*operation.Operator, error) { + fetcher, err := downloader.NewDownloader(log, config.DownloadConfig) + if err != nil { + return nil, err + } + allowEmptyPgp, pgp := release.PGP() verifier, err := downloader.NewVerifier(log, config.DownloadConfig, allowEmptyPgp, pgp) if err != nil { diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go index 888433ea0bc..2a88b8bfb2b 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go @@ -61,7 +61,7 @@ func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI stri func newDownloader(version string, log *logger.Logger, settings *artifact.Config) (download.Downloader, error) { if !strings.HasSuffix(version, "-SNAPSHOT") { - return downloader.NewDownloader(log, settings), nil + return downloader.NewDownloader(log, settings) } // try snapshot repo before official @@ -70,11 +70,12 @@ func newDownloader(version string, log *logger.Logger, settings *artifact.Config return nil, err } - return composed.NewDownloader( - fs.NewDownloader(settings), - snapDownloader, - http.NewDownloader(settings), - ), nil + httpDownloader, err := http.NewDownloader(settings) + if err != nil { + return nil, err + } + + return composed.NewDownloader(fs.NewDownloader(settings), snapDownloader, httpDownloader), nil } func newVerifier(version string, log *logger.Logger, settings *artifact.Config) (download.Verifier, error) { diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index 9f69013d41c..cc925d0cb4e 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -27,6 +27,7 @@ import ( "github.com/spf13/cobra" "gopkg.in/yaml.v2" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/elastic/beats/v7/libbeat/kibana" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" @@ -457,12 +458,15 @@ func kibanaClient(cfg kibanaConfig, headers map[string]string) (*kibana.Client, } } + transport := httpcommon.DefaultHTTPTransportSettings() + transport.TLS = tls + return kibana.NewClientWithConfigDefault(&kibana.ClientConfig{ Host: cfg.Fleet.Host, Username: cfg.Fleet.Username, Password: cfg.Fleet.Password, IgnoreVersion: true, - TLS: tls, + Transport: transport, Headers: headers, }, 0) } 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 e170d9dea0f..cbc5f209023 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go @@ -104,19 +104,18 @@ func (e *enrollCmdOption) remoteConfig() (remote.Config, error) { return remote.Config{}, fmt.Errorf("connection to fleet-server is insecure, strongly recommended to use a secure connection (override with --insecure)") } + var tlsCfg tlscommon.Config + // Add any SSL options from the CLI. if len(e.CAs) > 0 || len(e.CASha256) > 0 { - cfg.TLS = &tlscommon.Config{ - CAs: e.CAs, - CASha256: e.CASha256, - } + tlsCfg.CAs = e.CAs + tlsCfg.CASha256 = e.CASha256 } if e.Insecure { - cfg.TLS = &tlscommon.Config{ - VerificationMode: tlscommon.VerifyNone, - } + tlsCfg.VerificationMode = tlscommon.VerifyNone } + cfg.Transport.TLS = &tlsCfg return cfg, nil } diff --git a/x-pack/elastic-agent/pkg/artifact/config.go b/x-pack/elastic-agent/pkg/artifact/config.go index 78a0e62ad8a..d1181b778d2 100644 --- a/x-pack/elastic-agent/pkg/artifact/config.go +++ b/x-pack/elastic-agent/pkg/artifact/config.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" ) @@ -27,9 +28,6 @@ type Config struct { // TargetDirectory: path to the directory containing downloaded packages TargetDirectory string `json:"targetDirectory" config:"target_directory"` - // Timeout: timeout for downloading package - Timeout time.Duration `json:"timeout" config:"timeout"` - // InstallPath: path to the directory containing installed packages InstallPath string `yaml:"installPath" config:"install_path"` @@ -39,16 +37,23 @@ type Config struct { // local or network disk. // If not provided FileSystem Downloader will fallback to /beats subfolder of elastic-agent directory. DropPath string `yaml:"dropPath" config:"drop_path"` + + httpcommon.HTTPTransportSettings `config:",inline" yaml:",inline"` // Note: use anonymous struct for json inline } // DefaultConfig creates a config with pre-set default values. func DefaultConfig() *Config { homePath := paths.Home() + transport := httpcommon.DefaultHTTPTransportSettings() + + // binaries are a getting bit larger it might take >30s to download them + transport.Timeout = 120 * time.Second + return &Config{ - SourceURI: "https://artifacts.elastic.co/downloads/", - TargetDirectory: filepath.Join(homePath, "downloads"), - Timeout: 120 * time.Second, // binaries are a getting bit larger it might take >30s to download them - InstallPath: filepath.Join(homePath, "install"), + SourceURI: "https://artifacts.elastic.co/downloads/", + TargetDirectory: filepath.Join(homePath, "downloads"), + InstallPath: filepath.Join(homePath, "install"), + HTTPTransportSettings: transport, } } diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go index 8abea0e59f0..44ac7b748bd 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -47,9 +48,11 @@ func TestFetchVerify(t *testing.T) { TargetDirectory: targetPath, DropPath: dropPath, InstallPath: installPath, - Timeout: timeout, OperatingSystem: "darwin", Architecture: "32", + HTTPTransportSettings: httpcommon.HTTPTransportSettings{ + Timeout: timeout, + }, } err := prepareFetchVerifyTests(dropPath, targetPath, targetFilePath, hashTargetFilePath) @@ -134,9 +137,11 @@ func TestVerify(t *testing.T) { config := &artifact.Config{ TargetDirectory: targetDir, DropPath: filepath.Join(targetDir, "drop"), - Timeout: timeout, OperatingSystem: "linux", Architecture: "32", + HTTPTransportSettings: httpcommon.HTTPTransportSettings{ + Timeout: timeout, + }, } if err := prepareTestCase(beatSpec, version, config); err != nil { diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go index dcb42daf148..15f969880bf 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go @@ -14,6 +14,7 @@ import ( "path" "strings" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" @@ -36,11 +37,16 @@ type Downloader struct { } // NewDownloader creates and configures Elastic Downloader -func NewDownloader(config *artifact.Config) *Downloader { - client := http.Client{Timeout: config.Timeout} - rt := withHeaders(client.Transport, headers) - client.Transport = rt - return NewDownloaderWithClient(config, client) +func NewDownloader(config *artifact.Config) (*Downloader, error) { + client, err := config.HTTPTransportSettings.Client( + httpcommon.WithAPMHTTPInstrumentation(), + ) + if err != nil { + return nil, err + } + + client.Transport = withHeaders(client.Transport, headers) + return NewDownloaderWithClient(config, *client), nil } // NewDownloaderWithClient creates Elastic Downloader with specific client used diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go index a329b9b2f8e..747324a7cc7 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -54,7 +55,9 @@ func TestDownload(t *testing.T) { config := &artifact.Config{ SourceURI: source, TargetDirectory: targetDir, - Timeout: timeout, + HTTPTransportSettings: httpcommon.HTTPTransportSettings{ + Timeout: timeout, + }, } for _, testCase := range testCases { @@ -92,7 +95,9 @@ func TestVerify(t *testing.T) { config := &artifact.Config{ SourceURI: source, TargetDirectory: targetDir, - Timeout: timeout, + HTTPTransportSettings: httpcommon.HTTPTransportSettings{ + Timeout: timeout, + }, } for _, testCase := range testCases { diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go index b206bd5faea..2e47c8dd6ca 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go @@ -19,6 +19,7 @@ import ( "golang.org/x/crypto/openpgp" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "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/artifact" @@ -46,12 +47,19 @@ func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (*Veri return nil, errors.New("expecting PGP but retrieved none", errors.TypeSecurity) } - client := http.Client{Timeout: config.Timeout} - rtt := withHeaders(client.Transport, headers) - client.Transport = rtt + client, err := config.HTTPTransportSettings.Client( + httpcommon.WithAPMHTTPInstrumentation(), + httpcommon.WithModRoundtripper(func(rt http.RoundTripper) http.RoundTripper { + return withHeaders(rt, headers) + }), + ) + if err != nil { + return nil, err + } + v := &Verifier{ config: config, - client: client, + client: *client, allowEmptyPgp: allowEmptyPgp, pgpBytes: pgp, } diff --git a/x-pack/elastic-agent/pkg/artifact/download/localremote/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/localremote/downloader.go index 6934adc1ea3..fe6c79fedee 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/localremote/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/localremote/downloader.go @@ -17,7 +17,7 @@ import ( // NewDownloader creates a downloader which first checks local directory // and then fallbacks to remote if configured. -func NewDownloader(log *logger.Logger, config *artifact.Config) download.Downloader { +func NewDownloader(log *logger.Logger, config *artifact.Config) (download.Downloader, error) { downloaders := make([]download.Downloader, 0, 3) downloaders = append(downloaders, fs.NewDownloader(config)) @@ -31,6 +31,11 @@ func NewDownloader(log *logger.Logger, config *artifact.Config) download.Downloa } } - downloaders = append(downloaders, http.NewDownloader(config)) - return composed.NewDownloader(downloaders...) + httpDownloader, err := http.NewDownloader(config) + if err != nil { + return nil, err + } + + downloaders = append(downloaders, httpDownloader) + return composed.NewDownloader(downloaders...), nil } diff --git a/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go index a5b706a243c..acf6b32328f 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go @@ -23,7 +23,7 @@ func NewDownloader(config *artifact.Config, versionOverride string) (download.Do if err != nil { return nil, err } - return http.NewDownloader(cfg), nil + return http.NewDownloader(cfg) } func snapshotConfig(config *artifact.Config, versionOverride string) (*artifact.Config, error) { @@ -33,13 +33,13 @@ func snapshotConfig(config *artifact.Config, versionOverride string) (*artifact. } return &artifact.Config{ - OperatingSystem: config.OperatingSystem, - Architecture: config.Architecture, - SourceURI: snapshotURI, - TargetDirectory: config.TargetDirectory, - Timeout: config.Timeout, - InstallPath: config.InstallPath, - DropPath: config.DropPath, + OperatingSystem: config.OperatingSystem, + Architecture: config.Architecture, + SourceURI: snapshotURI, + TargetDirectory: config.TargetDirectory, + InstallPath: config.InstallPath, + DropPath: config.DropPath, + HTTPTransportSettings: config.HTTPTransportSettings, }, nil } diff --git a/x-pack/elastic-agent/pkg/remote/client.go b/x-pack/elastic-agent/pkg/remote/client.go index ad5f136f7e0..44f5b7ad562 100644 --- a/x-pack/elastic-agent/pkg/remote/client.go +++ b/x-pack/elastic-agent/pkg/remote/client.go @@ -15,11 +15,9 @@ import ( "time" "github.com/pkg/errors" - "golang.org/x/net/http2" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" ) @@ -118,12 +116,11 @@ func NewWithConfig(log *logger.Logger, cfg Config, wrapper wrapperFunc) (*Client if err != nil { return nil, errors.Wrap(err, "invalid fleet-server endpoint") } - addr, err := url.Parse(connStr) - if err != nil { - return nil, errors.Wrap(err, "invalid fleet-server endpoint") - } - transport, err := makeTransport(addr.Scheme, cfg.Timeout, cfg.TLS) + transport, err := cfg.Transport.RoundTripper( + httpcommon.WithAPMHTTPInstrumentation(), + httpcommon.WithForceAttemptHTTP2(true), + ) if err != nil { return nil, err } @@ -142,7 +139,7 @@ func NewWithConfig(log *logger.Logger, cfg Config, wrapper wrapperFunc) (*Client httpClient := http.Client{ Transport: transport, - Timeout: cfg.Timeout, + Timeout: cfg.Transport.Timeout, } clients[i] = &requestClient{ @@ -275,20 +272,3 @@ func prefixRequestFactory(URL string) requestFunc { return http.NewRequest(method, newPath, body) } } - -// makeTransport create a transport object based on the TLS configuration. -func makeTransport(scheme string, timeout time.Duration, tls *tlscommon.Config) (http.RoundTripper, error) { - dialer := transport.NetDialer(timeout) - if scheme == "http" { - return &http.Transport{Dial: dialer.Dial}, nil - } - tlsConfig, err := tlscommon.LoadTLSConfig(tls) - if err != nil { - return nil, errors.Wrap(err, "invalid TLS configuration") - } - tlsDialer, err := transport.TLSDialerH2(dialer, tlsConfig, timeout) - if err != nil { - return nil, errors.Wrap(err, "fail to create TLS dialer") - } - return &http2.Transport{DialTLS: tlsDialer.Dial}, nil -} diff --git a/x-pack/elastic-agent/pkg/remote/config.go b/x-pack/elastic-agent/pkg/remote/config.go index 02b32274f2f..31ae29f70ba 100644 --- a/x-pack/elastic-agent/pkg/remote/config.go +++ b/x-pack/elastic-agent/pkg/remote/config.go @@ -8,20 +8,20 @@ import ( "fmt" "time" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) // Config is the configuration for the client. 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"` - Timeout time.Duration `config:"timeout" yaml:"timeout,omitempty"` - TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` + 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"` + + Transport httpcommon.HTTPTransportSettings `config:",inline" yaml:",inline"` } // Protocol define the protocol to use to make the connection. (Either HTTPS or HTTP) @@ -46,16 +46,18 @@ func (p *Protocol) Unpack(from string) error { // DefaultClientConfig creates default configuration for client. func DefaultClientConfig() Config { + transport := httpcommon.DefaultHTTPTransportSettings() + // Default timeout 10 minutes, expecting Fleet Server to control the long poll with default timeout of 5 minutes + transport.Timeout = 10 * time.Minute + return Config{ - Protocol: ProtocolHTTP, - Host: "localhost:5601", - Path: "", - SpaceID: "", - Username: "", - Password: "", - // Default timeout 10 minutes, expecting Fleet Server to control the long poll with default timeout of 5 minutes - Timeout: 10 * time.Minute, - TLS: nil, + Protocol: ProtocolHTTP, + Host: "localhost:5601", + Path: "", + SpaceID: "", + Username: "", + Password: "", + Transport: transport, } } diff --git a/x-pack/elastic-agent/pkg/remote/config_test.go b/x-pack/elastic-agent/pkg/remote/config_test.go index 21843a4b047..403609735dd 100644 --- a/x-pack/elastic-agent/pkg/remote/config_test.go +++ b/x-pack/elastic-agent/pkg/remote/config_test.go @@ -13,6 +13,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) func TestPackUnpack(t *testing.T) { @@ -22,7 +24,9 @@ func TestPackUnpack(t *testing.T) { Username: "foo", Password: "bar", Path: "/ok", - Timeout: 10 * time.Second, + Transport: httpcommon.HTTPTransportSettings{ + Timeout: 10 * time.Second, + }, } b, err := yaml.Marshal(&c) diff --git a/x-pack/filebeat/input/httpjson/config.go b/x-pack/filebeat/input/httpjson/config.go index 6384811aaa4..a2965ace4ef 100644 --- a/x-pack/filebeat/input/httpjson/config.go +++ b/x-pack/filebeat/input/httpjson/config.go @@ -14,7 +14,7 @@ import ( "time" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) // config contains information about httpjson configuration @@ -35,9 +35,10 @@ type config struct { RetryMax int `config:"retry.max_attempts"` RetryWaitMin time.Duration `config:"retry.wait_min"` RetryWaitMax time.Duration `config:"retry.wait_max"` - TLS *tlscommon.Config `config:"ssl"` URL *urlConfig `config:"url" validate:"required"` DateCursor *dateCursorConfig `config:"date_cursor"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } // Pagination contains information about httpjson pagination settings diff --git a/x-pack/filebeat/input/httpjson/input.go b/x-pack/filebeat/input/httpjson/input.go index ca2e43483d1..0411fa65d41 100644 --- a/x-pack/filebeat/input/httpjson/input.go +++ b/x-pack/filebeat/input/httpjson/input.go @@ -20,7 +20,7 @@ import ( stateless "github.com/elastic/beats/v7/filebeat/input/v2/input-stateless" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/useragent" "github.com/elastic/beats/v7/libbeat/feature" "github.com/elastic/beats/v7/libbeat/logp" @@ -85,19 +85,6 @@ func Plugin(log *logp.Logger, store cursor.StateStore) inputv2.Plugin { } } -func newTLSConfig(config config) (*tlscommon.TLSConfig, error) { - if err := config.Validate(); err != nil { - return nil, err - } - - tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS) - if err != nil { - return nil, err - } - - return tlsConfig, nil -} - func test(url *url.URL) error { port := func() string { if url.Port() != "" { @@ -121,7 +108,6 @@ func test(url *url.URL) error { func run( ctx inputv2.Context, config config, - tlsConfig *tlscommon.TLSConfig, publisher cursor.Publisher, cursor *cursor.Cursor, ) error { @@ -129,7 +115,7 @@ func run( stdCtx := ctxtool.FromCanceller(ctx.Cancelation) - httpClient, err := newHTTPClient(stdCtx, config, tlsConfig) + httpClient, err := newHTTPClient(stdCtx, config) if err != nil { return err } @@ -169,19 +155,21 @@ func run( return nil } -func newHTTPClient(ctx context.Context, config config, tlsConfig *tlscommon.TLSConfig) (*http.Client, error) { +func newHTTPClient(ctx context.Context, config config) (*http.Client, error) { + config.Transport.Timeout = config.HTTPClientTimeout + + httpClient, err := + config.Transport.Client( + httpcommon.WithAPMHTTPInstrumentation(), + httpcommon.WithKeepaliveSettings{Disable: true}, + ) + if err != nil { + return nil, err + } + // Make retryable HTTP client client := &retryablehttp.Client{ - HTTPClient: &http.Client{ - Transport: &http.Transport{ - DialContext: (&net.Dialer{ - Timeout: config.HTTPClientTimeout, - }).DialContext, - TLSClientConfig: tlsConfig.ToConfig(), - DisableKeepAlives: true, - }, - Timeout: config.HTTPClientTimeout, - }, + HTTPClient: httpClient, Logger: newRetryLogger(), RetryWaitMin: config.RetryWaitMin, RetryWaitMax: config.RetryWaitMax, diff --git a/x-pack/filebeat/input/httpjson/input_cursor.go b/x-pack/filebeat/input/httpjson/input_cursor.go index d18a91f3918..0ee0ac44e9a 100644 --- a/x-pack/filebeat/input/httpjson/input_cursor.go +++ b/x-pack/filebeat/input/httpjson/input_cursor.go @@ -8,7 +8,6 @@ import ( v2 "github.com/elastic/beats/v7/filebeat/input/v2" cursor "github.com/elastic/beats/v7/filebeat/input/v2/input-cursor" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type cursorInput struct{} @@ -18,8 +17,7 @@ func (cursorInput) Name() string { } type source struct { - config config - tlsConfig *tlscommon.TLSConfig + config config } func (src source) Name() string { @@ -31,23 +29,15 @@ func cursorConfigure(cfg *common.Config) ([]cursor.Source, cursor.Input, error) if err := cfg.Unpack(&conf); err != nil { return nil, nil, err } - return newCursorInput(conf) + + sources, inp := newCursorInput(conf) + return sources, inp, nil } -func newCursorInput(config config) ([]cursor.Source, cursor.Input, error) { - tlsConfig, err := newTLSConfig(config) - if err != nil { - return nil, nil, err - } +func newCursorInput(config config) ([]cursor.Source, cursor.Input) { // we only allow one url per config, if we wanted to allow more than one // each source should hold only one url - return []cursor.Source{ - &source{config: config, - tlsConfig: tlsConfig, - }, - }, - &cursorInput{}, - nil + return []cursor.Source{&source{config: config}}, &cursorInput{} } func (in *cursorInput) Test(src cursor.Source, _ v2.TestContext) error { @@ -63,5 +53,5 @@ func (in *cursorInput) Run( publisher cursor.Publisher, ) error { s := src.(*source) - return run(ctx, s.config, s.tlsConfig, publisher, &cursor) + return run(ctx, s.config, publisher, &cursor) } diff --git a/x-pack/filebeat/input/httpjson/input_stateless.go b/x-pack/filebeat/input/httpjson/input_stateless.go index c7ebf6c3d4c..fbf28b2d20c 100644 --- a/x-pack/filebeat/input/httpjson/input_stateless.go +++ b/x-pack/filebeat/input/httpjson/input_stateless.go @@ -9,12 +9,10 @@ import ( stateless "github.com/elastic/beats/v7/filebeat/input/v2/input-stateless" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type statelessInput struct { - config config - tlsConfig *tlscommon.TLSConfig + config config } func (statelessInput) Name() string { @@ -26,15 +24,11 @@ func statelessConfigure(cfg *common.Config) (stateless.Input, error) { if err := cfg.Unpack(&conf); err != nil { return nil, err } - return newStatelessInput(conf) + return newStatelessInput(conf), nil } -func newStatelessInput(config config) (*statelessInput, error) { - tlsConfig, err := newTLSConfig(config) - if err != nil { - return nil, err - } - return &statelessInput{config: config, tlsConfig: tlsConfig}, nil +func newStatelessInput(config config) *statelessInput { + return &statelessInput{config: config} } func (in *statelessInput) Test(v2.TestContext) error { @@ -54,5 +48,5 @@ func (pub statelessPublisher) Publish(event beat.Event, _ interface{}) error { // It will return on context cancellation, any other error will be retried. func (in *statelessInput) Run(ctx v2.Context, publisher stateless.Publisher) error { pub := statelessPublisher{wrapped: publisher} - return run(ctx, in.config, in.tlsConfig, pub, nil) + return run(ctx, in.config, pub, nil) } diff --git a/x-pack/filebeat/input/httpjson/input_test.go b/x-pack/filebeat/input/httpjson/input_test.go index 242811d2795..9630d0c81fb 100644 --- a/x-pack/filebeat/input/httpjson/input_test.go +++ b/x-pack/filebeat/input/httpjson/input_test.go @@ -227,9 +227,7 @@ func TestStatelessHTTPJSONInput(t *testing.T) { conf := newDefaultConfig() assert.NoError(t, cfg.Unpack(&conf)) - input, err := newStatelessInput(conf) - - assert.NoError(t, err) + input := newStatelessInput(conf) assert.Equal(t, "httpjson-stateless", input.Name()) assert.NoError(t, input.Test(v2.TestContext{})) diff --git a/x-pack/filebeat/input/httpjson/internal/v2/config.go b/x-pack/filebeat/input/httpjson/internal/v2/config.go index 2795aad5de9..aa2be1c0113 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/config.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/config.go @@ -7,6 +7,8 @@ package v2 import ( "errors" "time" + + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) type config struct { @@ -37,16 +39,17 @@ func (c config) Validate() error { } func defaultConfig() config { - timeout := 30 * time.Second maxAttempts := 5 waitMin := time.Second waitMax := time.Minute + transport := httpcommon.DefaultHTTPTransportSettings() + transport.Timeout = 30 * time.Second + return config{ Interval: time.Minute, Auth: &authConfig{}, Request: &requestConfig{ - Timeout: &timeout, - Method: "GET", + Method: "GET", Retry: retryConfig{ MaxAttempts: &maxAttempts, WaitMin: &waitMin, @@ -54,6 +57,7 @@ func defaultConfig() config { }, RedirectForwardHeaders: false, RedirectMaxRedirects: 10, + Transport: transport, }, Response: &responseConfig{}, } diff --git a/x-pack/filebeat/input/httpjson/internal/v2/config_request.go b/x-pack/filebeat/input/httpjson/internal/v2/config_request.go index f64a03d9899..a8bc7204a23 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/config_request.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/config_request.go @@ -12,7 +12,7 @@ import ( "time" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) type retryConfig struct { @@ -76,26 +76,18 @@ func (u *urlConfig) Unpack(in string) error { } type requestConfig struct { - URL *urlConfig `config:"url" validate:"required"` - Method string `config:"method" validate:"required"` - Body *common.MapStr `config:"body"` - EncodeAs string `config:"encode_as"` - Timeout *time.Duration `config:"timeout"` - SSL *tlscommon.Config `config:"ssl"` - Retry retryConfig `config:"retry"` - RedirectForwardHeaders bool `config:"redirect.forward_headers"` - RedirectHeadersBanList []string `config:"redirect.headers_ban_list"` - RedirectMaxRedirects int `config:"redirect.max_redirects"` - RateLimit *rateLimitConfig `config:"rate_limit"` - Transforms transformsConfig `config:"transforms"` - ProxyURL *urlConfig `config:"proxy_url"` -} - -func (c requestConfig) getTimeout() time.Duration { - if c.Timeout == nil { - return 0 - } - return *c.Timeout + URL *urlConfig `config:"url" validate:"required"` + Method string `config:"method" validate:"required"` + Body *common.MapStr `config:"body"` + EncodeAs string `config:"encode_as"` + Retry retryConfig `config:"retry"` + RedirectForwardHeaders bool `config:"redirect.forward_headers"` + RedirectHeadersBanList []string `config:"redirect.headers_ban_list"` + RedirectMaxRedirects int `config:"redirect.max_redirects"` + RateLimit *rateLimitConfig `config:"rate_limit"` + Transforms transformsConfig `config:"transforms"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } func (c *requestConfig) Validate() error { @@ -110,10 +102,6 @@ func (c *requestConfig) Validate() error { return fmt.Errorf("unsupported method %q", c.Method) } - if c.Timeout != nil && *c.Timeout <= 0 { - return errors.New("timeout must be greater than 0") - } - if _, err := newBasicTransformsFromConfig(c.Transforms, requestNamespace, nil); err != nil { return err } diff --git a/x-pack/filebeat/input/httpjson/internal/v2/input.go b/x-pack/filebeat/input/httpjson/internal/v2/input.go index e8c8fe51082..9cbd017c6ba 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/input.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/input.go @@ -20,7 +20,7 @@ import ( inputcursor "github.com/elastic/beats/v7/filebeat/input/v2/input-cursor" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" "github.com/elastic/beats/v7/libbeat/common/useragent" "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/go-concert/ctxtool" @@ -64,19 +64,6 @@ func (log *retryLogger) Warn(format string, args ...interface{}) { log.log.Warnf(format, args...) } -func newTLSConfig(config config) (*tlscommon.TLSConfig, error) { - if err := config.Validate(); err != nil { - return nil, err - } - - tlsConfig, err := tlscommon.LoadTLSConfig(config.Request.SSL) - if err != nil { - return nil, err - } - - return tlsConfig, nil -} - func test(url *url.URL) error { port := func() string { if url.Port() != "" { @@ -100,7 +87,6 @@ func test(url *url.URL) error { func run( ctx v2.Context, config config, - tlsConfig *tlscommon.TLSConfig, publisher inputcursor.Publisher, cursor *inputcursor.Cursor, ) error { @@ -108,7 +94,7 @@ func run( stdCtx := ctxtool.FromCanceller(ctx.Cancelation) - httpClient, err := newHTTPClient(stdCtx, config, tlsConfig, log) + httpClient, err := newHTTPClient(stdCtx, config, log) if err != nil { return err } @@ -147,27 +133,20 @@ func run( return nil } -func newHTTPClient(ctx context.Context, config config, tlsConfig *tlscommon.TLSConfig, log *logp.Logger) (*httpClient, error) { - timeout := config.Request.getTimeout() - proxy_url := config.Request.ProxyURL - +func newHTTPClient(ctx context.Context, config config, log *logp.Logger) (*httpClient, error) { // Make retryable HTTP client - transport := &http.Transport{ - DialContext: (&net.Dialer{ - Timeout: timeout, - }).DialContext, - TLSClientConfig: tlsConfig.ToConfig(), - DisableKeepAlives: true, - } - if proxy_url != nil && proxy_url.URL != nil { - transport.Proxy = http.ProxyURL(proxy_url.URL) + netHTTPClient, err := config.Request.Transport.Client( + httpcommon.WithAPMHTTPInstrumentation(), + httpcommon.WithKeepaliveSettings{Disable: true}, + ) + if err != nil { + return nil, err } + + netHTTPClient.CheckRedirect = checkRedirect(config.Request, log) + client := &retryablehttp.Client{ - HTTPClient: &http.Client{ - Transport: transport, - Timeout: timeout, - CheckRedirect: checkRedirect(config.Request, log), - }, + HTTPClient: netHTTPClient, Logger: newRetryLogger(log), RetryWaitMin: config.Request.Retry.getWaitMin(), RetryWaitMax: config.Request.Retry.getWaitMax(), diff --git a/x-pack/filebeat/input/httpjson/internal/v2/input_cursor.go b/x-pack/filebeat/input/httpjson/internal/v2/input_cursor.go index 537e67762df..db454f6776d 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/input_cursor.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/input_cursor.go @@ -8,7 +8,6 @@ import ( v2 "github.com/elastic/beats/v7/filebeat/input/v2" inputcursor "github.com/elastic/beats/v7/filebeat/input/v2/input-cursor" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type cursorInput struct{} @@ -18,8 +17,7 @@ func (cursorInput) Name() string { } type source struct { - config config - tlsConfig *tlscommon.TLSConfig + config config } func (src source) Name() string { @@ -31,23 +29,14 @@ func cursorConfigure(cfg *common.Config) ([]inputcursor.Source, inputcursor.Inpu if err := cfg.Unpack(&conf); err != nil { return nil, nil, err } - return newCursorInput(conf) + sources, inp := newCursorInput(conf) + return sources, inp, nil } -func newCursorInput(config config) ([]inputcursor.Source, inputcursor.Input, error) { - tlsConfig, err := newTLSConfig(config) - if err != nil { - return nil, nil, err - } +func newCursorInput(config config) ([]inputcursor.Source, inputcursor.Input) { // we only allow one url per config, if we wanted to allow more than one // each source should hold only one url - return []inputcursor.Source{ - &source{config: config, - tlsConfig: tlsConfig, - }, - }, - &cursorInput{}, - nil + return []inputcursor.Source{&source{config: config}}, &cursorInput{} } func (in *cursorInput) Test(src inputcursor.Source, _ v2.TestContext) error { @@ -63,5 +52,5 @@ func (in *cursorInput) Run( publisher inputcursor.Publisher, ) error { s := src.(*source) - return run(ctx, s.config, s.tlsConfig, publisher, &cursor) + return run(ctx, s.config, publisher, &cursor) } diff --git a/x-pack/filebeat/input/httpjson/internal/v2/input_stateless.go b/x-pack/filebeat/input/httpjson/internal/v2/input_stateless.go index 92a1b8ae2dd..4a871d62d77 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/input_stateless.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/input_stateless.go @@ -9,12 +9,10 @@ import ( stateless "github.com/elastic/beats/v7/filebeat/input/v2/input-stateless" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) type statelessInput struct { - config config - tlsConfig *tlscommon.TLSConfig + config config } func (statelessInput) Name() string { @@ -30,11 +28,7 @@ func statelessConfigure(cfg *common.Config) (stateless.Input, error) { } func newStatelessInput(config config) (*statelessInput, error) { - tlsConfig, err := newTLSConfig(config) - if err != nil { - return nil, err - } - return &statelessInput{config: config, tlsConfig: tlsConfig}, nil + return &statelessInput{config: config}, nil } func (in *statelessInput) Test(v2.TestContext) error { @@ -54,5 +48,5 @@ func (pub statelessPublisher) Publish(event beat.Event, _ interface{}) error { // It will return on context cancellation, any other error will be retried. func (in *statelessInput) Run(ctx v2.Context, publisher stateless.Publisher) error { pub := statelessPublisher{wrapped: publisher} - return run(ctx, in.config, in.tlsConfig, pub, nil) + return run(ctx, in.config, pub, nil) } diff --git a/x-pack/filebeat/input/httpjson/internal/v2/request_test.go b/x-pack/filebeat/input/httpjson/internal/v2/request_test.go index f6564af3ed0..6e35d5cc45f 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/request_test.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/request_test.go @@ -58,7 +58,7 @@ func TestCtxAfterDoRequest(t *testing.T) { log := logp.NewLogger("") ctx := context.Background() - client, err := newHTTPClient(ctx, config, nil, log) + client, err := newHTTPClient(ctx, config, log) assert.NoError(t, err) requestFactory := newRequestFactory(config.Request, nil, log) diff --git a/x-pack/libbeat/common/cloudfoundry/config.go b/x-pack/libbeat/common/cloudfoundry/config.go index 2f15d0c7cf9..a78755062e4 100644 --- a/x-pack/libbeat/common/cloudfoundry/config.go +++ b/x-pack/libbeat/common/cloudfoundry/config.go @@ -5,12 +5,11 @@ package cloudfoundry import ( - "crypto/tls" "fmt" "strings" "time" - "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" ) const ( @@ -26,9 +25,6 @@ type Config struct { ClientID string `config:"client_id" validate:"required"` ClientSecret string `config:"client_secret" validate:"required"` - // TLS configuration for the client - TLS *tlscommon.Config `config:"ssl"` - // Override URLs returned from the CF client APIAddress string `config:"api_address" validate:"required"` DopplerAddress string `config:"doppler_address"` @@ -44,6 +40,8 @@ type Config struct { // Time to wait before retrying to get application info in case of error. CacheRetryDelay time.Duration `config:"cache_retry_delay"` + + Transport httpcommon.HTTPTransportSettings `config:",inline"` } // InitDefaults initialize the defaults for the configuration. @@ -51,6 +49,8 @@ func (c *Config) InitDefaults() { c.CacheDuration = 120 * time.Second c.CacheRetryDelay = 20 * time.Second c.Version = ConsumerVersionV1 + + c.Transport = httpcommon.DefaultHTTPTransportSettings() } func (c *Config) Validate() error { @@ -61,15 +61,6 @@ func (c *Config) Validate() error { return nil } -// TLSConfig returns the TLS configuration. -func (c *Config) TLSConfig() (*tls.Config, error) { - tls, err := tlscommon.LoadTLSConfig(c.TLS) - if err != nil { - return nil, err - } - return tls.ToConfig(), nil -} - func anyOf(elems []string, s string) bool { for _, elem := range elems { if s == elem { diff --git a/x-pack/libbeat/common/cloudfoundry/hub.go b/x-pack/libbeat/common/cloudfoundry/hub.go index 4cf9757c278..9bcf929ded2 100644 --- a/x-pack/libbeat/common/cloudfoundry/hub.go +++ b/x-pack/libbeat/common/cloudfoundry/hub.go @@ -11,6 +11,8 @@ import ( "github.com/cloudfoundry-community/go-cfclient" "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" ) @@ -151,23 +153,11 @@ func (h *Hub) doerFromClient(client *cfclient.Client) (*authTokenDoer, error) { // httpClient returns an HTTP client configured with the configuration TLS. func (h *Hub) httpClient() (*http.Client, bool, error) { - tls, err := h.cfg.TLSConfig() + httpClient, err := h.cfg.Transport.Client(httpcommon.WithAPMHTTPInstrumentation()) if err != nil { - return nil, true, err + return nil, false, err } - httpClient := cfclient.DefaultConfig().HttpClient - tp := defaultTransport() - tp.TLSClientConfig = tls - httpClient.Transport = tp - return httpClient, tls.InsecureSkipVerify, nil -} -// defaultTransport returns a new http.Transport for http.Client -func defaultTransport() *http.Transport { - defaultTransport := http.DefaultTransport.(*http.Transport) - return &http.Transport{ - Proxy: defaultTransport.Proxy, - TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, - ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, - } + tls, _ := tlscommon.LoadTLSConfig(h.cfg.Transport.TLS) + return httpClient, tls.ToConfig().InsecureSkipVerify, nil } diff --git a/x-pack/metricbeat/module/openmetrics/collector/_meta/data.json b/x-pack/metricbeat/module/openmetrics/collector/_meta/data.json index 88dba9c9659..5c3e9aec6ba 100644 --- a/x-pack/metricbeat/module/openmetrics/collector/_meta/data.json +++ b/x-pack/metricbeat/module/openmetrics/collector/_meta/data.json @@ -11,7 +11,7 @@ }, "openmetrics": { "labels": { - "device": "br-10229e3512d9", + "device": "br-3a285aa5e58c", "job": "openmetrics" }, "metrics": { diff --git a/x-pack/metricbeat/module/prometheus/collector/_meta/data.json b/x-pack/metricbeat/module/prometheus/collector/_meta/data.json index f0fed23d976..f6c2e256b75 100644 --- a/x-pack/metricbeat/module/prometheus/collector/_meta/data.json +++ b/x-pack/metricbeat/module/prometheus/collector/_meta/data.json @@ -1,5 +1,5 @@ { - "@timestamp": "2017-10-12T08:05:34.853Z", + "@timestamp": "2019-03-01T08:05:34.853Z", "event": { "dataset": "prometheus.collector", "duration": 115000, @@ -11,21 +11,15 @@ }, "prometheus": { "labels": { - "instance": "172.27.0.2:9090", - "interval": "15s", + "device": "br-210476dc4ef8", "job": "prometheus" }, - "prometheus_target_interval_length_seconds_count": { - "counter": 1, - "rate": 0 - }, - "prometheus_target_interval_length_seconds_sum": { - "counter": 15.000401344, - "rate": 0 + "node_network_carrier": { + "value": 0 } }, "service": { - "address": "172.27.0.2:9090", + "address": "127.0.0.1:55555", "type": "prometheus" } } \ No newline at end of file From e00802492637cc568425d9edf582c70a5428a3ef Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Tue, 29 Jun 2021 13:47:07 -0700 Subject: [PATCH 17/25] Refactor of system/memory metricset (#26334) * init commit * start on linux implementation * finish linux, start work on darwin * fix build platform issues * fix metrics on darwin * add openbsd * add freebsd * add windows, aix * fix aix build * finish memory * fix up opt changes * cleanup metricset code * fix up folder methods * fix calculations, Opt API, gomod * make notice * go mod tidy, mage fmt * fix up linux/memory * update fields * update system tests * fix system tests, again * fix extra print statements * fix if block in fillPercentages * vix Value API * fix up tests, opt --- NOTICE.txt | 424 +++++++++--------- go.mod | 2 +- libbeat/metric/system/memory/memory.go | 172 ------- libbeat/metric/system/memory/memory_test.go | 96 ---- libbeat/metric/system/process/process.go | 16 +- metricbeat/docs/fields.asciidoc | 12 + metricbeat/internal/metrics/memory/memory.go | 102 +++++ .../internal/metrics/memory/memory_aix.go | 75 ++++ .../internal/metrics/memory/memory_darwin.go | 133 ++++++ .../internal/metrics/memory/memory_freebsd.go | 90 ++++ .../internal/metrics/memory/memory_linux.go | 143 ++++++ .../internal/metrics/memory/memory_openbsd.go | 236 ++++++++++ .../internal/metrics/memory/memory_test.go | 102 +++++ .../internal/metrics/memory/memory_windows.go | 51 +++ metricbeat/internal/metrics/opt.go | 80 +++- .../module/linux/memory/_meta/data.json | 14 +- metricbeat/module/linux/memory/data.go | 163 ++++--- .../module/linux}/memory/doc.go | 0 metricbeat/module/linux/memory/memory.go | 9 +- metricbeat/module/linux/memory/memory_test.go | 2 +- metricbeat/module/system/fields.go | 2 +- .../module/system/memory/_meta/data.json | 45 +- .../module/system/memory/_meta/fields.yml | 6 + .../module/system/memory/helper_linux.go | 32 ++ .../module/system/memory/helper_other.go | 38 ++ metricbeat/module/system/memory/memory.go | 79 +--- .../module/system/memory/memory_test.go | 2 +- metricbeat/module/system/test_system.py | 13 +- 28 files changed, 1502 insertions(+), 637 deletions(-) delete mode 100644 libbeat/metric/system/memory/memory.go delete mode 100644 libbeat/metric/system/memory/memory_test.go create mode 100644 metricbeat/internal/metrics/memory/memory.go create mode 100644 metricbeat/internal/metrics/memory/memory_aix.go create mode 100644 metricbeat/internal/metrics/memory/memory_darwin.go create mode 100644 metricbeat/internal/metrics/memory/memory_freebsd.go create mode 100644 metricbeat/internal/metrics/memory/memory_linux.go create mode 100644 metricbeat/internal/metrics/memory/memory_openbsd.go create mode 100644 metricbeat/internal/metrics/memory/memory_test.go create mode 100644 metricbeat/internal/metrics/memory/memory_windows.go rename {libbeat/metric/system => metricbeat/module/linux}/memory/doc.go (100%) create mode 100644 metricbeat/module/system/memory/helper_linux.go create mode 100644 metricbeat/module/system/memory/helper_other.go diff --git a/NOTICE.txt b/NOTICE.txt index 35e8d9ec736..9f3cb22b2ee 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -8539,6 +8539,218 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-ucfg@v0.8.3/ limitations under the License. +-------------------------------------------------------------------------------- +Dependency : github.com/elastic/go-windows +Version: v1.0.1 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-windows@v1.0.1/LICENSE.txt: + + + 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/gosigar Version: v0.14.1 @@ -27056,218 +27268,6 @@ 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/elastic/go-windows -Version: v1.0.1 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-windows@v1.0.1/LICENSE.txt: - - - 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/elazarl/goproxy Version: v0.0.0-20180725130230-947c36da3153 diff --git a/go.mod b/go.mod index 5b989515af4..f453a519371 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/elastic/go-sysinfo v1.7.0 github.com/elastic/go-txfile v0.0.7 github.com/elastic/go-ucfg v0.8.3 - github.com/elastic/go-windows v1.0.1 // indirect + github.com/elastic/go-windows v1.0.1 github.com/elastic/gosigar v0.14.1 github.com/fatih/color v1.9.0 github.com/fsnotify/fsevents v0.1.1 diff --git a/libbeat/metric/system/memory/memory.go b/libbeat/metric/system/memory/memory.go deleted file mode 100644 index 72e351db384..00000000000 --- a/libbeat/metric/system/memory/memory.go +++ /dev/null @@ -1,172 +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. - -// +build darwin freebsd linux openbsd windows - -package memory - -import ( - "github.com/pkg/errors" - - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/logp" - sysinfo "github.com/elastic/go-sysinfo" - sysinfotypes "github.com/elastic/go-sysinfo/types" - sigar "github.com/elastic/gosigar" -) - -// MemStat includes the memory usage statistics and ratios of usage and total memory usage -type MemStat struct { - sigar.Mem - UsedPercent float64 `json:"used_p"` - ActualUsedPercent float64 `json:"actual_used_p"` -} - -// Get returns the memory stats of the host -func Get() (*MemStat, error) { - mem := sigar.Mem{} - err := mem.Get() - if err != nil { - return nil, err - } - - return &MemStat{Mem: mem}, nil -} - -// AddMemPercentage calculates the ratio of used and total size of memory -func AddMemPercentage(m *MemStat) { - if m.Mem.Total == 0 { - return - } - - perc := float64(m.Mem.Used) / float64(m.Mem.Total) - m.UsedPercent = common.Round(perc, common.DefaultDecimalPlacesCount) - - actualPerc := float64(m.Mem.ActualUsed) / float64(m.Mem.Total) - m.ActualUsedPercent = common.Round(actualPerc, common.DefaultDecimalPlacesCount) -} - -// SwapStat includes the current swap usage and the ratio of used and total swap size -type SwapStat struct { - sigar.Swap - UsedPercent float64 `json:"used_p"` -} - -// GetSwap returns the swap usage of the host -func GetSwap() (*SwapStat, error) { - swap := sigar.Swap{} - err := swap.Get() - if err != nil { - return nil, err - } - - // This shouldn't happen, but it has been reported to happen and - // this can provoke too big values for used swap. - // Workaround this by assuming that all swap is free in that case. - if swap.Free > swap.Total || swap.Used > swap.Total { - logger := logp.NewLogger("memory") - logger.Debugf("memory", - "Unexpected values for swap memory - total: %v free: %v used: %v. Setting swap used to 0.", - swap.Total, swap.Free, swap.Used) - swap.Free = swap.Total - swap.Used = 0 - } - - return &SwapStat{Swap: swap}, nil -} - -// GetMemoryEvent returns the event created from memory statistics -func GetMemoryEvent(memStat *MemStat) common.MapStr { - return common.MapStr{ - "total": memStat.Total, - "used": memStat.Used, - "free": memStat.Free, - "actual_used": memStat.ActualUsed, - "actual_free": memStat.ActualFree, - "used_p": memStat.UsedPercent, - "actual_used_p": memStat.ActualUsedPercent, - } -} - -// GetSwapEvent returns the event created from swap usage -func GetSwapEvent(swapStat *SwapStat) common.MapStr { - return common.MapStr{ - "total": swapStat.Total, - "used": swapStat.Used, - "free": swapStat.Free, - "used_p": swapStat.UsedPercent, - } -} - -// AddSwapPercentage calculates the ratio of used and total swap size -func AddSwapPercentage(s *SwapStat) { - if s.Swap.Total == 0 { - return - } - - perc := float64(s.Swap.Used) / float64(s.Swap.Total) - s.UsedPercent = common.Round(perc, common.DefaultDecimalPlacesCount) -} - -// HugeTLBPagesStat includes metrics about huge pages usage -type HugeTLBPagesStat struct { - sigar.HugeTLBPages - UsedPercent float64 `json:"used_p"` -} - -// GetHugeTLBPages returns huge pages usage metrics -func GetHugeTLBPages() (*HugeTLBPagesStat, error) { - pages := sigar.HugeTLBPages{} - err := pages.Get() - - if err == nil { - return &HugeTLBPagesStat{HugeTLBPages: pages}, nil - } - - if sigar.IsNotImplemented(err) { - return nil, nil - } - - return nil, err -} - -// AddHugeTLBPagesPercentage calculates ratio of used huge pages -func AddHugeTLBPagesPercentage(s *HugeTLBPagesStat) { - if s.Total == 0 { - return - } - - perc := float64(s.Total-s.Free+s.Reserved) / float64(s.Total) - s.UsedPercent = common.Round(perc, common.DefaultDecimalPlacesCount) -} - -// GetVMStat gets linux vmstat metrics -func GetVMStat() (*sysinfotypes.VMStatInfo, error) { - h, err := sysinfo.Host() - if err != nil { - return nil, errors.Wrap(err, "failed to read self process information") - } - if vmstatHandle, ok := h.(sysinfotypes.VMStat); ok { - info, err := vmstatHandle.VMStat() - if err != nil { - return nil, errors.Wrap(err, "error getting VMStat info") - } - return info, nil - } - return nil, nil - -} diff --git a/libbeat/metric/system/memory/memory_test.go b/libbeat/metric/system/memory/memory_test.go deleted file mode 100644 index e71e092de52..00000000000 --- a/libbeat/metric/system/memory/memory_test.go +++ /dev/null @@ -1,96 +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. - -// +build !integration -// +build darwin freebsd linux openbsd windows - -package memory - -import ( - "runtime" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/elastic/gosigar" -) - -func TestGetMemory(t *testing.T) { - mem, err := Get() - - assert.NotNil(t, mem) - assert.NoError(t, err) - - assert.True(t, (mem.Total > 0)) - assert.True(t, (mem.Used > 0)) - assert.True(t, (mem.Free >= 0)) - assert.True(t, (mem.ActualFree >= 0)) - assert.True(t, (mem.ActualUsed > 0)) -} - -func TestGetSwap(t *testing.T) { - if runtime.GOOS == "windows" { - return //no load data on windows - } - - swap, err := GetSwap() - - assert.NotNil(t, swap) - assert.NoError(t, err) - - assert.True(t, (swap.Total >= 0)) - assert.True(t, (swap.Used >= 0)) - assert.True(t, (swap.Free >= 0)) -} - -func TestMemPercentage(t *testing.T) { - m := MemStat{ - Mem: gosigar.Mem{ - Total: 7, - Used: 5, - Free: 2, - }, - } - AddMemPercentage(&m) - assert.Equal(t, m.UsedPercent, 0.7143) - - m = MemStat{ - Mem: gosigar.Mem{Total: 0}, - } - AddMemPercentage(&m) - assert.Equal(t, m.UsedPercent, 0.0) -} - -func TestActualMemPercentage(t *testing.T) { - m := MemStat{ - Mem: gosigar.Mem{ - Total: 7, - ActualUsed: 5, - ActualFree: 2, - }, - } - AddMemPercentage(&m) - assert.Equal(t, m.ActualUsedPercent, 0.7143) - - m = MemStat{ - Mem: gosigar.Mem{ - Total: 0, - }, - } - AddMemPercentage(&m) - assert.Equal(t, m.ActualUsedPercent, 0.0) -} diff --git a/libbeat/metric/system/process/process.go b/libbeat/metric/system/process/process.go index 9e7eb5ac932..3a301000a9a 100644 --- a/libbeat/metric/system/process/process.go +++ b/libbeat/metric/system/process/process.go @@ -32,7 +32,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/match" "github.com/elastic/beats/v7/libbeat/logp" - "github.com/elastic/beats/v7/libbeat/metric/system/memory" + sysinfo "github.com/elastic/go-sysinfo" sigar "github.com/elastic/gosigar" "github.com/elastic/gosigar/cgroup" ) @@ -288,12 +288,20 @@ func GetOwnResourceUsageTimeInMillis() (int64, int64, error) { func (procStats *Stats) getProcessEvent(process *Process) common.MapStr { + // This is a holdover until we migrate this library to metricbeat/internal + // At which point we'll use the memory code there. var totalPhyMem uint64 - baseMem, err := memory.Get() + host, err := sysinfo.Host() if err != nil { - procStats.logger.Warnf("Getting memory details: %v", err) + procStats.logger.Warnf("Getting host details: %v", err) } else { - totalPhyMem = baseMem.Mem.Total + memStats, err := host.Memory() + if err != nil { + procStats.logger.Warnf("Getting memory details: %v", err) + } else { + totalPhyMem = memStats.Total + } + } proc := common.MapStr{ diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 6d0d48c3dca..10db058421a 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -51614,6 +51614,18 @@ format: bytes The total amount of free memory in bytes. This value does not include memory consumed by system caches and buffers (see system.memory.actual.free). +type: long + +format: bytes + +-- + +*`system.memory.cached`*:: ++ +-- +Total Cached memory on system. + + type: long format: bytes diff --git a/metricbeat/internal/metrics/memory/memory.go b/metricbeat/internal/metrics/memory/memory.go new file mode 100644 index 00000000000..73597e8974f --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory.go @@ -0,0 +1,102 @@ +// 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 memory + +import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +// Memory holds os-specifc memory usage data +// The vast majority of these values are cross-platform +// However, we're wrapping all them for the sake of safety, and for the more variable swap metrics +type Memory struct { + Total metrics.OptUint `struct:"total,omitempty"` + Used UsedMemStats `struct:"used,omitempty"` + + Free metrics.OptUint `struct:"free,omitempty"` + Cached metrics.OptUint `struct:"cached,omitempty"` + // "Actual" values are, technically, a linux-only concept + // For better or worse we've expanded it to include "derived" + // Memory values on other platforms, which we should + // probably keep for the sake of backwards compatibility + // However, because the derived value varies from platform to platform, + // We may want to more precisely document what these mean. + Actual ActualMemoryMetrics `struct:"actual,omitempty"` + + // Swap metrics + Swap SwapMetrics `struct:"swap,omitempty"` +} + +// UsedMemStats wraps used.* memory metrics +type UsedMemStats struct { + Pct metrics.OptFloat `struct:"pct,omitempty"` + Bytes metrics.OptUint `struct:"bytes,omitempty"` +} + +// ActualMemoryMetrics wraps the actual.* memory metrics +type ActualMemoryMetrics struct { + Free metrics.OptUint `struct:"free,omitempty"` + Used UsedMemStats `struct:"used,omitempty"` +} + +// SwapMetrics wraps swap.* memory metrics +type SwapMetrics struct { + Total metrics.OptUint `struct:"total,omitempty"` + Used UsedMemStats `struct:"used,omitempty"` + Free metrics.OptUint `struct:"free,omitempty"` +} + +// Get returns platform-independent memory metrics. +func Get(procfs string) (Memory, error) { + base, err := get(procfs) + if err != nil { + return Memory{}, errors.Wrap(err, "error getting system memory info") + } + base.fillPercentages() + return base, nil +} + +// IsZero implements the zeroer interface for structform's folders +func (used UsedMemStats) IsZero() bool { + return used.Pct.IsZero() && used.Bytes.IsZero() +} + +// IsZero implements the zeroer interface for structform's folders +func (swap SwapMetrics) IsZero() bool { + return swap.Free.IsZero() && swap.Used.IsZero() && swap.Total.IsZero() +} + +func (base *Memory) fillPercentages() { + // Add percentages + // In theory, `Used` and `Total` are available everywhere, so assume values are good. + if base.Total.Exists() && base.Total.ValueOr(0) != 0 { + percUsed := float64(base.Used.Bytes.ValueOr(0)) / float64(base.Total.ValueOr(1)) + base.Used.Pct = metrics.OptFloatWith(common.Round(percUsed, common.DefaultDecimalPlacesCount)) + + actualPercUsed := float64(base.Actual.Used.Bytes.ValueOr(0)) / float64(base.Total.ValueOr(0)) + base.Actual.Used.Pct = metrics.OptFloatWith(common.Round(actualPercUsed, common.DefaultDecimalPlacesCount)) + } + + if base.Swap.Total.ValueOr(0) != 0 && base.Swap.Used.Bytes.Exists() { + perc := float64(base.Swap.Used.Bytes.ValueOr(0)) / float64(base.Swap.Total.ValueOr(0)) + base.Swap.Used.Pct = metrics.OptFloatWith(common.Round(perc, common.DefaultDecimalPlacesCount)) + } +} diff --git a/metricbeat/internal/metrics/memory/memory_aix.go b/metricbeat/internal/metrics/memory/memory_aix.go new file mode 100644 index 00000000000..e936c518479 --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_aix.go @@ -0,0 +1,75 @@ +// 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 memory + +/* +#cgo LDFLAGS: -L/usr/lib -lperfstat + +#include +#include +#include +#include +#include +#include +#include +#include + +*/ +import "C" + +import ( + "fmt" + "os" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +var system struct { + ticks uint64 + btime uint64 + pagesize uint64 +} + +func init() { + // sysconf(_SC_CLK_TCK) returns the number of ticks by second. + system.ticks = uint64(C.sysconf(C._SC_CLK_TCK)) + system.pagesize = uint64(os.Getpagesize()) +} + +func get(_ string) (Memory, error) { + memData := Memory{} + meminfo := C.perfstat_memory_total_t{} + _, err := C.perfstat_memory_total(nil, &meminfo, C.sizeof_perfstat_memory_total_t, 1) + if err != nil { + return memData, fmt.Errorf("perfstat_memory_total: %s", err) + } + + totalMem := uint64(meminfo.real_total) * system.pagesize + freeMem := uint64(meminfo.real_free) * system.pagesize + + memData.Total = metrics.OptUintWith(totalMem) + memData.Free = metrics.OptUintWith(freeMem) + + kern := uint64(meminfo.numperm) * system.pagesize // number of pages in file cache + + memData.Used.Bytes = metrics.OptUintWith(totalMem - freeMem) + memData.Actual.Free = metrics.OptUintWith(freeMem + kern) + memData.Actual.Used.Bytes = metrics.OptUintWith(memData.Used.Bytes.ValueOr(0) - kern) + + return memData, nil +} diff --git a/metricbeat/internal/metrics/memory/memory_darwin.go b/metricbeat/internal/metrics/memory/memory_darwin.go new file mode 100644 index 00000000000..7f9d08e0a8c --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_darwin.go @@ -0,0 +1,133 @@ +// 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 memory + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +import ( + "bytes" + "encoding/binary" + "fmt" + "syscall" + "unsafe" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +type xswUsage struct { + Total, Avail, Used uint64 +} + +// get is the darwin implementation for fetching Memory data +func get(_ string) (Memory, error) { + var vmstat C.vm_statistics_data_t + + mem := Memory{} + + var total uint64 + + if err := sysctlbyname("hw.memsize", &total); err != nil { + return Memory{}, errors.Wrap(err, "error getting memsize") + } + mem.Total = metrics.OptUintWith(total) + + if err := vmInfo(&vmstat); err != nil { + return Memory{}, errors.Wrap(err, "error getting VM info") + } + + kern := uint64(vmstat.inactive_count) << 12 + free := uint64(vmstat.free_count) << 12 + + mem.Free = metrics.OptUintWith(free) + mem.Used.Bytes = metrics.OptUintWith(total - free) + + mem.Actual.Free = metrics.OptUintWith(free + kern) + mem.Actual.Used.Bytes = metrics.OptUintWith((total - free) - kern) + + var err error + mem.Swap, err = getSwap() + if err != nil { + return mem, errors.Wrap(err, "error getting swap memory") + } + + return mem, nil +} + +// Get fetches swap data +func getSwap() (SwapMetrics, error) { + swUsage := xswUsage{} + + swap := SwapMetrics{} + if err := sysctlbyname("vm.swapusage", &swUsage); err != nil { + return swap, errors.Wrap(err, "error getting swap usage") + } + + swap.Total = metrics.OptUintWith(swUsage.Total) + swap.Used.Bytes = metrics.OptUintWith(swUsage.Used) + swap.Free = metrics.OptUintWith(swUsage.Avail) + + return swap, nil +} + +// generic Sysctl buffer unmarshalling +func sysctlbyname(name string, data interface{}) (err error) { + val, err := syscall.Sysctl(name) + if err != nil { + return err + } + + buf := []byte(val) + + switch v := data.(type) { + case *uint64: + *v = *(*uint64)(unsafe.Pointer(&buf[0])) + return + } + + bbuf := bytes.NewBuffer([]byte(val)) + return binary.Read(bbuf, binary.LittleEndian, data) +} + +func vmInfo(vmstat *C.vm_statistics_data_t) error { + var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT + + status := C.host_statistics( + C.host_t(C.mach_host_self()), + C.HOST_VM_INFO, + C.host_info_t(unsafe.Pointer(vmstat)), + &count) + + if status != C.KERN_SUCCESS { + return fmt.Errorf("host_statistics=%d", status) + } + + return nil +} diff --git a/metricbeat/internal/metrics/memory/memory_freebsd.go b/metricbeat/internal/metrics/memory/memory_freebsd.go new file mode 100644 index 00000000000..13c1ebb0748 --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_freebsd.go @@ -0,0 +1,90 @@ +// 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 memory + +import ( + "unsafe" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +func get(_ string) (Memory, error) { + val := C.uint32_t(0) + sc := C.size_t(4) + + memData := Memory{} + + name := C.CString("vm.stats.vm.v_page_count") + _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return memData, errors.Errorf("error in vm.stats.vm.v_page_count") + } + pagecount := uint64(val) + + name = C.CString("vm.stats.vm.v_page_size") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return memData, errors.Errorf("error in vm.stats.vm.v_page_size") + } + pagesize := uint64(val) + + name = C.CString("vm.stats.vm.v_free_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return memData, errors.Errorf("error in vm.stats.vm.v_free_count") + } + + memFree := uint64(val) * pagesize + memData.Free = metrics.OptUintWith(memFree) + + name = C.CString("vm.stats.vm.v_inactive_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return memData, errors.Errorf("error in vm.stats.vm.v_inactive_count") + } + kern := uint64(val) + + memTotal := uint64(pagecount * pagesize) + + memData.Total = metrics.OptUintWith(memTotal) + + memData.Used.Bytes = metrics.OptUintWith(memTotal - memFree) + memData.Actual.Free = metrics.OptUintWith(memFree + (kern * pagesize)) + memData.Actual.Used.Bytes = metrics.OptUintWith((memTotal - memFree) - (kern * pagesize)) + + return memData, nil +} diff --git a/metricbeat/internal/metrics/memory/memory_linux.go b/metricbeat/internal/metrics/memory/memory_linux.go new file mode 100644 index 00000000000..dc563e1b47d --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_linux.go @@ -0,0 +1,143 @@ +// 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 memory + +import ( + "bufio" + "bytes" + "io" + "io/ioutil" + "path/filepath" + "strconv" + "strings" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +// get is the linux implementation for fetching Memory data +func get(rootfs string) (Memory, error) { + table, err := ParseMeminfo(rootfs) + if err != nil { + return Memory{}, errors.Wrap(err, "error fetching meminfo") + } + + memData := Memory{} + + var free, cached uint64 + if total, ok := table["MemTotal"]; ok { + memData.Total = metrics.OptUintWith(total) + } + if free, ok := table["MemFree"]; ok { + memData.Free = metrics.OptUintWith(free) + } + if cached, ok := table["Cached"]; ok { + memData.Cached = metrics.OptUintWith(cached) + } + + // overlook parsing issues here + // On the very small chance some of these don't exist, + // It's not the end of the world + buffers, _ := table["Buffers"] + + if memAvail, ok := table["MemAvailable"]; ok { + // MemAvailable is in /proc/meminfo (kernel 3.14+) + memData.Actual.Free = metrics.OptUintWith(memAvail) + } else { + // in the future we may want to find another way to do this. + // "MemAvailable" and other more derivied metrics + // Are very relative, and can be unhelpful in cerntain workloads + // We may want to find a way to more clearly express to users + // where a certain value is coming from and what it represents + + // The use of `cached` here is particularly concerning, + // as under certain intense DB server workloads, the cached memory can be quite large + // and give the impression that we've passed memory usage watermark + memData.Actual.Free = metrics.OptUintWith(free + buffers + cached) + } + + memData.Used.Bytes = metrics.OptUintWith(memData.Total.ValueOr(0) - memData.Free.ValueOr(0)) + memData.Actual.Used.Bytes = metrics.OptUintWith(memData.Total.ValueOr(0) - memData.Actual.Free.ValueOr(0)) + + // Populate swap data + swapTotal, okST := table["SwapTotal"] + if okST { + memData.Swap.Total = metrics.OptUintWith(swapTotal) + } + swapFree, okSF := table["SwapFree"] + if okSF { + memData.Swap.Free = metrics.OptUintWith(swapFree) + } + + if okSF && okST { + memData.Swap.Used.Bytes = metrics.OptUintWith(swapTotal - swapFree) + } + + return memData, nil + +} + +// ParseMeminfo parses the contents of /proc/meminfo into a hashmap +func ParseMeminfo(rootfs string) (map[string]uint64, error) { + table := map[string]uint64{} + + meminfoPath := filepath.Join(rootfs, "/proc/meminfo") + err := readFile(meminfoPath, func(line string) bool { + fields := strings.Split(line, ":") + + if len(fields) != 2 { + return true // skip on errors + } + + valueUnit := strings.Fields(fields[1]) + value, err := strconv.ParseUint(valueUnit[0], 10, 64) + if err != nil { + return true // skip on errors + } + + if len(valueUnit) > 1 && valueUnit[1] == "kB" { + value *= 1024 + } + table[fields[0]] = value + + return true + }) + return table, err +} + +func readFile(file string, handler func(string) bool) error { + contents, err := ioutil.ReadFile(file) + if err != nil { + return errors.Wrapf(err, "error reading file %s", file) + } + + reader := bufio.NewReader(bytes.NewBuffer(contents)) + + for { + line, _, err := reader.ReadLine() + if err == io.EOF { + break + } + if !handler(string(line)) { + break + } + } + + return nil +} diff --git a/metricbeat/internal/metrics/memory/memory_openbsd.go b/metricbeat/internal/metrics/memory/memory_openbsd.go new file mode 100644 index 00000000000..51e6ef830e3 --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_openbsd.go @@ -0,0 +1,236 @@ +// 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 memory + +/* +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +import ( + "syscall" + "unsafe" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +// Uvmexp wraps memory data from sysctl +type Uvmexp struct { + pagesize uint32 + pagemask uint32 + pageshift uint32 + npages uint32 + free uint32 + active uint32 + inactive uint32 + paging uint32 + wired uint32 + zeropages uint32 + reserve_pagedaemon uint32 + reserve_kernel uint32 + anonpages uint32 + vnodepages uint32 + vtextpages uint32 + freemin uint32 + freetarg uint32 + inactarg uint32 + wiredmax uint32 + anonmin uint32 + vtextmin uint32 + vnodemin uint32 + anonminpct uint32 + vtextmi uint32 + npct uint32 + vnodeminpct uint32 + nswapdev uint32 + swpages uint32 + swpginuse uint32 + swpgonly uint32 + nswget uint32 + nanon uint32 + nanonneeded uint32 + nfreeanon uint32 + faults uint32 + traps uint32 + intrs uint32 + swtch uint32 + softs uint32 + syscalls uint32 + pageins uint32 + obsolete_swapins uint32 + obsolete_swapouts uint32 + pgswapin uint32 + pgswapout uint32 + forks uint32 + forks_ppwait uint32 + forks_sharevm uint32 + pga_zerohit uint32 + pga_zeromiss uint32 + zeroaborts uint32 + fltnoram uint32 + fltnoanon uint32 + fltpgwait uint32 + fltpgrele uint32 + fltrelck uint32 + fltrelckok uint32 + fltanget uint32 + fltanretry uint32 + fltamcopy uint32 + fltnamap uint32 + fltnomap uint32 + fltlget uint32 + fltget uint32 + flt_anon uint32 + flt_acow uint32 + flt_obj uint32 + flt_prcopy uint32 + flt_przero uint32 + pdwoke uint32 + pdrevs uint32 + pdswout uint32 + pdfreed uint32 + pdscans uint32 + pdanscan uint32 + pdobscan uint32 + pdreact uint32 + pdbusy uint32 + pdpageouts uint32 + pdpending uint32 + pddeact uint32 + pdreanon uint32 + pdrevnode uint32 + pdrevtext uint32 + fpswtch uint32 + kmapent uint32 +} + +// Bcachestats reports cache stats from sysctl +type Bcachestats struct { + numbufs uint64 + numbufpages uint64 + numdirtypages uint64 + numcleanpages uint64 + pendingwrites uint64 + pendingreads uint64 + numwrites uint64 + numreads uint64 + cachehits uint64 + busymapped uint64 + dmapages uint64 + highpages uint64 + delwribufs uint64 + kvaslots uint64 + kvaslots_avail uint64 +} + +// Swapent reports swap metrics from sysctl +type Swapent struct { + se_dev C.dev_t + se_flags int32 + se_nblks int32 + se_inuse int32 + se_priority int32 + sw_path []byte +} + +func get(_ string) (Memory, error) { + + memData := Memory{} + + n := uintptr(0) + var uvmexp Uvmexp + mib := [2]int32{C.CTL_VM, C.VM_UVMEXP} + n = uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return memData, errors.Errorf("Error in size VM_UVMEXP sysctl call, errno %d", errno) + } + + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return memData, errors.Errorf("Error in VM_UVMEXP sysctl call, errno %d", errno) + } + + var bcachestats Bcachestats + mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT} + n = uintptr(0) + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return memData, errors.Errorf("Error in size VFS_BCACHESTAT sysctl call, errno %d", errno) + } + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return memData, errors.Errorf("Error in VFS_BCACHESTAT sysctl call, errno %d", errno) + } + + memFree := uint64(uvmexp.free) << uvmexp.pageshift + memUsed := uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift + + memData.Total = metrics.OptUintWith(uint64(uvmexp.npages) << uvmexp.pageshift) + memData.Used.Bytes = metrics.OptUintWith(memUsed) + memData.Free = metrics.OptUintWith(memFree) + + memData.Actual.Free = metrics.OptUintWith(memFree + (uint64(bcachestats.numbufpages) << uvmexp.pageshift)) + memData.Actual.Used.Bytes = metrics.OptUintWith(memUsed - (uint64(bcachestats.numbufpages) << uvmexp.pageshift)) + + var err error + memData.Swap, err = getSwap() + if err != nil { + return memData, errors.Wrap(err, "error getting swap data") + } + + return memData, nil +} + +func getSwap() (SwapMetrics, error) { + swapData := SwapMetrics{} + nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0) + + // If there are no swap devices, nothing to do here. + if nswap == 0 { + return swapData, nil + } + + swdev := make([]Swapent, nswap) + + rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap) + if rnswap == 0 { + return swapData, errors.Errorf("error in SWAP_STATS sysctl, swapctl returned %d", rnswap) + } + + for i := 0; i < int(nswap); i++ { + if swdev[i].se_flags&C.SWF_ENABLE == 2 { + swapData.Used.Bytes = metrics.OptUintWith(swapData.Used.Bytes.ValueOr(0) + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE))) + swapData.Total = metrics.OptUintWith(swapData.Total.ValueOr(0) + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE))) + } + } + + swapData.Free = metrics.OptUintWith(swapData.Total.ValueOr(0) - swapData.Used.Bytes.ValueOr(0)) + + return swapData, nil +} diff --git a/metricbeat/internal/metrics/memory/memory_test.go b/metricbeat/internal/metrics/memory/memory_test.go new file mode 100644 index 00000000000..5b7908290ec --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_test.go @@ -0,0 +1,102 @@ +// 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. + +// +build !integration +// +build darwin freebsd linux openbsd windows + +package memory + +import ( + "runtime" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" +) + +func TestGetMemory(t *testing.T) { + mem, err := Get("") + + assert.NotNil(t, mem) + assert.NoError(t, err) + + assert.True(t, mem.Total.Exists()) + assert.True(t, (mem.Total.ValueOr(0) > 0)) + + assert.True(t, mem.Used.Bytes.Exists()) + assert.True(t, (mem.Used.Bytes.ValueOr(0) > 0)) + + assert.True(t, mem.Free.Exists()) + assert.True(t, (mem.Free.ValueOr(0) >= 0)) + + assert.True(t, mem.Actual.Free.Exists()) + assert.True(t, (mem.Actual.Free.ValueOr(0) >= 0)) + + assert.True(t, mem.Actual.Used.Bytes.Exists()) + assert.True(t, (mem.Actual.Used.Bytes.ValueOr(0) > 0)) +} + +func TestGetSwap(t *testing.T) { + if runtime.GOOS == "freebsd" { + return //no load data on freebsd + } + + mem, err := Get("") + + assert.NotNil(t, mem) + assert.NoError(t, err) + + assert.True(t, mem.Swap.Total.Exists()) + assert.True(t, (mem.Swap.Total.ValueOr(0) >= 0)) + + assert.True(t, mem.Swap.Used.Bytes.Exists()) + assert.True(t, (mem.Swap.Used.Bytes.ValueOr(0) >= 0)) + + assert.True(t, mem.Swap.Free.Exists()) + assert.True(t, (mem.Swap.Free.ValueOr(0) >= 0)) +} + +func TestMemPercentage(t *testing.T) { + m := Memory{ + Total: metrics.OptUintWith(7), + Used: UsedMemStats{Bytes: metrics.OptUintWith(5)}, + Free: metrics.OptUintWith(2), + } + m.fillPercentages() + assert.Equal(t, m.Used.Pct.ValueOr(0), 0.7143) + + m = Memory{ + Total: metrics.OptUintWith(0), + } + m.fillPercentages() + assert.Equal(t, m.Used.Pct.ValueOr(0), 0.0) +} + +func TestActualMemPercentage(t *testing.T) { + m := Memory{ + Total: metrics.OptUintWith(7), + Actual: ActualMemoryMetrics{ + Used: UsedMemStats{Bytes: metrics.OptUintWith(5)}, + Free: metrics.OptUintWith(2), + }, + } + + m.fillPercentages() + assert.Equal(t, m.Actual.Used.Pct.ValueOr(0), 0.7143) + +} diff --git a/metricbeat/internal/metrics/memory/memory_windows.go b/metricbeat/internal/metrics/memory/memory_windows.go new file mode 100644 index 00000000000..b19bf977091 --- /dev/null +++ b/metricbeat/internal/metrics/memory/memory_windows.go @@ -0,0 +1,51 @@ +// 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 memory + +import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/metricbeat/internal/metrics" + "github.com/elastic/go-windows" +) + +// get is the windows implementation of get for memory metrics +func get(_ string) (Memory, error) { + + memData := Memory{} + + memoryStatusEx, err := windows.GlobalMemoryStatusEx() + if err != nil { + return memData, errors.Wrap(err, "Error fetching global memory status") + } + memData.Total = metrics.OptUintWith(memoryStatusEx.TotalPhys) + memData.Free = metrics.OptUintWith(memoryStatusEx.AvailPhys) + + memData.Used.Bytes = metrics.OptUintWith(memoryStatusEx.TotalPhys - memoryStatusEx.AvailPhys) + + // We shouldn't really be doing this, but we also don't want to make breaking changes right now, + // and memory.actual is used by quite a few visualizations + memData.Actual.Free = memData.Free + memData.Actual.Used.Bytes = memData.Used.Bytes + + memData.Swap.Free = metrics.OptUintWith(memoryStatusEx.AvailPageFile) + memData.Swap.Total = metrics.OptUintWith(memoryStatusEx.TotalPageFile) + memData.Swap.Used.Bytes = metrics.OptUintWith(memoryStatusEx.TotalPageFile - memoryStatusEx.AvailPageFile) + + return memData, nil +} diff --git a/metricbeat/internal/metrics/opt.go b/metricbeat/internal/metrics/opt.go index f2cdfb0f05c..a5f28975252 100644 --- a/metricbeat/internal/metrics/opt.go +++ b/metricbeat/internal/metrics/opt.go @@ -17,6 +17,10 @@ package metrics +import "github.com/elastic/go-structform" + +// Uint + // OptUint is a wrapper for "optional" types, with the bool value indicating // if the stored int is a legitimate value. type OptUint struct { @@ -24,8 +28,8 @@ type OptUint struct { value uint64 } -// NewNone returns a new OptUint wrapper -func NewNone() OptUint { +// NewUintNone returns a new OptUint wrapper +func NewUintNone() OptUint { return OptUint{ exists: false, value: 0, @@ -45,6 +49,11 @@ func (opt OptUint) IsZero() bool { return !opt.exists } +// Exists returns true if the underlying value exists +func (opt OptUint) Exists() bool { + return opt.exists +} + // ValueOr returns the stored value, or a given int // Please do not use this for populating reported data, // as we actually want to avoid sending zeros where values are functionally null @@ -63,3 +72,70 @@ func SumOptUint(opts ...OptUint) uint64 { } return sum } + +// Fold implements the folder interface for OptUint +func (in *OptUint) Fold(v structform.ExtVisitor) error { + if in.exists { + value := in.value + v.OnUint64(value) + } else { + v.OnNil() + } + return nil +} + +// Float + +// OptFloat is a wrapper for "optional" types, with the bool value indicating +// if the stored int is a legitimate value. +type OptFloat struct { + exists bool + value float64 +} + +// NewFloatNone returns a new uint wrapper +func NewFloatNone() OptFloat { + return OptFloat{ + exists: false, + value: 0, + } +} + +// OptFloatWith returns a new uint wrapper for the specified value +func OptFloatWith(f float64) OptFloat { + return OptFloat{ + exists: true, + value: f, + } +} + +// IsZero returns true if the underlying value nil +func (opt OptFloat) IsZero() bool { + return !opt.exists +} + +// Exists returns true if the underlying value exists +func (opt OptFloat) Exists() bool { + return opt.exists +} + +// ValueOr returns the stored value, or zero +// Please do not use this for populating reported data, +// as we actually want to avoid sending zeros where values are functionally null +func (opt OptFloat) ValueOr(f float64) float64 { + if opt.exists { + return opt.value + } + return f +} + +// Fold implements the folder interface for OptUint +func (in *OptFloat) Fold(v structform.ExtVisitor) error { + if in.exists { + value := in.value + v.OnFloat64(value) + } else { + v.OnNil() + } + return nil +} diff --git a/metricbeat/module/linux/memory/_meta/data.json b/metricbeat/module/linux/memory/_meta/data.json index 79a3d431869..cb4acfe5da0 100644 --- a/metricbeat/module/linux/memory/_meta/data.json +++ b/metricbeat/module/linux/memory/_meta/data.json @@ -26,25 +26,25 @@ }, "page_stats": { "direct_efficiency": { - "pct": 0.9228 + "pct": 0.9839 }, "kswapd_efficiency": { - "pct": 0.7523 + "pct": 0.7739 }, "pgfree": { - "pages": 16061818710 + "pages": 40941189636 }, "pgscan_direct": { - "pages": 1198580 + "pages": 1199988 }, "pgscan_kswapd": { - "pages": 50222460 + "pages": 19970993 }, "pgsteal_direct": { - "pages": 1106083 + "pages": 1180686 }, "pgsteal_kswapd": { - "pages": 37782783 + "pages": 15456470 } } } diff --git a/metricbeat/module/linux/memory/data.go b/metricbeat/module/linux/memory/data.go index d3f1a5ef2f8..eb4706e02f0 100644 --- a/metricbeat/module/linux/memory/data.go +++ b/metricbeat/module/linux/memory/data.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -// +build darwin freebsd linux openbsd windows +// +build linux package memory @@ -23,77 +23,128 @@ import ( "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" - mem "github.com/elastic/beats/v7/libbeat/metric/system/memory" + "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 { - vmstat, err := mem.GetVMStat() + vmstat, err := GetVMStat() if err != nil { - return errors.Wrap(err, "VMStat") + return errors.Wrap(err, "error fetching VMStats") } - if vmstat != nil { - pageStats := common.MapStr{ - "pgscan_kswapd": common.MapStr{ - "pages": vmstat.PgscanKswapd, - }, - "pgscan_direct": common.MapStr{ - "pages": vmstat.PgscanDirect, - }, - "pgfree": common.MapStr{ - "pages": vmstat.Pgfree, - }, - "pgsteal_kswapd": common.MapStr{ - "pages": vmstat.PgstealKswapd, - }, - "pgsteal_direct": common.MapStr{ - "pages": vmstat.PgstealDirect, - }, - } - // This is similar to the vmeff stat gathered by sar - // these ratios calculate thhe efficiency of page reclaim - if vmstat.PgscanDirect != 0 { - pageStats["direct_efficiency"] = common.MapStr{ - "pct": common.Round(float64(vmstat.PgstealDirect)/float64(vmstat.PgscanDirect), common.DefaultDecimalPlacesCount), - } + pageStats := common.MapStr{ + "pgscan_kswapd": common.MapStr{ + "pages": vmstat.PgscanKswapd, + }, + "pgscan_direct": common.MapStr{ + "pages": vmstat.PgscanDirect, + }, + "pgfree": common.MapStr{ + "pages": vmstat.Pgfree, + }, + "pgsteal_kswapd": common.MapStr{ + "pages": vmstat.PgstealKswapd, + }, + "pgsteal_direct": common.MapStr{ + "pages": vmstat.PgstealDirect, + }, + } + // This is similar to the vmeff stat gathered by sar + // these ratios calculate thhe efficiency of page reclaim + if vmstat.PgscanDirect != 0 { + pageStats["direct_efficiency"] = common.MapStr{ + "pct": common.Round(float64(vmstat.PgstealDirect)/float64(vmstat.PgscanDirect), common.DefaultDecimalPlacesCount), } + } - if vmstat.PgscanKswapd != 0 { - pageStats["kswapd_efficiency"] = common.MapStr{ - "pct": common.Round(float64(vmstat.PgstealKswapd)/float64(vmstat.PgscanKswapd), common.DefaultDecimalPlacesCount), - } + if vmstat.PgscanKswapd != 0 { + pageStats["kswapd_efficiency"] = common.MapStr{ + "pct": common.Round(float64(vmstat.PgstealKswapd)/float64(vmstat.PgscanKswapd), common.DefaultDecimalPlacesCount), } - baseMap["page_stats"] = pageStats + } + baseMap["page_stats"] = pageStats + + thp, err := getHugePages() + if err != nil { + return errors.Wrap(err, "error getting huge pages") + } + thp["swap"] = common.MapStr{ + "out": common.MapStr{ + "pages": vmstat.ThpSwpout, + "fallback": vmstat.ThpSwpoutFallback, + }, } - hugePagesStat, err := mem.GetHugeTLBPages() + baseMap["hugepages"] = thp + + return nil +} + +func getHugePages() (common.MapStr, error) { + // see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt + table, err := memory.ParseMeminfo("") if err != nil { - return errors.Wrap(err, "hugepages") + return nil, errors.Wrap(err, "error parsing meminfo") } - if hugePagesStat != nil { - mem.AddHugeTLBPagesPercentage(hugePagesStat) - thp := common.MapStr{ - "total": hugePagesStat.Total, - "used": common.MapStr{ - "bytes": hugePagesStat.TotalAllocatedSize, - "pct": hugePagesStat.UsedPercent, - }, - "free": hugePagesStat.Free, - "reserved": hugePagesStat.Reserved, - "surplus": hugePagesStat.Surplus, - "default_size": hugePagesStat.DefaultSize, + thp := common.MapStr{} + + total, okTotal := table["HugePages_Total"] + free, okFree := table["HugePages_Free"] + reserved, okReserved := table["HugePages_Rsvd"] + totalSize, okTotalSize := table["Hugetlb"] + defaultSize, okDefaultSize := table["Hugepagesize"] + + // Calculate percentages + if okTotal && okFree && okReserved { + thp.Put("total", total) + thp.Put("free", free) + thp.Put("reserved", reserved) + + // TODO: this repliactes the behavior of metricbeat in the past, + // but it might be possilbe to do something like (HugePages_Total*Hugepagesize)-Hugetlb / (HugePages_Total*Hugepagesize) + var perc float64 + if total > 0 { + perc = float64(total-free+reserved) / float64(total) } - if vmstat != nil { - thp["swap"] = common.MapStr{ - "out": common.MapStr{ - "pages": vmstat.ThpSwpout, - "fallback": vmstat.ThpSwpoutFallback, - }, - } + thp.Put("used.pct", common.Round(perc, common.DefaultDecimalPlacesCount)) + + if !okTotalSize && okDefaultSize { + thp.Put("used.bytes", (total-free+reserved)*defaultSize) } - baseMap["hugepages"] = thp } - return nil + if okTotalSize { + thp.Put("used.bytes", totalSize) + } + if okDefaultSize { + thp.Put("default_size", defaultSize) + } + if surplus, ok := table["HugePages_Surp"]; ok { + thp.Put("surplus", surplus) + } + + return thp, nil +} + +// GetVMStat gets linux vmstat metrics +func GetVMStat() (*sysinfotypes.VMStatInfo, error) { + // TODO: We may want to pull this code out of go-sysinfo. + // It's platform specific, and not used by anything else. + h, err := sysinfo.Host() + if err != nil { + return nil, errors.Wrap(err, "failed to read self process information") + } + vmstatHandle, ok := h.(sysinfotypes.VMStat) + if !ok { + return nil, errors.Wrap(err, "VMStat not available for platform") + } + info, err := vmstatHandle.VMStat() + if err != nil { + return nil, errors.Wrap(err, "error getting VMStat info") + } + return info, nil + } diff --git a/libbeat/metric/system/memory/doc.go b/metricbeat/module/linux/memory/doc.go similarity index 100% rename from libbeat/metric/system/memory/doc.go rename to metricbeat/module/linux/memory/doc.go diff --git a/metricbeat/module/linux/memory/memory.go b/metricbeat/module/linux/memory/memory.go index 163e3bea771..13f080196ad 100644 --- a/metricbeat/module/linux/memory/memory.go +++ b/metricbeat/module/linux/memory/memory.go @@ -15,9 +15,13 @@ // specific language governing permissions and limitations // under the License. +// +build linux + package memory import ( + "github.com/pkg/errors" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/elastic/beats/v7/metricbeat/mb" @@ -54,7 +58,10 @@ 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{} - FetchLinuxMemStats(rootEvent) + err := FetchLinuxMemStats(rootEvent) + if err != nil { + return errors.Wrap(err, "error fetching memory stats") + } report.Event(mb.Event{ MetricSetFields: rootEvent, }) diff --git a/metricbeat/module/linux/memory/memory_test.go b/metricbeat/module/linux/memory/memory_test.go index 2980c94841e..52b0bdcc7e1 100644 --- a/metricbeat/module/linux/memory/memory_test.go +++ b/metricbeat/module/linux/memory/memory_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -// +build darwin freebsd linux openbsd windows +// +build linux package memory diff --git a/metricbeat/module/system/fields.go b/metricbeat/module/system/fields.go index fdeeea5f9c6..ffde1aef0bc 100644 --- a/metricbeat/module/system/fields.go +++ b/metricbeat/module/system/fields.go @@ -32,5 +32,5 @@ func init() { // AssetSystem returns asset data. // This is the base64 encoded gzipped contents of module/system. func AssetSystem() string { - return "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" + return "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" } diff --git a/metricbeat/module/system/memory/_meta/data.json b/metricbeat/module/system/memory/_meta/data.json index 06abee40a35..ce7da4541cf 100644 --- a/metricbeat/module/system/memory/_meta/data.json +++ b/metricbeat/module/system/memory/_meta/data.json @@ -15,13 +15,14 @@ "system": { "memory": { "actual": { - "free": 8461623296, + "free": 46533455872, "used": { - "bytes": 7159164928, - "pct": 0.4583 + "bytes": 20981358592, + "pct": 0.3108 } }, - "free": 1299234816, + "cached": 42114609152, + "free": 3916599296, "hugepages": { "default_size": 2097152, "free": 0, @@ -41,49 +42,49 @@ }, "page_stats": { "direct_efficiency": { - "pct": 0.9242 + "pct": 0.9871 }, "kswapd_efficiency": { - "pct": 0.7518 + "pct": 0.7105 }, "pgfree": { - "pages": 15924304810 + "pages": 69780946234 }, "pgscan_direct": { - "pages": 1185751 + "pages": 1512375 }, "pgscan_kswapd": { - "pages": 50008148 + "pages": 25880646 }, "pgsteal_direct": { - "pages": 1095884 + "pages": 1492831 }, "pgsteal_kswapd": { - "pages": 37594071 + "pages": 18387096 } }, "swap": { - "free": 7823421440, + "free": 8560832512, "in": { - "pages": 2702 + "pages": 727 }, "out": { - "pages": 23582 + "pages": 11197 }, "readahead": { - "cached": 554, - "pages": 986 + "cached": 9, + "pages": 45 }, - "total": 7897870336, + "total": 8589930496, "used": { - "bytes": 74448896, - "pct": 0.0094 + "bytes": 29097984, + "pct": 0.0034 } }, - "total": 15620788224, + "total": 67514814464, "used": { - "bytes": 14321553408, - "pct": 0.9168 + "bytes": 63598215168, + "pct": 0.942 } } } diff --git a/metricbeat/module/system/memory/_meta/fields.yml b/metricbeat/module/system/memory/_meta/fields.yml index ab80bf3ba28..9a8a7714a5e 100644 --- a/metricbeat/module/system/memory/_meta/fields.yml +++ b/metricbeat/module/system/memory/_meta/fields.yml @@ -23,6 +23,12 @@ The total amount of free memory in bytes. This value does not include memory consumed by system caches and buffers (see system.memory.actual.free). + - name: cached + type: long + format: bytes + description: > + Total Cached memory on system. + - name: used.pct type: scaled_float format: percent diff --git a/metricbeat/module/system/memory/helper_linux.go b/metricbeat/module/system/memory/helper_linux.go new file mode 100644 index 00000000000..a0ba099afae --- /dev/null +++ b/metricbeat/module/system/memory/helper_linux.go @@ -0,0 +1,32 @@ +// 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 memory + +import ( + "github.com/elastic/beats/v7/libbeat/common" + linux "github.com/elastic/beats/v7/metricbeat/module/linux/memory" + sysinfotypes "github.com/elastic/go-sysinfo/types" +) + +func fetchLinuxMemStats(baseMap common.MapStr) error { + return linux.FetchLinuxMemStats(baseMap) +} + +func getVMStat() (*sysinfotypes.VMStatInfo, error) { + return linux.GetVMStat() +} diff --git a/metricbeat/module/system/memory/helper_other.go b/metricbeat/module/system/memory/helper_other.go new file mode 100644 index 00000000000..adbeba59aa6 --- /dev/null +++ b/metricbeat/module/system/memory/helper_other.go @@ -0,0 +1,38 @@ +// 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. + +// +build darwin freebsd aix openbsd windows + +package memory + +import ( + "errors" + + "github.com/elastic/beats/v7/libbeat/common" + sysinfotypes "github.com/elastic/go-sysinfo/types" +) + +// These whole helper files are a shim until we can make breaking changes and remove these +// data enrichers from the metricset, as they're linux-only. +// DEPRECATE: 8.0 +func fetchLinuxMemStats(baseMap common.MapStr) error { + return errors.New("MemStats is only available on Linux") +} + +func getVMStat() (*sysinfotypes.VMStatInfo, error) { + return nil, errors.New("VMStat is only available on Linux") +} diff --git a/metricbeat/module/system/memory/memory.go b/metricbeat/module/system/memory/memory.go index 26c6bea1867..54565231c53 100644 --- a/metricbeat/module/system/memory/memory.go +++ b/metricbeat/module/system/memory/memory.go @@ -21,14 +21,15 @@ package memory import ( "fmt" + "runtime" "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common" - mem "github.com/elastic/beats/v7/libbeat/metric/system/memory" + "github.com/elastic/beats/v7/libbeat/common/transform/typeconv" + 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" - linux "github.com/elastic/beats/v7/metricbeat/module/linux/memory" "github.com/elastic/beats/v7/metricbeat/module/system" ) @@ -58,74 +59,34 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch fetches memory metrics from the OS. func (m *MetricSet) Fetch(r mb.ReporterV2) error { - memStat, err := mem.Get() - if err != nil { - return errors.Wrap(err, "memory") - } - mem.AddMemPercentage(memStat) - swapStat, err := mem.GetSwap() + eventRaw, err := metrics.Get("") if err != nil { - return errors.Wrap(err, "swap") - } - mem.AddSwapPercentage(swapStat) - - memory := common.MapStr{ - "total": memStat.Total, - "used": common.MapStr{ - "bytes": memStat.Used, - "pct": memStat.UsedPercent, - }, - "free": memStat.Free, - "actual": common.MapStr{ - "free": memStat.ActualFree, - "used": common.MapStr{ - "pct": memStat.ActualUsedPercent, - "bytes": memStat.ActualUsed, - }, - }, + return errors.Wrap(err, "error fetching memory metrics") } - vmstat, err := mem.GetVMStat() - if err != nil { - return errors.Wrap(err, "VMStat") - } - - swap := common.MapStr{ - "total": swapStat.Total, - "used": common.MapStr{ - "bytes": swapStat.Used, - "pct": swapStat.UsedPercent, - }, - "free": swapStat.Free, - } - - if vmstat != nil { - // Swap in and swap out numbers - swap["in"] = common.MapStr{ - "pages": vmstat.Pswpin, - } - swap["out"] = common.MapStr{ - "pages": vmstat.Pswpout, - } - //Swap readahead - //See https://www.kernel.org/doc/ols/2007/ols2007v2-pages-273-284.pdf - swap["readahead"] = common.MapStr{ - "pages": vmstat.SwapRa, - "cached": vmstat.SwapRaHit, - } - } + memory := common.MapStr{} + err = typeconv.Convert(&memory, &eventRaw) // for backwards compatibility, only report if we're not in fleet mode - if !m.IsAgent { - err := linux.FetchLinuxMemStats(memory) + // This is entirely linux-specific data that should live in linux/memory. + // DEPRECATE: remove this for 8.0 + if !m.IsAgent && runtime.GOOS == "linux" { + err := fetchLinuxMemStats(memory) if err != nil { return errors.Wrap(err, "error getting page stats") } + vmstat, err := getVMStat() + if err != nil { + return errors.Wrap(err, "Error getting VMStat data") + } + // Swap in and swap out numbers + memory.Put("swap.in.pages", vmstat.Pswpin) + memory.Put("swap.out.pages", vmstat.Pswpout) + memory.Put("swap.readahead.pages", vmstat.SwapRa) + memory.Put("swap.readahead.cached", vmstat.SwapRaHit) } - memory["swap"] = swap - r.Event(mb.Event{ MetricSetFields: memory, }) diff --git a/metricbeat/module/system/memory/memory_test.go b/metricbeat/module/system/memory/memory_test.go index 978d2de8ae1..515bfcb26b8 100644 --- a/metricbeat/module/system/memory/memory_test.go +++ b/metricbeat/module/system/memory/memory_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -// +build darwin freebsd linux openbsd windows +// +build darwin freebsd linux openbsd windows aix package memory diff --git a/metricbeat/module/system/test_system.py b/metricbeat/module/system/test_system.py index b1c83db81eb..e4d69723cf1 100644 --- a/metricbeat/module/system/test_system.py +++ b/metricbeat/module/system/test_system.py @@ -67,8 +67,11 @@ SYSTEM_FSSTAT_FIELDS = ["count", "total_files", "total_size"] +SYSTEM_MEMORY_FIELDS_LINUX = ["swap", "actual.free", "free", "total", "cached", "used.bytes", "used.pct", "actual.used.bytes", + "actual.used.pct", "hugepages", "page_stats"] + SYSTEM_MEMORY_FIELDS = ["swap", "actual.free", "free", "total", "used.bytes", "used.pct", "actual.used.bytes", - "actual.used.pct", "hugepages", "page_stats"] + "actual.used.pct", "hugepages", "page_stats"] SYSTEM_NETWORK_FIELDS = ["name", "out.bytes", "in.bytes", "out.packets", "in.packets", "in.error", "out.error", "in.dropped", "out.dropped"] @@ -384,7 +387,13 @@ def test_memory(self): if not re.match("(?i)linux", sys.platform) and not "page_stats" in memory: # Ensure presence of page_stats only in Linux memory["page_stats"] = None - self.assertCountEqual(self.de_dot(SYSTEM_MEMORY_FIELDS), memory.keys()) + + if sys.platform.startswith("linux"): + self.assertCountEqual(self.de_dot( + SYSTEM_MEMORY_FIELDS_LINUX), memory.keys()) + else: + self.assertCountEqual(self.de_dot( + SYSTEM_MEMORY_FIELDS), memory.keys()) # Check that percentages are calculated. mem = memory From ba4d7c286519dccae13e541b9eba2bc997bbd923 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Wed, 30 Jun 2021 06:05:11 +0800 Subject: [PATCH 18/25] Add kinesis metricset (#25989) --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 258 +++ .../metricbeat-aws-kinesis-overview.png | Bin 0 -> 865888 bytes metricbeat/docs/modules/aws.asciidoc | 4 + metricbeat/docs/modules/aws/kinesis.asciidoc | 25 + metricbeat/docs/modules_list.asciidoc | 3 +- x-pack/metricbeat/module/aws/_meta/config.yml | 1 + .../Metricbeat-aws-kinesis-overview.json | 1378 +++++++++++++++++ .../module/aws/dynamodb/_meta/docs.asciidoc | 7 + x-pack/metricbeat/module/aws/fields.go | 2 +- .../module/aws/kinesis/_meta/data.json | 53 + .../module/aws/kinesis/_meta/docs.asciidoc | 40 + .../module/aws/kinesis/_meta/fields.yml | 110 ++ .../aws/kinesis/kinesis_integration_test.go | 38 + .../module/aws/kinesis/kinesis_test.go | 21 + .../module/aws/kinesis/manifest.yml | 50 + x-pack/metricbeat/module/aws/module.yml | 1 + .../module/aws/natgateway/_meta/docs.asciidoc | 7 + .../aws/transitgateway/_meta/docs.asciidoc | 7 + .../module/aws/vpn/_meta/docs.asciidoc | 7 + x-pack/metricbeat/modules.d/aws.yml.disabled | 1 + 21 files changed, 2012 insertions(+), 2 deletions(-) create mode 100644 metricbeat/docs/images/metricbeat-aws-kinesis-overview.png create mode 100644 metricbeat/docs/modules/aws/kinesis.asciidoc create mode 100644 x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-kinesis-overview.json create mode 100644 x-pack/metricbeat/module/aws/kinesis/_meta/data.json create mode 100644 x-pack/metricbeat/module/aws/kinesis/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/aws/kinesis/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/aws/kinesis/kinesis_integration_test.go create mode 100644 x-pack/metricbeat/module/aws/kinesis/kinesis_test.go create mode 100644 x-pack/metricbeat/module/aws/kinesis/manifest.yml diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e3912d5805f..874facc5433 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -980,6 +980,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Migrate sqs metricsets to use cloudwatch input. {pull}26117[26117] - Collect linked account information in AWS billing. {pull}26285[26285] - Add total CPU to vSphere virtual machine metrics. {pull}26167[26167] +- Add AWS Kinesis metricset. {pull}25989[25989] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 10db058421a..de6e99e8a77 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -3015,6 +3015,264 @@ type: long -- The number of targets that are considered unhealthy. +type: long + +-- + +[float] +=== kinesis + +`kinesis` contains the metrics that were scraped from AWS CloudWatch which contains monitoring metrics sent by Amazon Kinesis. + + + + +*`aws.kinesis.metrics.GetRecords_Bytes.avg`*:: ++ +-- +The average number of bytes retrieved from the Kinesis stream, measured over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.GetRecords_IteratorAgeMilliseconds.avg`*:: ++ +-- +The age of the last record in all GetRecords calls made against a Kinesis stream, measured over the specified time period. Age is the difference between the current time and when the last record of the GetRecords call was written to the stream. + + +type: double + +-- + +*`aws.kinesis.metrics.GetRecords_Latency.avg`*:: ++ +-- +The time taken per GetRecords operation, measured over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.GetRecords_Records.sum`*:: ++ +-- +The number of records retrieved from the shard, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.GetRecords_Success.sum`*:: ++ +-- +The number of successful GetRecords operations per stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.IncomingBytes.avg`*:: ++ +-- +The number of bytes successfully put to the Kinesis stream over the specified time period. This metric includes bytes from PutRecord and PutRecords operations. + + +type: double + +-- + +*`aws.kinesis.metrics.IncomingRecords.avg`*:: ++ +-- +The number of records successfully put to the Kinesis stream over the specified time period. This metric includes record counts from PutRecord and PutRecords operations. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecord_Bytes.avg`*:: ++ +-- +The number of bytes put to the Kinesis stream using the PutRecord operation over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecord_Latency.avg`*:: ++ +-- +The time taken per PutRecord operation, measured over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecord_Success.avg`*:: ++ +-- +The percentage of successful writes to a Kinesis stream, measured over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecords_Bytes.avg`*:: ++ +-- +The average number of bytes put to the Kinesis stream using the PutRecords operation over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecords_Latency.avg`*:: ++ +-- +The average time taken per PutRecords operation, measured over the specified time period. + + +type: double + +-- + +*`aws.kinesis.metrics.PutRecords_Success.avg`*:: ++ +-- +The total number of PutRecords operations where at least one record succeeded, per Kinesis stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.PutRecords_TotalRecords.sum`*:: ++ +-- +The total number of records sent in a PutRecords operation per Kinesis data stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.PutRecords_SuccessfulRecords.sum`*:: ++ +-- +The number of successful records in a PutRecords operation per Kinesis data stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.PutRecords_FailedRecords.sum`*:: ++ +-- +The number of records rejected due to internal failures in a PutRecords operation per Kinesis data stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.PutRecords_ThrottledRecords.sum`*:: ++ +-- +The number of records rejected due to throttling in a PutRecords operation per Kinesis data stream, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.ReadProvisionedThroughputExceeded.avg`*:: ++ +-- +The number of GetRecords calls throttled for the stream over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShard_RateExceeded.avg`*:: ++ +-- +This metric is emitted when a new subscription attempt fails because there already is an active subscription by the same consumer or if you exceed the number of calls per second allowed for this operation. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShard_Success.avg`*:: ++ +-- +This metric records whether the SubscribeToShard subscription was successfully established. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShardEvent_Bytes.avg`*:: ++ +-- +The number of bytes received from the shard, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShardEvent_MillisBehindLatest.avg`*:: ++ +-- +The difference between the current time and when the last record of the SubscribeToShard event was written to the stream. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShardEvent_Records.sum`*:: ++ +-- +The number of records received from the shard, measured over the specified time period. + + +type: long + +-- + +*`aws.kinesis.metrics.SubscribeToShardEvent_Success.avg`*:: ++ +-- +This metric is emitted every time an event is published successfully. It is only emitted when there's an active subscription. + + +type: long + +-- + +*`aws.kinesis.metrics.WriteProvisionedThroughputExceeded.avg`*:: ++ +-- +The number of records rejected due to throttling for the stream over the specified time period. This metric includes throttling from PutRecord and PutRecords operations. + + type: long -- diff --git a/metricbeat/docs/images/metricbeat-aws-kinesis-overview.png b/metricbeat/docs/images/metricbeat-aws-kinesis-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd41126714d2c8e9df698bb9b8a6ce0b31d8cfa GIT binary patch literal 865888 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

;q4~;m~Y%JFn>@*${MPCM#shiM( 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

  • k1lY+4C9Y?{3xlc*32}`q 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%0D1s-fny1Uo5 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⁣n$N3BRQzns1g-Wz*<)9 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 z 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�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

    uTx=vb3^m-{U5NR>h&xN%vy@GiZgr~2;QSxy4l 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 literal 0 HcmV?d00001 diff --git a/metricbeat/docs/modules/aws.asciidoc b/metricbeat/docs/modules/aws.asciidoc index 085436b05d9..7d23de407fa 100644 --- a/metricbeat/docs/modules/aws.asciidoc +++ b/metricbeat/docs/modules/aws.asciidoc @@ -386,6 +386,8 @@ The following metricsets are available: * <> +* <> + * <> * <> @@ -418,6 +420,8 @@ include::aws/ec2.asciidoc[] include::aws/elb.asciidoc[] +include::aws/kinesis.asciidoc[] + include::aws/lambda.asciidoc[] include::aws/natgateway.asciidoc[] diff --git a/metricbeat/docs/modules/aws/kinesis.asciidoc b/metricbeat/docs/modules/aws/kinesis.asciidoc new file mode 100644 index 00000000000..8700afa0578 --- /dev/null +++ b/metricbeat/docs/modules/aws/kinesis.asciidoc @@ -0,0 +1,25 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-aws-kinesis]] +[role="xpack"] +=== AWS kinesis metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/aws/kinesis/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/aws/kinesis/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 7917a95594c..ebe1a03bed3 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -16,12 +16,13 @@ This file is generated! See scripts/mage/docs_collector.go |<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | -.16+| .16+| |<> beta[] +.17+| .17+| |<> beta[] |<> |<> beta[] |<> |<> |<> +|<> beta[] |<> |<> beta[] |<> diff --git a/x-pack/metricbeat/module/aws/_meta/config.yml b/x-pack/metricbeat/module/aws/_meta/config.yml index 6fc2787fa8c..68293513b02 100644 --- a/x-pack/metricbeat/module/aws/_meta/config.yml +++ b/x-pack/metricbeat/module/aws/_meta/config.yml @@ -2,6 +2,7 @@ period: 1m metricsets: - elb + - kinesis - natgateway - rds - transitgateway diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-kinesis-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-kinesis-overview.json new file mode 100644 index 00000000000..a6cca66cfbd --- /dev/null +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-kinesis-overview.json @@ -0,0 +1,1378 @@ +{ + "objects": [ + { + "attributes": { + "description": "Overview of Amazon Kinesis Metrics", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 5, + "i": "0359194f-01a1-4a5b-8040-c897bdc86638", + "w": 48, + "x": 0, + "y": 0 + }, + "panelIndex": "0359194f-01a1-4a5b-8040-c897bdc86638", + "panelRefName": "panel_0359194f-01a1-4a5b-8040-c897bdc86638", + "title": "Filters", + "type": "visualization", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "df2dc50f-c09b-4dcd-96a8-24037c576db3", + "w": 16, + "x": 32, + "y": 5 + }, + "panelIndex": "df2dc50f-c09b-4dcd-96a8-24037c576db3", + "panelRefName": "panel_df2dc50f-c09b-4dcd-96a8-24037c576db3", + "title": "GetRecords Latency", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "5f153d11-e84a-4ac5-aec9-4fca79863744", + "w": 16, + "x": 0, + "y": 5 + }, + "panelIndex": "5f153d11-e84a-4ac5-aec9-4fca79863744", + "panelRefName": "panel_5f153d11-e84a-4ac5-aec9-4fca79863744", + "title": "PutRecords Latency", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "a7378b79-483c-4e99-97e2-9b49fd9e81da", + "w": 16, + "x": 16, + "y": 5 + }, + "panelIndex": "a7378b79-483c-4e99-97e2-9b49fd9e81da", + "panelRefName": "panel_a7378b79-483c-4e99-97e2-9b49fd9e81da", + "title": "PutRecord Latency", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "01a12917-ef1c-47b6-964a-26ef424dd0d3", + "w": 16, + "x": 32, + "y": 20 + }, + "panelIndex": "01a12917-ef1c-47b6-964a-26ef424dd0d3", + "panelRefName": "panel_01a12917-ef1c-47b6-964a-26ef424dd0d3", + "title": "GetRecords Bytes", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "7e5774cb-e2e5-4f11-95bc-732ed6600757", + "w": 16, + "x": 0, + "y": 20 + }, + "panelIndex": "7e5774cb-e2e5-4f11-95bc-732ed6600757", + "panelRefName": "panel_7e5774cb-e2e5-4f11-95bc-732ed6600757", + "title": "PutRecord Bytes", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "e18e62e5-672a-4939-afe1-68354e76aefc", + "w": 16, + "x": 16, + "y": 20 + }, + "panelIndex": "e18e62e5-672a-4939-afe1-68354e76aefc", + "panelRefName": "panel_e18e62e5-672a-4939-afe1-68354e76aefc", + "title": "PutRecord Bytes", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "a1f01da7-4496-4f4e-acc8-9e6efd826f52", + "w": 16, + "x": 32, + "y": 35 + }, + "panelIndex": "a1f01da7-4496-4f4e-acc8-9e6efd826f52", + "panelRefName": "panel_a1f01da7-4496-4f4e-acc8-9e6efd826f52", + "title": "GetRecords Success", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "6ddd4401-6625-42b6-9270-9bc17c8408e6", + "w": 16, + "x": 0, + "y": 35 + }, + "panelIndex": "6ddd4401-6625-42b6-9270-9bc17c8408e6", + "panelRefName": "panel_6ddd4401-6625-42b6-9270-9bc17c8408e6", + "title": "PutRecords Success", + "type": "lens", + "version": "7.13.2" + }, + { + "embeddableConfig": { + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "fb4e4fb3-91de-46c8-b3f8-ef17ba3c4773", + "w": 16, + "x": 16, + "y": 35 + }, + "panelIndex": "fb4e4fb3-91de-46c8-b3f8-ef17ba3c4773", + "panelRefName": "panel_fb4e4fb3-91de-46c8-b3f8-ef17ba3c4773", + "title": "PutRecord Success", + "type": "lens", + "version": "7.13.2" + } + ], + "timeRestore": false, + "title": "[Metricbeat AWS] Kinesis Overview", + "version": 1 + }, + "coreMigrationVersion": "7.13.2", + "id": "07d67a60-d872-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "dashboard": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "3c5d7860-d903-11eb-8220-c9141cc1b15c", + "name": "0359194f-01a1-4a5b-8040-c897bdc86638:panel_0359194f-01a1-4a5b-8040-c897bdc86638", + "type": "visualization" + }, + { + "id": "63aa5990-d86f-11eb-8220-c9141cc1b15c", + "name": "df2dc50f-c09b-4dcd-96a8-24037c576db3:panel_df2dc50f-c09b-4dcd-96a8-24037c576db3", + "type": "lens" + }, + { + "id": "9deb6a80-d870-11eb-8220-c9141cc1b15c", + "name": "5f153d11-e84a-4ac5-aec9-4fca79863744:panel_5f153d11-e84a-4ac5-aec9-4fca79863744", + "type": "lens" + }, + { + "id": "2a711450-d871-11eb-8220-c9141cc1b15c", + "name": "a7378b79-483c-4e99-97e2-9b49fd9e81da:panel_a7378b79-483c-4e99-97e2-9b49fd9e81da", + "type": "lens" + }, + { + "id": "d1468000-d86f-11eb-8220-c9141cc1b15c", + "name": "01a12917-ef1c-47b6-964a-26ef424dd0d3:panel_01a12917-ef1c-47b6-964a-26ef424dd0d3", + "type": "lens" + }, + { + "id": "6d631980-d870-11eb-8220-c9141cc1b15c", + "name": "7e5774cb-e2e5-4f11-95bc-732ed6600757:panel_7e5774cb-e2e5-4f11-95bc-732ed6600757", + "type": "lens" + }, + { + "id": "6d631980-d870-11eb-8220-c9141cc1b15c", + "name": "e18e62e5-672a-4939-afe1-68354e76aefc:panel_e18e62e5-672a-4939-afe1-68354e76aefc", + "type": "lens" + }, + { + "id": "79d713c0-d86f-11eb-8220-c9141cc1b15c", + "name": "a1f01da7-4496-4f4e-acc8-9e6efd826f52:panel_a1f01da7-4496-4f4e-acc8-9e6efd826f52", + "type": "lens" + }, + { + "id": "c68d7c30-d870-11eb-8220-c9141cc1b15c", + "name": "6ddd4401-6625-42b6-9270-9bc17c8408e6:panel_6ddd4401-6625-42b6-9270-9bc17c8408e6", + "type": "lens" + }, + { + "id": "56ac2b40-d871-11eb-8220-c9141cc1b15c", + "name": "fb4e4fb3-91de-46c8-b3f8-ef17ba3c4773:panel_fb4e4fb3-91de-46c8-b3f8-ef17ba3c4773", + "type": "lens" + } + ], + "type": "dashboard", + "updated_at": "2021-06-29T18:23:18.412Z", + "version": "WzEzOTgwLDFd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "AWS Kinesis Filter [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "controls": [ + { + "fieldName": "cloud.region", + "id": "1549397251041", + "indexPatternRefName": "control_0_index_pattern", + "label": "region name", + "options": { + "dynamicOptions": true, + "multiselect": true, + "order": "desc", + "size": 5, + "type": "terms" + }, + "parent": "", + "type": "list" + }, + { + "fieldName": "aws.dimensions.StreamName", + "id": "1624989316975", + "indexPatternRefName": "control_1_index_pattern", + "label": "stream name", + "options": { + "dynamicOptions": true, + "multiselect": true, + "order": "desc", + "size": 5, + "type": "terms" + }, + "parent": "", + "type": "list" + } + ], + "pinFilters": false, + "updateFiltersOnChange": true, + "useTimeFilter": false + }, + "title": "AWS Kinesis Filter [Metricbeat AWS]", + "type": "input_control_vis" + } + }, + "coreMigrationVersion": "7.13.2", + "id": "3c5d7860-d903-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "visualization": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "control_0_index_pattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "control_1_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2021-06-29T17:55:48.582Z", + "version": "WzEzNjQ1LDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "columns": { + "092aa8e6-3739-49c1-ac6c-ec67956dec97": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "GetRecords Latency", + "operationType": "median", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.GetRecords_Latency.avg" + }, + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "8c750b7f-30c5-4d35-93f7-dbea0067dca4": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "092aa8e6-3739-49c1-ac6c-ec67956dec97", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS GetRecords Latency [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "63aa5990-d86f-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T17:59:42.533Z", + "version": "WzEzNjk2LDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "columns": { + "092aa8e6-3739-49c1-ac6c-ec67956dec97": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "PutRecords Latency", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.PutRecords.Latency.avg" + }, + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "8c750b7f-30c5-4d35-93f7-dbea0067dca4": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "092aa8e6-3739-49c1-ac6c-ec67956dec97", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS PutRecords Latency [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "9deb6a80-d870-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:01:15.961Z", + "version": "WzEzODA1LDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "columns": { + "092aa8e6-3739-49c1-ac6c-ec67956dec97": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "PutRecord Latency", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.PutRecord.Latency.avg" + }, + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "8c750b7f-30c5-4d35-93f7-dbea0067dca4": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "092aa8e6-3739-49c1-ac6c-ec67956dec97", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "092aa8e6-3739-49c1-ac6c-ec67956dec97" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "8c750b7f-30c5-4d35-93f7-dbea0067dca4", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS PutRecord Latency [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "2a711450-d871-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:01:38.259Z", + "version": "WzEzODQyLDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "7cd103e8-3dd3-4fa2-8c13-bc9f80617367", + "36345734-4c23-4815-8a5e-b63c20cac94d" + ], + "columns": { + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "36345734-4c23-4815-8a5e-b63c20cac94d": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "GetRecords Bytes", + "operationType": "median", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.GetRecords_Bytes.avg" + }, + "7cd103e8-3dd3-4fa2-8c13-bc9f80617367": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "36345734-4c23-4815-8a5e-b63c20cac94d", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "36345734-4c23-4815-8a5e-b63c20cac94d" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "7cd103e8-3dd3-4fa2-8c13-bc9f80617367", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS GetRecords Bytes [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "d1468000-d86f-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:00:11.026Z", + "version": "WzEzNzIzLDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "7cd103e8-3dd3-4fa2-8c13-bc9f80617367", + "36345734-4c23-4815-8a5e-b63c20cac94d" + ], + "columns": { + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "36345734-4c23-4815-8a5e-b63c20cac94d": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "PutRecord Bytes", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.PutRecord.Bytes.avg" + }, + "7cd103e8-3dd3-4fa2-8c13-bc9f80617367": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "36345734-4c23-4815-8a5e-b63c20cac94d", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "36345734-4c23-4815-8a5e-b63c20cac94d" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "7cd103e8-3dd3-4fa2-8c13-bc9f80617367", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS PutRecord Bytes [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "6d631980-d870-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:01:45.819Z", + "version": "WzEzODU1LDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "columns": { + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "6117c588-4178-4597-b6da-e0277ec0d410": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "GetRecords Success", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.GetRecords_Success.sum" + }, + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "6117c588-4178-4597-b6da-e0277ec0d410", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS GetRecords Success [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "79d713c0-d86f-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:00:17.123Z", + "version": "WzEzNzMzLDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "columns": { + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "6117c588-4178-4597-b6da-e0277ec0d410": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "PutRecords Success", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.PutRecords.Success.avg" + }, + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "6117c588-4178-4597-b6da-e0277ec0d410", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS PutRecords Success [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "c68d7c30-d870-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:01:31.839Z", + "version": "WzEzODMwLDFd" + }, + { + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "fa1d3f51-58b9-4971-a28d-40616cfceb01": { + "columnOrder": [ + "19e03939-49d0-48f7-b76c-d70142001365", + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "columns": { + "19e03939-49d0-48f7-b76c-d70142001365": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + }, + "6117c588-4178-4597-b6da-e0277ec0d410": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "PutRecord Success", + "operationType": "average", + "scale": "ratio", + "sourceField": "aws.kinesis.metrics.PutRecord.Success.avg" + }, + "a077ea8a-21dd-4bfe-b146-6d6425f7a14f": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.dimensions.StreamName", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "6117c588-4178-4597-b6da-e0277ec0d410", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.dimensions.StreamName" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "layers": [ + { + "accessors": [ + "6117c588-4178-4597-b6da-e0277ec0d410" + ], + "layerId": "fa1d3f51-58b9-4971-a28d-40616cfceb01", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "a077ea8a-21dd-4bfe-b146-6d6425f7a14f", + "xAccessor": "19e03939-49d0-48f7-b76c-d70142001365" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "AWS PutRecord Success [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "coreMigrationVersion": "7.13.2", + "id": "56ac2b40-d871-11eb-8220-c9141cc1b15c", + "migrationVersion": { + "lens": "7.13.1" + }, + "namespaces": [ + "default" + ], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-fa1d3f51-58b9-4971-a28d-40616cfceb01", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-06-29T18:01:53.731Z", + "version": "WzEzODY5LDFd" + } + ], + "version": "7.13.2" +} diff --git a/x-pack/metricbeat/module/aws/dynamodb/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/dynamodb/_meta/docs.asciidoc index 54635237c5f..98713e800bb 100644 --- a/x-pack/metricbeat/module/aws/dynamodb/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/dynamodb/_meta/docs.asciidoc @@ -14,6 +14,13 @@ For all other DynamoDB metrics, the aggregation granularity is five minutes. # the options for this metricset are also available here. ---- +[float] +=== Dashboard + +The aws dynamodb metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-dynamodb-overview.png[] + [float] === Metrics Please see more details for each metric in diff --git a/x-pack/metricbeat/module/aws/fields.go b/x-pack/metricbeat/module/aws/fields.go index a06ed77cfae..553b2a0176a 100644 --- a/x-pack/metricbeat/module/aws/fields.go +++ b/x-pack/metricbeat/module/aws/fields.go @@ -19,5 +19,5 @@ func init() { // AssetAws returns asset data. // This is the base64 encoded gzipped contents of module/aws. func AssetAws() string { - return "eJzsvVtzGzfyN3yfT4Ham9gpiZvYydZbuXirdMpGz1+WFVFe544LzjRJrDDAGMBIZmo//FNoAHOe4WmGkv/1+CoRSeDXBzS6G43GKXmE9a+EPuvvCDHMcPiV/O3s8/Rv3xESg44USw2T4lfy/39HCCH/ps/63ySRccaBRJJziIwmZ5+nJJGCGamYWJIEjGKRJgslE/zsgsssfqYmWk2+I0QBB6rhV7Kk3xGyYMBj/SuOfkoETSCgsf/MOrVfVDJL/V9aQFUHKQ9k6FJPfsj/HMaT8/9AZEp/dn+YuU8fYf0sVdz+8SyhacrE0n/3bz/8rfS9Vmzu3wNd2oHJE+UZkJQy5flDnzVRoGWmItCTBgX6/WSeRY9gJvb/G5Q0sfZguKUJELkglEzfEz9qY8KYJSA0k+KVMO4DKlMZVgPy9z9MvMpNfpj88P2OqGOZzTmMAVoTs6KGKDCZEhA7eRdrgZzdXZMvGah1kyTOxCPEMxpFMhOmQVF5QZAW/S8PxeLKn7s1ZwNN9t/1Jck0xMRIwmIQhi3WHirxUCetGGq6eyAKp8eKUM6o3h5QADNnnDOx3MjUHhT/9mP8m0RSGMqEFTUQ0IYl1EBMohVVS9BkIRVZy0yhGfSICBM1ixj+5ZZxDoZuKd6rMOeFm7KVzVxW6G1Q94F+ZUmWdBDgsffI9yJTCkS03lfGV415Iz8iyQTrmHQK6olFcHuAbvkhcEAk1Uox6WJGO4yzRCrD/oL4QmrTCqSuWF0iLY9Kk9rCrw7ZMFqt5OXQSCS16RozTGk53TlhOzM3zdgYMsx1zkHEr5FlHtjRGFaZr5Ndt1IllFu+ftJ0CWdtuF6YcQVEklmMx2Bex5zdfPwk5q9V8XJoR1O92ozdTLOs/SOjwjDTbuFfjmko9S8e21GYVp2xk2naUGVmMTX77012BGJHwJ1JWZcSnmx8ZfdjKzLdOjOI+KB5r0S8x6yoArMYFkwwO85gevIIdZ3bRE2DoocVEG0wNPUOeapAgzCaUAzKLKWU6BQitmAQt+IsBZXrtE0xh4JkXRA7lo3UmkCq/J6vK0Ea6Q55yOZgjewQ+zQIanrp1sQS+JpyqUA5vGS+LoJg3XDMo9wpPsg3L4apuedJOSp7BgVER4qmITLLMxWfMTp7XrFoVQzQkt+w8rIkxWyxAGX/x9KhUxpVfcVqwiP863Pq83GGC5qsxuXDlnT9eQXCRaEl/hOaspbUwFrQRMbzg6QTBjmSbOwPL3HKy/NDQy0/9mCmbZpFEWi9yPg9fMlAmxtqbMwzoU/1aI3suDE25U+8DtAnUHYL424ua2V0joMoB0TbgDqwzYbaZwn9S4riT1OjgCZ1VnggmbdrZTUzLAGSgmIynuzOkIR+HY0hIdx7jQz5KDgTcC1i+HoHKgJh6BLulFwq0HpUNUnz6SxDIpmkHOxvnL2gRMAzWXI5p5xoiKSIqVoTZoESpskcLME0jl1qhhJD5xy66bxT8olpJgXEnxUzcEFTGjGz/iSYGZdOkSVzUJbGtMBAni0IEnkU6OVp7yUgJZh96qB/KyrvgcYvTaQCGg9O44UUOkuOTWAwagWhbcRFHhuRT6C6l+NJ6zRakrXMSEQFMYpGj2Qln0mSRSs7G6b4yrw1KyWz5SrNjF0OmYaeRd7NMp0lnSxrSentwDCdJd8ol45sH5qa1Wobvj2mja5b3xKf7iHlLKKWsmP6YMBpqgPlczDPYPdWQbI0xrwzM5AQmqZA0YFgAjmW+xwafQ5rs1tnkgJsXGkJcxb9hFAROw+7OTIV0qxA5b/wk3n7v2H/buHfMVy2/zX8e1BUaBpZui+kWHAWmdEU8MwrnwIb6nsunXJ4gpK3G2dgHTdT4KLcLl6EpnNeR1K4g5q2vBophpOOGZomgNPp3Vgxkq2ShvLXyoYzd9zW5TIaxtlfuN6OYqiq0cAmJzJDdBDb+NvS23o03E9sdcN6NdS27mk7kztdawPJlVJSjbkP7xi6OsO2BAGqmT12/6ggvz883JFffvyRaENNZjf0GA4IcC+kiJlbVxcriB5/o4xbVXfIR2RO4c8tcEpCjYEkddxKQS2kSuy6Duic6HsW7B2ImIllaSe8QC04Bgm4G7lNz4uRKkDEBoQlqLmVtY46z4z7+Yo+ARHSkDUYMrcmrjTYgZ4CjR9WShrD4eoJxGhCvm/TfiQOvkaA/iF0W7LWIQcKkQP5Y6v5zhwoecycJcy0Z7OkIDSvWCNvtPW/qa6wRDgWvO3mAdr316kHVRs/piL4be8D/WpXhe51mQ8zFcFh7s+PIFdsdDUHV1U1X1tZdu5nbnSmnbaQWIJGo0HTlK+d2TmNIUGn2XJJWza1M6nPshZserCj3FgX7RUzrNAIR2p7KFvLmcpFmdPkN6mazDMFqyOa6nKtUofbSePgBHjAW6gr0pPpHhPeJo/Pbnc8pkBafbHXLREHeVSRvGpBvLwt+UC/lqIM1N+uuGrMBMZh8dSKLVfQqF9y/xpj1XR/g57vwrjOGO1lOFdXw3amlX/Ss0b35FpegzMv+067H5LDXB/xfPzqfHpYucLQB+P/kjxLcGGer601OzzoD0kvzf5CxQEardz6kKmNd5kU5SjWZ6HRRUyNdXmfEJK2YSKNVuFY85YZJU/n1Bo4JrShIoIT8ryy8jGljEKtvCf8uSUJvilgdqzBpTcqb9wy+CaZY/XmYzoEZ6zBMZglrPmBOV80pn4bEO0XDUt6duySHMfDWhPigWD/yCCDGxBLsxoIb42rdnOv612exHqmzKAGSutS+IIE1KwDSHrII96ivGIg2qob1fXfP5blkILyWwp5c/3xbvqWxMDZEyhw0HNZ2g8ru9zCxdc+h3d1PvWLb0I+2XX2zMyqXGfgBphOL/M1KgVfb2JL+UR6FBX1ddo9gtfkjSiqu40k7375x//UHKO3xXFivxYMw5vzTGlzTrm1YwNwo8D0T8y5cnKXqVRqQEhvlum7tyekUFDyMTUsQW78fnlJ3mjz01t3IHUhefhb9NPbKjGO3hjs0l9YfuKionOJmb42LY0UxNbpfGM1zYIgeC0mh1H5XJufEAJOrCChTJQO2uaWYY2Lhu0qh4cxmBy0AutLBe1vDt2K01ZPnPNDOW/Ycxe4DGReLACX6joyVY3VNCRZ1zE/BkG9GF0dmpBefqpJsXOSs3nCjCmf/ec+evTuMB89endMH/3i3WE+epRmE+T0JG0UhjvidUQ5xLMFl7T+hS1qi6uWhHIuIzyDv7p4h3qXGSinBqgCf8fPcBtUkUxDOB8NzmL7fTtLiDNCM7z000rLpguPHfXRuQ5e3H3KLV2+sMrYcCO238pKge8mvHO3eYyCGCjeMS4Dd4wWBeYV1TZmVRnERDP7F2bIM9WE00yg4442nSpTL5YpE6MzlfJMz45AlJ+qShEeTuGhVGHyBMkEZo5KsYYzEfZnF3efLnAEv3v7W/hMk79AyW0p1TN3D7T9PvXBpCItrQTbtSKkISllMYnls7AkN+XtvAFnVswqswY0ytBbpHF+jOlI6LilDeZZqscJE5OU2k17v8vE7ZTWrbyfgSiIgD1Z1RO4c3kQhAkDakEj0I2lx0RoPWGdmbagsJuiWQpqpiEawQI2aSu5+WjLrde1NZn9FMnMHFFIu6PfQ0glkv63SImJyXxttr+U71z0X0nbj/YQHw5ztBWGsx1Fco6uktx2J3GzKr684I626l5QckOtuJjpRyYnNho4nuRQamGRUe/mWypyeWgjFRT50SfKOJ4sGLmv3BqEjiS384Kskrj2prCXGIzdXkRs5bKmo8itROqogguElWS3J42b1bDeo6hXcFsJp0hU1NMzx15iSFuvpHan8aKTuiFW2i65nVblHFOczbzUcRfeuOJsUHf46ttHmq40dxKtIHqcufLWgUi9h1Qqo21kjSWgFaQrqklKNRZ7SLOqfhjKhS0mf40CiMZC6OpnPnfMqTYkYSIz2xM5c+MdmdYxCAnzvAAp7RLblph804ik6rMk1r1bQv3eze4pOql8j7LNO1b+KUvoEiZDtsWzwK4vw8kdjp+3pXOptV3wFZngiZXBgD0grkXMIiwSD5oQg3Hl76X0M9MEhLVFHQY1B5oq9kQNTGKhZ8N2+MOEshudXN5OXX82z95GhLAlSlavQvGaWP/zDtCu755+JjSOFWhNqNYyYpjzxlO9vbBmc86isRiKgzf4uaVWemgDcjEwzuO4ssaFReT6Lv/kjWXwWzKXmdtA92EpLqFJJON2bu5tiHDcOg9PXCX8T/84nTNDMqHZUmBGGifZCunwcm9FSt6k7sIK+S9RmRDuv/QqM4aJ5Slmmf9LDKiECdTp/1qPBRsChf+E+O0GiszKOrgu0LGmeqytwM+D7lbYFloO/PhhnWuAH7NpzdVNe7+aFyvKO6fRI4j4QgrhvO6BLrBVRRnlw5fZKqQpNWXhawLa0DlnemWdTX8LEx0USWPiT6RU7mcqWDJtsLom6GZPjfDvDw93FzKGmad49u7PPwemEm/RvfvzT6JAp1JocPfowuU7LFo9EPT7cUC/HxX0z+OA/nlU0L+MA/qXUUBf3ZyPyeWIM2vDwJoGBK2rqBtrdEvII/JYg3oCNQhkf9dsmIuf9QJJXwdZ5FIQbmEtE9p1ExddpSfKe24kp4xz+QRqOOjNutlwDy+36vnV+zlENNOuKlhnChtsgjugt+a+R0eAcrNa/y4D0w+991Jl+soNXyyw8qpDJx+7jmypHVNLWbmIdgiwnWx+gwrOLVoB6m1dW948XJQ/zesMgleoZBbKbWmDD900fhIjiyQTwwpluHYvhTSwPs33JjkhTISKthPnFmJ1r/1K02FBB9AUd/cd+1tMPcmEYbyRsFHGJR005J6P30BWQGNQPTtE3oL97Ob8LDLsCQpPzwlyGBYVXdUrTp+vBSNWLct6ShGKY5zbXHSIBJu+Xs7e6kf2+1QtwWxJfih/vrn4NFTZcxvVVZC1O19vbi4+vS3fnDtL88YC5Mb+8nyjbpdpuoXn48lTwHNDkGWP/XjSvFPSBg0w2EWiLpL9wXaYbnuh5f2wi68eGqhWhzpizFoi99WFr+02bQxP5xVYswsc++FmegtLaRjNw/UxXNOHm2mFSOwAXvaefVCAGhezGKP53BwQSjRoja1FQ9q0SrBvwkRxInTT+4OG2W/sK8Sze7/1zcageWGnOM13V9rIWBTZig1g7yFmCiIzCkzlBx8E4CfFZzcsYWZ2hZ0zID4i5khmPBbfm+rlr3Lg8On+JhxT5XLBInSrWs79sQEFt2tH2UEF+f/+Z8vw8/2ff45Cayml4oi2WF0MilRLxZaYf+0wBtsH/OPB7wj7h8T/y5j4O3IAg+L/8ccR8f/444jA340J/N2IwN+PCfz9iMB/HhP4z0MCv757+kfNwR7Dn2pxrZtOAt4Wt4D64Y6YobPDF+mXvCJ5twxiS5g2BktfPEB7bWrzMxLUrz/3Pl05hoA2HYC1pkqrpKyw25Prv8CMbmnUUxr6ZXPYhVB24n/G4eqJ8swV1w0NLuOb1WXJnsC1v3PpOWXNpm9Y4Ymhgqxk1rPER8gu7ZVT6suS1i4JHJqQKIY5YjLi1k36ShMRv3H5PGQaricJseDyWZM31QOAt00bv8lm14DPHi7uxgdvd6nRCLiZHoGAm+loBHy6PIIEPl0OJ4FvwfY1MI+fS6tz3+rMiopYr+hjcNN9m2J/wCsKLEXj+xCG263UZcvCAV+vw1mYorFczQ716fU4nSqFjM5WzaTLtODiHs117l7TQ9P0ShzlE8JExDM8Gn64uPv79d3mE8Uq9NEE0gK/rPp9Tw2gPL6JlV2myK9vp0091F3czZztmt2DhiETzM2iAw2GvLmfPrytXhl3l5jyAwC5Jeyrm/MXwbxv3Y/F7JTpxVnt2OtY7dj+YtUzwdwV/V6k0CzGOgZfxPGChSR96PIik2ZExGkyj+lB0ZAb4oiR0A1O+LqioGvx5M9mhncE7caqnY+3yERxqII3W75ClBlXlxM2tNJzj+5jd1Yr4vL/+md6dcaNu5OXD73hSNKXSQ9NJCsYuD+2S6DxDRgDajCUv0lFqF6LaKWkkNiFJgA9cRc4anJy2ll5fwPLl6gg8JRvGzHQ+JQjVF8cOM/c1tmzwV+CNkzg3Jeuv+L6N8p4pgYpBRmN0hz0VjRmaqiXcfBSTt6Z0ZeoUdO2knQKIs69Lnzs0xOx+d2LMddCrcyUYqtZ/9xGz8mAsdu+VGeDdP+0euHk6d/I8A9p5+s0dIpw749ppyy+cVp+y1JBJFUcYoUNrL3Iw/Wr3GINzuVcA4rKy6JstFAEcK959Ozs1odRT5hIHwP1b75F6ucpuYdly2p0CAvw7rXaSgQRaPXfiqX43jceC+CLFEnU48aU2o22UjusT7OThIgUlc6ye9MTbd38fRuKUHrkCRSWBNn/4Yz6NeLatsnFJraSmD2xuHDj601nO8guuhbuyoCyNzPsscQ2vsyAkswvArw8RVaDY6qqEnKvT3PeKUKmfTPJlsMMapbUwDNdH3aYkQ/T4cKjbb8o3tJ3DwhGjwTbVVoW3J49ED+GdcWpawXidgvd6qe/4Cv1mL25Fr8pmZT8qYGVotapzK/bMp/yw+aSf9TTq7kAPUW2vgzekPxjwin8v+4uNmD+mJkHOTaf86Zbvq9zA7w/8t+e1Qh7RE77ixG9aHdidnGIf+bc8XHP8gunH69pdVCyDdyrIsE8dvlBOZe9M2IMKO+kMmc8VGGOspHUlQELRd3TQX43JzQ44qlUPU50aGsts5GVwXtl+Kos9mWFUi2NLxF3l/ZDM6CY+7/07OcuGXipZDoG+pBrjBXe/G+xeBuhjb2HNDrKHryLVICPYt22xryTcfO4R95LGs1hh9hNytBH5fjgO0r7BZMx7niWDue9tajX8m201gG0ig97qErFx3yo6v7ywIeq8EWK0LF8n0b4oe2k73b/XY/ketvkWzF2PvvhYJ66hzMqj3LkbeK6e5bv3eN/KNJ8jLNrb/z/18v/2L38Y2ronGqYlSzHKOSEiWq3xJpPWubI5nkHvAlVohXUXu2Q/LNJ9+H14luawJuz+9u3qALuUbhYbwYVcarbebUXrIuyAS335goPZ1ARkwQSqdZFXRNiCF+8PN/Ur7WEnsUgDFuwRtOlIUigVqzqVGdpyhnEhfCLWSfupc/iD4Q50jPBvmRgATh9z79hh92JRNe8cDjypr6ZhsMZdt9SZy2mc0q725DO8ORqFkNqVq3YDu6vLTODeTO7g15/1OSNAhr/vfLurH5bfkuN4tGn88+YfmzHHtprfuEzd1NqRpcgzOw/cj6OxfAlMdM/bsjUXc06sxMSO2G5x8nGfpQLBWD3y5lbPUdt6l7km4vuroqKWCaB6x5UJ/KZNlLR5RFbY3fA9jiITjsb7vnrBrNMQzzD0Nbd35yxeEgdCbcaSjOQ68vwMIx278JYDBN3Gx3wmPVOarNUMP3jph285DY4mSnI76/PNJdmxulykswHhM/pcoklB/6tTXdbFWfNP0MvWmo8yjegEjTyn89u0MDkkeJO9FkrMGNyItP+ruN72p/wZGdpy2f60Z10dr582IUUmYGc36FFc9D52J+GH6L2ePBNyb1Ff+9lU9p8rJysnq1Y6GLsfIny/lSWzYf19I+bE/KBKkYvz90jPYW8KtN0eB76mabOP34hQ2ABuLXvKqj9O10VinFLd0Gb3c4xAZfbD+tdFca8ncqyzeByqWe+Gq8pzUMWICpmiRQbCpRMiZ14p5WFW+vxl5bb0XdcW18yUGx79dkLnZ+jOMnbBCoGGnMZPY4LK58lFFTkbukmfK5DO25rL7X6/OZbubxwlimpKnYJO03hZH2EuFcNmEyPRUfpJIdxHt48qGluXiecaQPKQz2xm4HEllbUkF9OnZ+Xd7PrJ9O1+38ROt3axGVaIzNPKx5OJrqHXEaUv7CTGLSzauwNJKlUVK3dS/qumtIa101ayuWSCWyDn6mRTZUPMnDG4nxukz0onsKdRDJJWHuebTBr7+bYxcqXAMbAoaN//HDbEc6R2/1d0MV8XGiXlzelO8c7AEtGBsaEBmX0CcnSmBrwLzc6Tu6E1A10DLD7CNhf+x0UXm53Qh/40tPU+OpIfpLm9hTro1v/zr0CbC1wONTBNzSjVeWlFWud/c6KbrvdX721LgzXHiyYeVRDsoKJSCY2Xnxz7wZ/W/BE0cWCRS1+ernsHdkVZdrIBFThEIUfW9aFfOnlNP8zeiHWxJfOaig+wZfHzltzJUhmSLbIzCwlsuXBj/7t8MW6RmMs5npRN330L4M1nZSNGDVw6DhcGszkuDn2MTnOoI6Lzs2xDzr0DMcF13jWDkW8CSP3XXB39GiGzLp4CLiEGk4PGt+Ecc58K91+MnbxLMaiAZN1MSywG6IUhFOxzKys3lxe3rzN/ZJdKdvBNRmLsl7vZUd6dnRgxiUpLOkdadjJag9AwVBGPeDf0aKPJYOq0d9RBjva/bFoqG4NO9Kw2+7wChVpx3BzNMtbiUi3FAIez/ocO8ME9AvlU0oJahlFWcpc0m/OBFVrTKEE9zWhNi5pnjW4DJvqPVIokVs/9Br2wKsl316akNgJyYJx2C3rXoJfPzYYHf5BxwWlH+uJK94bNccVKhXK84ZbzWKJj26LEPEWlRohIt7o2papmXMZPQ720mg7ORUy6pn84j6fQ7L56KFUMBLPZz7Qn41RHrNnwUvIFPu3XCLKubNxPgAtTgH8NzcTqmTjBuUBdF2eEzugJpw9Avl8f/1wdU+kIvdXZ5dX9ydDAgexZAIGfhfxikaryuGuyoTnvZvvxFFWP8QtHeBinwATtRNAkc6Z31JmpdPtIddJ/ehaFafWQYPCG38F77HbutswIpmk1LA548yse863e2XlSV1yOad8Fs/zjQXiWX5KutOeuoH067Lx+idOSy69Mahf+W09Ly0AFvcCUsUSu9EWt4fbT238u8xoXarf35I71my5BNgC1JH5UiiMgljaXcyFqwGOKnPEuRk1hhxEetnjwAqboSgPN7+3Ip3TpbtOmsMRyxDS9unDlg6lp9oPPhmRTl88chh9lVPkfaibJfTrcBSWS72qJJVfe6yDd7bYmvTm8XhwF2oZ/f1IZWJgUpl4DaTOafSIV5Vn0YqKJcxcEwo9iRS45aq6ouxDKz7zqYmb2ve/0ASnDs11F+wJfL2ne/YbayE27UydZOEb/IN6rJHJqs3pusiqFHNsT8AzE7F8nrh5Bo1zFgtQYJWnrHW+m1hBhZs/f1jV01v/fFsqeFfu71BtCldDqemDab1wnVDOw3sgfSQvsC+FawDtmjaGiTqK9lxdhC8cotFjls4UGOvfSzHzbR+H3PYfWhpduHnzGo38BDM8Tq+zNJXKMSmVTJhTJk7RiVSAi4MsgJpMAXqL1QPSQmm/12GinMBeRaiwRgua6pU0L8aLyPekxSe7OA/kBVzOztCWkAWL7VkM2G19JwZENFrBbMXMDF3RyTyzq29A2qtXsZo9kXwLG38Pyk3vUG0H2PUam2kYcvnuBvoeIWgwfbh9zJiluE53qCfePerKjU3lhhaWo/vYq/wUZEfxc6xnRs68x5G6GFN/4bM9q6J3TKEuSwB3cB3vL6fleDin30gizQoUEfjYiLceGze6LA0VbTNXMThzVxpfyj7Y5e+uqa5l5vJLrpCxvCNsmc/wkvU1pRwWZiTiFCSUYcBfusSBaUyszmspQkyA6sw9MVqvz8vt9vtZTBlfB/l8V8e6y83h+mC1a8T4WS6MMS8VT98feqc4egQz0eyvlyrBxNg911fn1Lr8hMfWitt5SzO5mMn5fyAyw6+t0rU0N0MLNreKOM9FjdcaO7TP7wmH6p0fpqRx4T2P16xnYUN0N7xHFBY+FZVvv65fjUQPyOVup++97E6IgiVVMQd/EXWdduzDOfbloB5DDfM/rx5quK1yBd1joo2GDXjTbES8d58Gx9tzBDsI5Murm6uHq6FRr7oqKAbB/PvV2eVW+rxJF6QeUxk+TuvasBfKnmqOQ3EWSKZXN1cXD+QjCh3vfltDN7BWOEpmOqJCHPnyTb2eLmyyHos7O9maHYdQr8Bk6rWQH8Acg37Oxlxt1ejSzuX7LSB0pLjfe4rls+CSxi8jGSeWAgMutu227OcVKKi+kutKn/HMeS7jjvvoWfrS5AYE4UFgdLtKj7FZ7Ce7W05wnc9//lpv1DSguv389Wv1jVzXn8L1Pd1Gbm7F0aIDLjAMrX8kUpGfegn7ZUzCfvn6tfp47jEIC/VmC4bdnNYGdjiNObzqLAV1GnQOUz95RiQ8TF2oJHaWLjd3a2OBkS7bUlmU2LoHa4rmkBvefn6gIx+im6OyBDhNtau46WANygoXcsGO8LAoDZ/o0AS/b+3m8aA4rHWZFsdsXTa9bW9d9oKNfe8ybO45ZX8N0fXeqkHoapGA1nQJmqSZ7x/a3TZv+mE6de9v3FMzFBDl+/KUXvaYfpgGXCR2j0Gw+iXUMq5bNHQfFx88LXc5KcP2I2zyyq4Ad8fbr4HbKTEyZdEWaG+lwXIrLHDxb16MB7lgL18HpobV0k6BO3Sa26Hn2IpexHjutCtpv+Hd3bHoQgNQwu5vChsZiNwVLePGcuZjNnRb1irk2lPB68Bq/ClZIAqSSs6irVS/i4bTa/FEOYvPjFFsng31Lt0gVFUeSA7jfE9oDhUz+MwRQE5d37ev1O7bJ5Xf5r8g/2f68db1lY+kUhAZV8qYUNP7UsBGLt5Kb1u+GT66FzCELLFzR/rvIVbsCcSDvORfRqUWoeLxWyK9s9HyitBeZudBejLGpwK7WYvvrSe5Jx3TD9MPUpjVg7ykBqYpCPNpejkI6GhF1dK95eDYXe1HibWj1ovNuxn6YvSIchAxxauyZuUv/7iedaVduu0I4MuBLt+Xo7p8fxzYrdZ3JfP8mNHlTkfYA1yvSVMlv7IEe6gXzxM5WERIcerSzXHuWPkz3haVLJxYL9wYOF0PV3zVsYjKgIpKAj83ljE1G1UpoKiLLEkgZtQA70iJ5LQIaWZPTLOmdzpMqF21CW4DIwvOlquOnEaO7Cio6uwzisET5UXwt6U+WFUaF2nQ152QhXh1XGh5bnW+tgaS592CfHcH7ysQd/tlA2TdbOA8tMzjOGxGPTyEJDXr0PxinFahNfac3V0H9uHDXcytcMddQgMBHYVpIApze/QD/Ub0vB2P3UfDXouZ/jH1NrMybuXeFxvkNaXqUHu/qOSH+eZeVTrKs0Q15nT7iuEpn/Ge8MkN79aY8jc4jvTyxq7AhmdX5YWK/VDlr8Cccxo9riQf6xWN/DmYIlpck8QuUutekXmYnijZ6NHcA/tW3uP3jwg67BQIntA64PwYTB9a+IYj7G3otEwAo4tXa9kuKOdjvEDkr5JCjHt8tSGe3XldXRmmHWkUIYBOjOEBgDFwYtibY83FlN/ArIP09Zrhay4+WTBRmKSYJSC0e5Raaxkx3Nrw4KxQnqaqPqXiIEV9SsXeavqvu9vXvwc/ZEIAn5rhzh1KDwIAMTj8BG/r2Q9YZNmiT8iPhIkYL55qcvnx8y3GoT+V/vjpzv3q/J93/iflT6+mD2fnN9fT368u8Zc/EqaL9mOUc192jWB6EnSO/Etq6IbNdXv6a/5H+RkiqxGeI1sg2rSr7gqp8dpTGc7/DQAA//+uKcsu" + return "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" } diff --git a/x-pack/metricbeat/module/aws/kinesis/_meta/data.json b/x-pack/metricbeat/module/aws/kinesis/_meta/data.json new file mode 100644 index 00000000000..cc8f5592be0 --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/_meta/data.json @@ -0,0 +1,53 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "aws": { + "cloudwatch": { + "namespace": "AWS/Kinesis" + }, + "dimensions": { + "StreamName": "fb-test" + }, + "kinesis": { + "metrics": { + "GetRecords_Bytes": { + "avg": 0 + }, + "GetRecords_IteratorAgeMilliseconds": { + "avg": 0 + }, + "GetRecords_Latency": { + "avg": 9.46 + }, + "GetRecords_Records": { + "sum": 0 + }, + "GetRecords_Success": { + "sum": 150 + }, + "ReadProvisionedThroughputExceeded": { + "avg": 0 + } + } + } + }, + "cloud": { + "account": { + "id": "428152502467", + "name": "elastic-beats" + }, + "provider": "aws", + "region": "us-west-1" + }, + "event": { + "dataset": "aws.kinesis", + "duration": 115000, + "module": "aws" + }, + "metricset": { + "name": "kinesis", + "period": 10000 + }, + "service": { + "type": "aws" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/aws/kinesis/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/kinesis/_meta/docs.asciidoc new file mode 100644 index 00000000000..a994095d707 --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/_meta/docs.asciidoc @@ -0,0 +1,40 @@ +Amazon Kinesis Data Streams sends data points to CloudWatch for +monitoring purpose, such as to track shard usage, monitor incoming bytes and +outgoing bytes. These metrics are automatically collected and pushed to CloudWatch +every minute. There are two different levels of monitoring metrics: + +* *Basic(stream-level)*: Stream-level data is sent automatically every minute at no charge. +* *Enhanced(shard-level)*: Shard-level data is sent every minute for an additional +cost. To get this level of data, you must specifically enable it for the stream +using the https://docs.aws.amazon.com/kinesis/latest/APIReference/API_EnableEnhancedMonitoring.html[EnableEnhancedMonitoring] operation. + +[float] +=== AWS Permissions +Some specific AWS permissions are required for IAM user to collect AWS EBS metrics. +---- +ec2:DescribeRegions +cloudwatch:GetMetricData +cloudwatch:ListMetrics +tag:getResources +sts:GetCallerIdentity +iam:ListAccountAliases +---- + +[float] +=== Dashboard + +The kinesis metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-kinesis-overview.png[] + +[float] +=== Configuration example +[source,yaml] +---- +- module: aws + period: 1m + metricsets: + - kinesis + # This module uses the aws cloudwatch metricset, all + # the options for this metricset are also available here. +---- diff --git a/x-pack/metricbeat/module/aws/kinesis/_meta/fields.yml b/x-pack/metricbeat/module/aws/kinesis/_meta/fields.yml new file mode 100644 index 00000000000..bf75245d33f --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/_meta/fields.yml @@ -0,0 +1,110 @@ +- name: kinesis + type: group + description: > + `kinesis` contains the metrics that were scraped from AWS CloudWatch which contains monitoring metrics sent by Amazon Kinesis. + release: beta + fields: + - name: metrics + type: group + fields: + - name: GetRecords_Bytes.avg + type: double + description: > + The average number of bytes retrieved from the Kinesis stream, measured over the specified time period. + - name: GetRecords_IteratorAgeMilliseconds.avg + type: double + description: > + The age of the last record in all GetRecords calls made against a Kinesis stream, measured over the specified time period. + Age is the difference between the current time and when the last record of the GetRecords call was written to the stream. + - name: GetRecords_Latency.avg + type: double + description: > + The time taken per GetRecords operation, measured over the specified time period. + - name: GetRecords_Records.sum + type: long + description: > + The number of records retrieved from the shard, measured over the specified time period. + - name: GetRecords_Success.sum + type: long + description: > + The number of successful GetRecords operations per stream, measured over the specified time period. + - name: IncomingBytes.avg + type: double + description: > + The number of bytes successfully put to the Kinesis stream over the specified time period. This metric includes bytes from PutRecord and PutRecords operations. + - name: IncomingRecords.avg + type: double + description: > + The number of records successfully put to the Kinesis stream over the specified time period. This metric includes record counts from PutRecord and PutRecords operations. + - name: PutRecord_Bytes.avg + type: double + description: > + The number of bytes put to the Kinesis stream using the PutRecord operation over the specified time period. + - name: PutRecord_Latency.avg + type: double + description: > + The time taken per PutRecord operation, measured over the specified time period. + - name: PutRecord_Success.avg + type: double + description: > + The percentage of successful writes to a Kinesis stream, measured over the specified time period. + - name: PutRecords_Bytes.avg + type: double + description: > + The average number of bytes put to the Kinesis stream using the PutRecords operation over the specified time period. + - name: PutRecords_Latency.avg + type: double + description: > + The average time taken per PutRecords operation, measured over the specified time period. + - name: PutRecords_Success.avg + type: long + description: > + The total number of PutRecords operations where at least one record succeeded, per Kinesis stream, measured over the specified time period. + - name: PutRecords_TotalRecords.sum + type: long + description: > + The total number of records sent in a PutRecords operation per Kinesis data stream, measured over the specified time period. + - name: PutRecords_SuccessfulRecords.sum + type: long + description: > + The number of successful records in a PutRecords operation per Kinesis data stream, measured over the specified time period. + - name: PutRecords_FailedRecords.sum + type: long + description: > + The number of records rejected due to internal failures in a PutRecords operation per Kinesis data stream, measured over the specified time period. + - name: PutRecords_ThrottledRecords.sum + type: long + description: > + The number of records rejected due to throttling in a PutRecords operation per Kinesis data stream, measured over the specified time period. + - name: ReadProvisionedThroughputExceeded.avg + type: long + description: > + The number of GetRecords calls throttled for the stream over the specified time period. + - name: SubscribeToShard_RateExceeded.avg + type: long + description: > + This metric is emitted when a new subscription attempt fails because there already is an active subscription by the same consumer or if you exceed the number of calls per second allowed for this operation. + - name: SubscribeToShard_Success.avg + type: long + description: > + This metric records whether the SubscribeToShard subscription was successfully established. + - name: SubscribeToShardEvent_Bytes.avg + type: long + description: > + The number of bytes received from the shard, measured over the specified time period. + - name: SubscribeToShardEvent_MillisBehindLatest.avg + type: long + description: > + The difference between the current time and when the last record of the SubscribeToShard event was written to the stream. + - name: SubscribeToShardEvent_Records.sum + type: long + description: > + The number of records received from the shard, measured over the specified time period. + - name: SubscribeToShardEvent_Success.avg + type: long + description: > + This metric is emitted every time an event is published successfully. It is only emitted when there's an active subscription. + - name: WriteProvisionedThroughputExceeded.avg + type: long + description: > + The number of records rejected due to throttling for the stream over the specified time period. This metric includes throttling from PutRecord and PutRecords operations. diff --git a/x-pack/metricbeat/module/aws/kinesis/kinesis_integration_test.go b/x-pack/metricbeat/module/aws/kinesis/kinesis_integration_test.go new file mode 100644 index 00000000000..6b69f4791d8 --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/kinesis_integration_test.go @@ -0,0 +1,38 @@ +// 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. + +// +build integration +// +build aws + +package kinesis + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + _ "github.com/elastic/beats/v7/libbeat/processors/actions" + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/mtest" +) + +func TestFetch(t *testing.T) { + config := mtest.GetConfigForTest(t, "kinesis", "60s") + + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} + +func TestData(t *testing.T) { + config := mtest.GetConfigForTest(t, "kinesis", "60s") + + metricSet := mbtest.NewFetcher(t, config) + metricSet.WriteEvents(t, "/") +} diff --git a/x-pack/metricbeat/module/aws/kinesis/kinesis_test.go b/x-pack/metricbeat/module/aws/kinesis/kinesis_test.go new file mode 100644 index 00000000000..652ada02a72 --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/kinesis_test.go @@ -0,0 +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 kinesis + +import ( + "os" + + "github.com/elastic/beats/v7/metricbeat/mb" + + // Register input module and metricset + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/cloudwatch" +) + +func init() { + // To be moved to some kind of helper + os.Setenv("BEAT_STRICT_PERMS", "false") + mb.Registry.SetSecondarySource(mb.NewLightModulesSource("../../../module")) +} diff --git a/x-pack/metricbeat/module/aws/kinesis/manifest.yml b/x-pack/metricbeat/module/aws/kinesis/manifest.yml new file mode 100644 index 00000000000..3a0dad52772 --- /dev/null +++ b/x-pack/metricbeat/module/aws/kinesis/manifest.yml @@ -0,0 +1,50 @@ +default: true +input: + module: aws + metricset: cloudwatch + defaults: + metrics: + - namespace: AWS/Kinesis + resource_type: kinesis + statistic: ["Average"] + name: + - GetRecords.Bytes + - GetRecords.IteratorAgeMilliseconds + - GetRecords.Latency + - IncomingBytes + - IncomingRecords + - PutRecord.Bytes + - PutRecord.Latency + - PutRecord.Success + - PutRecords.Bytes + - PutRecords.Latency + - PutRecords.Success + - ReadProvisionedThroughputExceeded + - SubscribeToShard.RateExceeded + - SubscribeToShard.Success + - SubscribeToShardEvent.Bytes + - SubscribeToShardEvent.MillisBehindLatest + - SubscribeToShardEvent.Success + - WriteProvisionedThroughputExceeded + - OutgoingBytes + - IteratorAgeMilliseconds + - namespace: AWS/Kinesis + resource_type: kinesis + statistic: ["Sum"] + name: + - GetRecords.Records + - GetRecords.Success + - PutRecords.TotalRecords + - PutRecords.SuccessfulRecords + - PutRecords.FailedRecords + - PutRecords.ThrottledRecords + - SubscribeToShardEvent.Records + - OutgoingRecords + + + + + + + + diff --git a/x-pack/metricbeat/module/aws/module.yml b/x-pack/metricbeat/module/aws/module.yml index 1f68157f87b..099599a2e66 100644 --- a/x-pack/metricbeat/module/aws/module.yml +++ b/x-pack/metricbeat/module/aws/module.yml @@ -14,3 +14,4 @@ metricsets: - vpn - transitgateway - natgateway + - kinesis diff --git a/x-pack/metricbeat/module/aws/natgateway/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/natgateway/_meta/docs.asciidoc index 5036de308b3..ce9b294b11c 100644 --- a/x-pack/metricbeat/module/aws/natgateway/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/natgateway/_meta/docs.asciidoc @@ -16,6 +16,13 @@ sts:GetCallerIdentity iam:ListAccountAliases ---- +[float] +=== Dashboard + +The aws natgateway metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-natgateway-overview.png[] + [float] === Configuration example [source,yaml] diff --git a/x-pack/metricbeat/module/aws/transitgateway/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/transitgateway/_meta/docs.asciidoc index 02a87e8a134..9e18ee339da 100644 --- a/x-pack/metricbeat/module/aws/transitgateway/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/transitgateway/_meta/docs.asciidoc @@ -17,6 +17,13 @@ sts:GetCallerIdentity iam:ListAccountAliases ---- +[float] +=== Dashboard + +The aws transitgateway metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-transitgateway-overview.png[] + [float] === Configuration example [source,yaml] diff --git a/x-pack/metricbeat/module/aws/vpn/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/vpn/_meta/docs.asciidoc index 7c83c8ebe71..02307ba21b4 100644 --- a/x-pack/metricbeat/module/aws/vpn/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/vpn/_meta/docs.asciidoc @@ -15,6 +15,13 @@ sts:GetCallerIdentity iam:ListAccountAliases ---- +[float] +=== Dashboard + +The aws vpn metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-vpn-overview.png[] + [float] === Configuration example [source,yaml] diff --git a/x-pack/metricbeat/modules.d/aws.yml.disabled b/x-pack/metricbeat/modules.d/aws.yml.disabled index a4453b2ffeb..d36b81571e2 100644 --- a/x-pack/metricbeat/modules.d/aws.yml.disabled +++ b/x-pack/metricbeat/modules.d/aws.yml.disabled @@ -5,6 +5,7 @@ period: 1m metricsets: - elb + - kinesis - natgateway - rds - transitgateway From 7b665979d36c69894a6290043c3a664436f30cd1 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 29 Jun 2021 18:16:08 -0400 Subject: [PATCH 19/25] Add Fleet agent.id to Agent monitoring data (#26548) This is a follow up to #26394 which set the agent.id field to the Fleet agent ID for for integrations that are run by Agent, but that didn't cover the Filebeat and Metricbeat processes that are executed by Agent for monitoring itself. This covers those processes. Relates #26394 --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 2 +- .../pkg/agent/operation/monitoring.go | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index ffd8febf29c..3afc0034a88 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -114,7 +114,7 @@ - Log output of container to $LOGS_PATH/elastic-agent-start.log when LOGS_PATH set {pull}25150[25150] - Use `filestream` input for internal log collection. {pull}25660[25660] - Enable agent to send custom headers to kibana/ES {pull}26275[26275] -- Set `agent.id` to the Fleet Agent ID in events published from inputs backed by Beats. {issue}21121[21121] {pull}26394[26394] +- Set `agent.id` to the Fleet Agent ID in events published from inputs backed by Beats. {issue}21121[21121] {pull}26394[26394] {pull}26548[26548] - Add proxy support to artifact downloader and communication with fleet server. {pull}25219[25219] - Enable configuring monitoring namespace {issue}26439[26439] - Communicate with Fleet Server over HTTP2. {pull}26474[26474] diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go index 17188321b56..4712759ab70 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go @@ -339,6 +339,16 @@ func (o *Operator) getMonitoringFilebeatConfig(outputType string, output interfa "output": map[string]interface{}{ outputType: output, }, + "processors": []map[string]interface{}{ + { + "add_fields": map[string]interface{}{ + "target": "agent", + "fields": map[string]interface{}{ + "id": o.agentInfo.AgentID(), + }, + }, + }, + }, } o.logger.Debugf("monitoring configuration generated for filebeat: %v", result) @@ -563,6 +573,16 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter "output": map[string]interface{}{ outputType: output, }, + "processors": []map[string]interface{}{ + { + "add_fields": map[string]interface{}{ + "target": "agent", + "fields": map[string]interface{}{ + "id": o.agentInfo.AgentID(), + }, + }, + }, + }, } o.logger.Debugf("monitoring configuration generated for metricbeat: %v", result) From 60355b5216ddadf93e7a8846483c6bc38fe1e4da Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 29 Jun 2021 15:36:49 -0700 Subject: [PATCH 20/25] API keys do not reflect the need for read_pipeline (#26466) (#26582) As discussed in the PR https://github.com/elastic/beats/pull/26465 the docs should reflect that read_pipeline is needed when using modules. Users usually just copy and paste the JSON payload and might experience failures when running any beat with modules. Co-authored-by: Philipp Kahr --- libbeat/docs/security/api-keys.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbeat/docs/security/api-keys.asciidoc b/libbeat/docs/security/api-keys.asciidoc index aa397ff5fee..1a934b67ce8 100644 --- a/libbeat/docs/security/api-keys.asciidoc +++ b/libbeat/docs/security/api-keys.asciidoc @@ -29,7 +29,7 @@ POST /_security/api_key "name": "{beat_default_index_prefix}_host001", <1> "role_descriptors": { "{beat_default_index_prefix}_writer": { <2> - "cluster": ["monitor", "read_ilm"], + "cluster": ["monitor", "read_ilm", "read_pipeline"], "index": [ { "names": ["{beat_default_index_prefix}-*"], From f364c0700cb92de3a9b43d893c19da0da2022446 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 29 Jun 2021 15:37:23 -0700 Subject: [PATCH 21/25] Update to "read_pipeline" permission (#26465) (#26580) I don't know in what version this was updated to be called "read_pipeline". but it is available through the roles settings in Kibana. Co-authored-by: Philipp Kahr --- libbeat/docs/security/users.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbeat/docs/security/users.asciidoc b/libbeat/docs/security/users.asciidoc index 45ccc48710a..0e2d11bcc34 100644 --- a/libbeat/docs/security/users.asciidoc +++ b/libbeat/docs/security/users.asciidoc @@ -266,7 +266,7 @@ endif::no_ilm[] ifeval::["{beatname_lc}"=="filebeat"] |Cluster -|`cluster:admin/ingest/pipeline/get` +|`read_pipeline` |Check for ingest pipelines used by modules. Needed when using modules. endif::[] From 8ca57d309f1cabe95c08a29dd5a4c682a999fec5 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Tue, 29 Jun 2021 19:23:57 -0500 Subject: [PATCH 22/25] [Heartbeat] Skip flakey timer queue test (#26592) Apparently this is causing flakey builds on all platforms now --- heartbeat/scheduler/timerqueue/queue_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/heartbeat/scheduler/timerqueue/queue_test.go b/heartbeat/scheduler/timerqueue/queue_test.go index ee1794ef59a..2e5a2e59eb8 100644 --- a/heartbeat/scheduler/timerqueue/queue_test.go +++ b/heartbeat/scheduler/timerqueue/queue_test.go @@ -20,7 +20,6 @@ package timerqueue import ( "context" "math/rand" - "runtime" "sort" "testing" "time" @@ -29,9 +28,7 @@ import ( ) func TestQueueRunsInOrder(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("flaky test on windows: https://github.com/elastic/beats/issues/26205") - } + t.Skip("flaky test on windows: https://github.com/elastic/beats/issues/26205") // Bugs can show up only occasionally for i := 0; i < 100; i++ { testQueueRunsInOrderOnce(t) From ef283a839af20a5f36a19c2124549383ece29723 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Wed, 30 Jun 2021 09:29:47 +0100 Subject: [PATCH 23/25] Packaging: add arm7 platform in the main pipeline (#26575) --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 527bcbecb55..2e4dc51d510 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -353,9 +353,9 @@ def packagingLinux(Map args = [:]) { 'linux/amd64', 'linux/386', 'linux/arm64', + 'linux/armv7', // The platforms above are disabled temporarly as crossbuild images are // not available. See: https://github.com/elastic/golang-crossbuild/issues/71 - //'linux/armv7', //'linux/ppc64le', //'linux/mips64', //'linux/s390x', From 1541b2e659f20ed0360bc8cb94c5f381edee3076 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Wed, 30 Jun 2021 09:31:58 +0100 Subject: [PATCH 24/25] macos for metricbeat to run in the extended meta-stage (#26573) --- metricbeat/Jenkinsfile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/metricbeat/Jenkinsfile.yml b/metricbeat/Jenkinsfile.yml index 57f18ff81d2..bbb1986cb47 100644 --- a/metricbeat/Jenkinsfile.yml +++ b/metricbeat/Jenkinsfile.yml @@ -48,6 +48,7 @@ stages: - "macosTest" branches: true ## for all the branches tags: true ## for all the tags + stage: extended windows: mage: "mage build unitTest" platforms: ## override default labels in this specific stage. From 5488dcf334c5ecd9342969ff69df9fea916c7d76 Mon Sep 17 00:00:00 2001 From: Ivan Fernandez Calvo Date: Wed, 30 Jun 2021 10:41:05 +0200 Subject: [PATCH 25/25] fix: Force PLATFORMS environment variable when we build Elastic Agent dependencies on arm64 (#26415) * fix: build elastic agent dependencies on the architecture you are running * fix: format * fix: build ARM on ARM * fix: format * chore: backup the platforms env var --- x-pack/elastic-agent/magefile.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x-pack/elastic-agent/magefile.go b/x-pack/elastic-agent/magefile.go index 5d7de29af97..bacd468b44d 100644 --- a/x-pack/elastic-agent/magefile.go +++ b/x-pack/elastic-agent/magefile.go @@ -579,6 +579,16 @@ func packageAgent(requiredPackages []string, packagingFn func()) { } os.Setenv(agentDropPath, dropPath) + if runtime.GOARCH == "arm64" { + const platformsVar = "PLATFORMS" + oldPlatforms := os.Getenv(platformsVar) + os.Setenv(platformsVar, runtime.GOOS+"/"+runtime.GOARCH) + if oldPlatforms != "" { + defer os.Setenv(platformsVar, oldPlatforms) + } else { + defer os.Unsetenv(oldPlatforms) + } + } // cleanup after build defer os.RemoveAll(dropPath)