Skip to content

Commit

Permalink
rules: analytics generic ES search endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
sonicold authored and regit committed Jun 19, 2023
1 parent f7f1638 commit c5b755a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
48 changes: 48 additions & 0 deletions rules/es_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,51 @@ def _get_query(self) -> dict:
}
}
return q


class ESGenericSearch(ESQuery):
'''
=============================================================================================================================================================
==== POST ====\n
Post ES query:\n
curl -k https://myssp2/rest/rules/es/search/ -H "Authorization: Token d16206ca40ce0cbbf3080eb1e662b17c5452d96f" -H 'Content-Type: application/json' -X POST -d '{"index":"logstash-tls-*", "size":0, qfilter":"(event_type: tls AND (proto: UDP OR proto: TCP))", "aggs":"{'aggs': {'1': {'terms': {'field': 'tls.cipher_suite.keyword', 'order': {'_count': 'desc'}, 'size': 5}}}}"}'
=============================================================================================================================================================
'''
def __init__(self, request, index, qfilter, size, aggs=None, time_filter='@timestamp', *args, **kwargs):
self.index = index
self.qfilter_ = qfilter
self.aggs = aggs
self.size = size
self.time_filter = time_filter
super().__init__(request, *args, **kwargs)

def _get_index(self) -> str:
return self.index

def _get_query(self) -> dict:
q = {
'query': {
'bool': {
'must': [{
'query_string': {
'analyze_wildcard': True,
'query': self.qfilter_
}
}, {
'range': {
self.time_filter: {
'from': self._from_date(),
'to': self._to_date()
}
}
}]
}
},
'size': self.size
}

if self.aggs:
q.update({'aggs': self.aggs.get('aggs', {})})

return q
26 changes: 25 additions & 1 deletion rules/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from rules.es_graphs import ESSigsListHits, ESTopRules, ESError, ESDeleteAlertsBySid, ESEventsFromFlowID, ESFieldsStats

from rules.es_analytics import ESGetUniqueFields
from rules.es_analytics import ESGraphAgg, ESFieldUniqAgg
from rules.es_analytics import ESGraphAgg, ESFieldUniqAgg, ESGenericSearch

from scirius.rest_utils import SciriusReadOnlyModelViewSet
from scirius.settings import USE_EVEBOX, USE_KIBANA, KIBANA_PROXY, KIBANA_URL, ELASTICSEARCH_KEYWORD, USE_CYBERCHEF, CYBERCHEF_URL
Expand Down Expand Up @@ -3247,6 +3247,29 @@ def _get(self, request, format=None) -> dict:
})


class ESGenericSearchViewSet(ESBaseViewSet):
REQUIRED_GROUPS = {
'READ': ('rules.events_view',),
'WRITE': ('rules.events_view',),
}

def post(self, request, _=None):

index = self.request.data.get('index')
qfilter = self.request.data.get('qfilter')
aggs = self.request.data.get('aggs')
size = self.request.data.get('size')
time_filter = self.request.data.get('time_filter', '@timestamp')

if not index:
raise serializers.ValidationError({'index': ['is mandatory']})

if not qfilter:
raise serializers.ValidationError({'qfilter': ['is mandatory']})

return Response(ESGenericSearch(request, index, qfilter, size, aggs, time_filter).get())


def get_custom_urls():
urls = []
url_ = re_path(r'rules/system_settings/$', SystemSettingsViewSet.as_view({
Expand Down Expand Up @@ -3293,6 +3316,7 @@ def get_custom_urls():
urls.append(re_path(r'rules/es/unique_fields/$', ESUniqueFieldViewSet.as_view(), name='es_unique_fields'))
urls.append(re_path(r'rules/es/graph_agg/$', ESGraphAggViewSet.as_view(), name='es_graph_agg'))
urls.append(re_path(r'rules/es/unique_values/$', ESFieldUniqViewSet.as_view(), name='es_unique_values'))
urls.append(re_path(r'rules/es/search/$', ESGenericSearchViewSet.as_view(), name='es_search'))

return urls

Expand Down

0 comments on commit c5b755a

Please sign in to comment.