Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds timestamp field alias and sets time range filter in bucket level monitor #262

Merged
merged 6 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@
*/
package org.opensearch.securityanalytics.transport;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -41,6 +29,8 @@
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.client.Client;
import org.opensearch.client.node.NodeClient;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.metadata.MappingMetadata;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.common.inject.Inject;
import org.opensearch.common.io.stream.NamedWriteableRegistry;
Expand All @@ -59,6 +49,7 @@
import org.opensearch.commons.alerting.action.IndexMonitorRequest;
import org.opensearch.commons.alerting.action.IndexMonitorResponse;
import org.opensearch.commons.alerting.model.BucketLevelTrigger;
import org.opensearch.commons.alerting.model.CronSchedule;
import org.opensearch.commons.alerting.model.DataSources;
import org.opensearch.commons.alerting.model.DocLevelMonitorInput;
import org.opensearch.commons.alerting.model.DocLevelQuery;
Expand All @@ -69,8 +60,10 @@
import org.opensearch.commons.alerting.model.action.Action;
import org.opensearch.commons.authuser.User;
import org.opensearch.index.IndexNotFoundException;
import org.opensearch.index.query.BoolQueryBuilder;
import org.opensearch.index.query.QueryBuilder;
import org.opensearch.index.query.QueryBuilders;
import org.opensearch.index.query.RangeQueryBuilder;
import org.opensearch.index.reindex.BulkByScrollResponse;
import org.opensearch.index.seqno.SequenceNumbers;
import org.opensearch.rest.RestRequest;
Expand All @@ -80,11 +73,15 @@
import org.opensearch.search.SearchHit;
import org.opensearch.search.SearchHits;
import org.opensearch.search.builder.SearchSourceBuilder;
import org.opensearch.securityanalytics.action.GetIndexMappingsAction;
import org.opensearch.securityanalytics.action.GetIndexMappingsRequest;
import org.opensearch.securityanalytics.action.GetIndexMappingsResponse;
import org.opensearch.securityanalytics.action.IndexDetectorAction;
import org.opensearch.securityanalytics.action.IndexDetectorRequest;
import org.opensearch.securityanalytics.action.IndexDetectorResponse;
import org.opensearch.securityanalytics.config.monitors.DetectorMonitorConfig;
import org.opensearch.securityanalytics.mapper.MapperService;
import org.opensearch.securityanalytics.mapper.MapperUtils;
import org.opensearch.securityanalytics.model.Detector;
import org.opensearch.securityanalytics.model.DetectorInput;
import org.opensearch.securityanalytics.model.DetectorRule;
Expand All @@ -105,10 +102,24 @@
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

