-
Notifications
You must be signed in to change notification settings - Fork 8.1k
/
fleet_es_assets.ts
209 lines (185 loc) · 6.38 KB
/
fleet_es_assets.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { getFileDataIndexName, getFileMetadataIndexName } from '../../common';
import { getESAssetMetadata } from '../services/epm/elasticsearch/meta';
const meta = getESAssetMetadata();
export const FLEET_INSTALL_FORMAT_VERSION = '1.0.0';
export const FLEET_AGENT_POLICIES_SCHEMA_VERSION = '1.1.1';
export const FLEET_FINAL_PIPELINE_ID = '.fleet_final_pipeline-1';
export const FLEET_GLOBALS_COMPONENT_TEMPLATE_NAME = '.fleet_globals-1';
export const FLEET_GLOBALS_COMPONENT_TEMPLATE_CONTENT = {
_meta: meta,
template: {
settings: {},
mappings: {
_meta: meta,
// All the dynamic field mappings
dynamic_templates: [
// This makes sure all mappings are keywords by default
{
strings_as_keyword: {
mapping: {
ignore_above: 1024,
type: 'keyword',
},
match_mapping_type: 'string',
},
},
],
// As we define fields ahead, we don't need any automatic field detection
// This makes sure all the fields are mapped to keyword by default to prevent mapping conflicts
date_detection: false,
},
},
};
export const FLEET_AGENT_ID_VERIFY_COMPONENT_TEMPLATE_NAME = '.fleet_agent_id_verification-1';
export const FLEET_AGENT_ID_VERIFY_COMPONENT_TEMPLATE_CONTENT = {
_meta: meta,
template: {
settings: {
index: {
final_pipeline: FLEET_FINAL_PIPELINE_ID,
},
},
mappings: {
properties: {
event: {
properties: {
ingested: {
type: 'date',
format: 'strict_date_time_no_millis||strict_date_optional_time||epoch_millis',
},
agent_id_status: {
ignore_above: 1024,
type: 'keyword',
},
},
},
},
},
},
};
export const FLEET_COMPONENT_TEMPLATES = [
{ name: FLEET_GLOBALS_COMPONENT_TEMPLATE_NAME, body: FLEET_GLOBALS_COMPONENT_TEMPLATE_CONTENT },
{
name: FLEET_AGENT_ID_VERIFY_COMPONENT_TEMPLATE_NAME,
body: FLEET_AGENT_ID_VERIFY_COMPONENT_TEMPLATE_CONTENT,
},
];
export const FLEET_FINAL_PIPELINE_VERSION = 4;
// If the content is updated you probably need to update the FLEET_FINAL_PIPELINE_VERSION too to allow upgrade of the pipeline
export const FLEET_FINAL_PIPELINE_CONTENT = `---
version: ${FLEET_FINAL_PIPELINE_VERSION}
_meta:
managed_by: ${meta.managed_by}
managed: ${meta.managed}
description: >
Final pipeline for processing all incoming Fleet Agent documents.
processors:
- script:
description: Add time when event was ingested (and remove sub-seconds to improve storage efficiency)
tag: truncate-subseconds-event-ingested
ignore_failure: true
source: |-
if (ctx?.event == null) {
ctx.event = [:];
}
ctx.event.ingested = metadata().now.withNano(0).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
- remove:
description: Remove any pre-existing untrusted values.
field:
- event.agent_id_status
- _security
ignore_missing: true
- remove:
description: Remove event.original unless the preserve_original_event tag is set
field: event.original
if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))"
ignore_failure: true
ignore_missing: true
- set_security_user:
field: _security
properties:
- authentication_type
- username
- realm
- api_key
- script:
description: >
Add event.agent_id_status based on the API key metadata and the
agent.id contained in the event.
tag: agent-id-status
source: |-
boolean is_user_trusted(def ctx, def users) {
if (ctx?._security?.username == null) {
return false;
}
def user = null;
for (def item : users) {
if (item?.username == ctx._security.username) {
user = item;
break;
}
}
if (user == null || user?.realm == null || ctx?._security?.realm?.name == null) {
return false;
}
if (ctx._security.realm.name != user.realm) {
return false;
}
return true;
}
String verified(def ctx, def params) {
// No agent.id field to validate.
if (ctx?.agent?.id == null) {
return "missing";
}
// Check auth metadata from API key.
if (ctx?._security?.authentication_type == null
// Agents only use API keys.
|| ctx._security.authentication_type != 'API_KEY'
// Verify the API key owner before trusting any metadata it contains.
|| !is_user_trusted(ctx, params.trusted_users)
// Verify the API key has metadata indicating the assigned agent ID.
|| ctx?._security?.api_key?.metadata?.agent_id == null) {
return "auth_metadata_missing";
}
// The API key can only be used represent the agent.id it was issued to.
if (ctx._security.api_key.metadata.agent_id != ctx.agent.id) {
// Potential masquerade attempt.
return "mismatch";
}
return "verified";
}
if (ctx?.event == null) {
ctx.event = [:];
}
ctx.event.agent_id_status = verified(ctx, params);
params:
# List of users responsible for creating Fleet output API keys.
trusted_users:
- username: elastic/fleet-server
realm: _service_account
- username: cloud-internal-agent-server
realm: found
- username: elastic
realm: reserved
- remove:
field: _security
ignore_missing: true
on_failure:
- remove:
field: _security
ignore_missing: true
ignore_failure: true
- append:
field: error.message
value:
- 'failed in Fleet agent final_pipeline: {{ _ingest.on_failure_message }}'`;
// Fleet Agent indexes for storing files
export const FILE_STORAGE_METADATA_AGENT_INDEX = getFileMetadataIndexName('agent');
export const FILE_STORAGE_DATA_AGENT_INDEX = getFileDataIndexName('agent');