public class TransportIndexDetectorAction extends HandledTransportAction<IndexDetectorRequest, IndexDetectorResponse> implements SecureTransportAction {

public static final String PLUGIN_OWNER_FIELD = "security_analytics";
private static final Logger log = LogManager.getLogger(TransportIndexDetectorAction.class);
public static final String TIMESTAMP_FIELD_ALIAS = "timestamp";

private final Client client;

Expand All @@ -133,6 +144,8 @@ public class TransportIndexDetectorAction extends HandledTransportAction<IndexDe

private final NamedWriteableRegistry namedWriteableRegistry;

private final IndexNameExpressionResolver indexNameExpressionResolver;

private volatile TimeValue indexTimeout;
@Inject
public TransportIndexDetectorAction(TransportService transportService,
Expand All @@ -145,7 +158,8 @@ public TransportIndexDetectorAction(TransportService transportService,
MapperService mapperService,
ClusterService clusterService,
Settings settings,
NamedWriteableRegistry namedWriteableRegistry) {
NamedWriteableRegistry namedWriteableRegistry,
IndexNameExpressionResolver indexNameExpressionResolver) {
super(IndexDetectorAction.NAME, transportService, actionFilters, IndexDetectorRequest::new);
this.client = client;
this.xContentRegistry = xContentRegistry;
Expand All @@ -156,6 +170,7 @@ public TransportIndexDetectorAction(TransportService transportService,
this.clusterService = clusterService;
this.settings = settings;
this.namedWriteableRegistry = namedWriteableRegistry;
this.indexNameExpressionResolver = indexNameExpressionResolver;
this.threadPool = this.detectorIndices.getThreadPool();
this.indexTimeout = SecurityAnalyticsSettings.INDEX_TIMEOUT.get(this.settings);
this.filterByEnabled = SecurityAnalyticsSettings.FILTER_BY_BACKEND_ROLES.get(this.settings);
Expand Down Expand Up @@ -477,6 +492,39 @@ private IndexMonitorRequest createBucketLevelMonitorRequest(
// Build query string filter
.query(QueryBuilders.queryStringQuery(rule.getQueries().get(0).getValue()))
.aggregation(aggregationQueries.getAggBuilder());
String concreteIndex = IndexUtils.getNewIndexByCreationDate( // index variable in method signature can also be an index pattern
clusterService.state(),
indexNameExpressionResolver,
index
);
try {
GetIndexMappingsResponse getIndexMappingsResponse = client.execute(
GetIndexMappingsAction.INSTANCE,
new GetIndexMappingsRequest(concreteIndex))
.actionGet();
MappingMetadata mappingMetadata = getIndexMappingsResponse.mappings().get(concreteIndex);
List<Pair<String, String>> pairs = MapperUtils.getAllAliasPathPairs(mappingMetadata);
boolean timeStampAliasPresent = pairs.
stream()
.anyMatch(p ->
TIMESTAMP_FIELD_ALIAS.equals(p.getLeft()) || TIMESTAMP_FIELD_ALIAS.equals(p.getRight()));
if(timeStampAliasPresent) {
BoolQueryBuilder boolQueryBuilder = searchSourceBuilder.query() == null
? new BoolQueryBuilder()
: QueryBuilders.boolQuery().must(searchSourceBuilder.query());
RangeQueryBuilder timeRangeFilter = QueryBuilders.rangeQuery(TIMESTAMP_FIELD_ALIAS)
.gt("{{period_end}}||-1h")
.lte("{{period_end}}")
.format("epoch_millis");
boolQueryBuilder.must(timeRangeFilter);
searchSourceBuilder.query(boolQueryBuilder);
}
} catch (Exception e) {
log.error(
String.format(Locale.getDefault(),
"Unable to verify presence of timestamp alias for index [%s] in detector [%s]. Not setting time range filter for bucket level monitor.",
concreteIndex, detector.getName()), e);
}

List<SearchInput> bucketLevelMonitorInputs = new ArrayList<>();
bucketLevelMonitorInputs.add(new SearchInput(Arrays.asList(index), searchSourceBuilder));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import java.util.SortedMap;
import org.opensearch.action.ActionListener;
import org.opensearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.opensearch.action.support.IndicesOptions;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.client.IndicesAdminClient;
import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.metadata.IndexAbstraction;
import org.opensearch.cluster.metadata.IndexMetadata;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.common.xcontent.LoggingDeprecationHandler;
import org.opensearch.common.xcontent.NamedXContentRegistry;
import org.opensearch.common.xcontent.XContentParser;
Expand Down Expand Up @@ -154,4 +156,10 @@ public static String getNewestIndexByCreationDate(String[] concreteIndices, Clus
}
return newestIndex;
}

public static String getNewIndexByCreationDate(ClusterState state, IndexNameExpressionResolver i, String index) {
String[] strings = i.concreteIndexNames(state, IndicesOptions.LENIENT_EXPAND_OPEN, index);
return getNewestIndexByCreationDate(strings, state);
}

}
1 change: 1 addition & 0 deletions src/main/resources/OSMapping/ad_ldap/fieldmappings.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
fieldmappings:
TargetUserName: winlog-event_data-TargetUserName
creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/ad_ldap/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"winlog-event_data-TargetUserName": {
"path": "winlog.event_data.TargetUserName",
"type": "alias"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ fieldmappings:
fieldB: mappedB
fieldA1: mappedA
CommandLine: windows-event_data-CommandLine
creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/apache_access/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"event_uid": {
"type": "alias",
"path": "EventID"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
3 changes: 2 additions & 1 deletion src/main/resources/OSMapping/cloudtrail/fieldmappings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ fieldmappings:
requestParameters.containerDefinitions.command: aws-cloudtrail-requestParameters-containerDefinitions-command
userIdentity.sessionContext.sessionIssuer.type: userIdentity-sessionContext-sessionIssuer-type
userIdentity.type: aws-cloudtrail-userIdentity-type
userIdentity.arn: aws-cloudtrail-userIdentity-arn
userIdentity.arn: aws-cloudtrail-userIdentity-arn
eventTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/cloudtrail/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
"userIdentity-sessionContext-sessionIssuer-type": {
"type": "alias",
"path": "aws.cloudtrail.userIdentity.sessionContext.sessionIssuer.type"
},
"timestamp": {
"path": "aws.cloudtrail.eventTime",
"type": "alias"
}
}
}
3 changes: 2 additions & 1 deletion src/main/resources/OSMapping/dns/fieldmappings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
fieldmappings:
record_type: dns-answers-type
query: dns-question-name
parent_domain: dns-question-registered_domain
parent_domain: dns-question-registered_domain
creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/dns/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"dns-question-registered_domain": {
"type": "alias",
"path": "dns.question.registered_domain"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
2 changes: 1 addition & 1 deletion src/main/resources/OSMapping/linux/fieldmappings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ fieldmappings:
ParentImage: process-parent-executable
CurrentDirectory: process-working_directory
LogonId: process-real_user-id

creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/linux/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
"process-real_user-id": {
"path": "process.real_user.id",
"type": "alias"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/network/NetFlowMapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"http.response.status_code": {
"type": "alias",
"path": "netflow.http_status_code"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
3 changes: 2 additions & 1 deletion src/main/resources/OSMapping/network/fieldmappings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ fieldmappings:
client_header_names: zeek-http-client_header_names
resp_mime_types: zeek-http-resp_mime_types
cipher: zeek-kerberos-cipher
request_type: zeek-kerberos-request_type
request_type: zeek-kerberos-request_type
creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/network/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
"zeek-kerberos-request_type": {
"path": "zeek.kerberos.request_type",
"type": "alias"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ fieldmappings:
HiveName: unmapped.HiveName
fieldB: mappedB
fieldA1: mappedA

creationTime: timestamp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"windows-servicename": {
"type": "alias",
"path": "ServiceName"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ fieldmappings:
HiveName: unmapped.HiveName
fieldB: mappedB
fieldA1: mappedA

creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/others_apt/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"windows-servicename": {
"type": "alias",
"path": "ServiceName"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ fieldmappings:
HiveName: unmapped.HiveName
fieldB: mappedB
fieldA1: mappedA

creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/others_cloud/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"windows-servicename": {
"type": "alias",
"path": "ServiceName"
},
"creationTime": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ fieldmappings:
HiveName: unmapped.HiveName
fieldB: mappedB
fieldA1: mappedA

creationTime: timestamp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"windows-servicename": {
"type": "alias",
"path": "ServiceName"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ fieldmappings:
HiveName: unmapped.HiveName
fieldB: mappedB
fieldA1: mappedA
creationTime: timestamp
4 changes: 4 additions & 0 deletions src/main/resources/OSMapping/others_macos/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"macos.event_data.CommandLine": {
"type": "alias",
"path": "CommandLine"
},
"timestamp": {
"path": "creationTime",
"type": "alias"
}
}
}
Loading