Skip to content

Commit

Permalink
Reroute Kibana Alerts searches to Elastic (#132)
Browse files Browse the repository at this point in the history
We need to reroute `/_search` request related to Kibana Alerts to
Elastic.


This is 3rd attempt to implement this bypass. This attempt has a minimal
impact on the search pipeline.
  • Loading branch information
nablaone authored May 17, 2024
1 parent e7fbb2b commit 0fd5a5a
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 3 deletions.
64 changes: 64 additions & 0 deletions http_requests/kibana-alert.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
POST http://localhost:8080/_search
Content-Type: application/json

{
"aggs": {
"endpoint_alert_count": {
"cardinality": {
"field": "event.id"
}
}
},
"pit": {
"id": "gcSHBAEvLmludGVybmFsLmFsZXJ0cy1zZWN1cml0eS5hbGVydHMtZGVmYXVsdC0wMDAwMDEWRWdvdFQwblRUN0tNaFk4SWc3TDRSQQAWMEdVOVNnVk1TV0t3ckRxbUpkb3BzZwAAAAAAAASdvBZGQXQwWTUyTVRKQ29zaDJ1elRhWFR3AAEWRWdvdFQwblRUN0tNaFk4SWc3TDRSQQAA"
},
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"match_phrase": {
"event.module": "endpoint"
}
}
]
}
},
{
"bool": {
"should": [
{
"match_phrase": {
"kibana.alert.rule.parameters.immutable": "true"
}
}
]
}
},
{
"range": {
"@timestamp": {
"gte": "now-3h",
"lte": "now"
}
}
}
]
}
},
"size": 1000,
"sort": [
{
"@timestamp": {
"format": "strict_date_optional_time_nanos",
"order": "asc"
}
},
{
"_shard_doc": "desc"
}
],
"track_total_hits": false
}
59 changes: 59 additions & 0 deletions quesma/quesma/matchers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package quesma

import (
"encoding/json"
"mitmproxy/quesma/elasticsearch"
"mitmproxy/quesma/logger"
"mitmproxy/quesma/quesma/config"
Expand Down Expand Up @@ -74,3 +75,61 @@ func matchedAgainstPattern(configuration config.QuesmaConfiguration) mux.MatchPr
}
}
}

// Returns false if the body contains a Kibana alert related field.
func matchAgainstKibanaAlerts() mux.MatchPredicate {
return func(m map[string]string, body string) bool {

if body == "" {
return true
}

// https://www.elastic.co/guide/en/security/current/alert-schema.html

var query map[string]interface{}
err := json.Unmarshal([]byte(body), &query)
if err != nil {
logger.Warn().Msgf("error parsing json %v", err)
return true
}

var findKibanaAlertField func(node interface{}) bool

findKibanaAlertField = func(node interface{}) bool {

if node == nil {
return false
}

switch nodeValue := node.(type) {

case map[string]interface{}:

for k, v := range nodeValue {

if strings.Contains(k, "kibana.alert.") {
return true
}

if findKibanaAlertField(v) {
return true
}
}

case []interface{}:

for _, i := range nodeValue {
if findKibanaAlertField(i) {
return true
}
}

}
return false
}

q := query["query"].(map[string]interface{})

return !findKibanaAlertField(q)
}
}
167 changes: 167 additions & 0 deletions quesma/quesma/matchers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package quesma

import (
"github.com/stretchr/testify/assert"
"testing"
)

const kibanaAlerts = `{
"aggs": {
"endpoint_alert_count": {
"cardinality": {
"field": "event.id"
}
}
},
"pit": {
"id": "gcSHBAEvLmludGVybmFsLmFsZXJ0cy1zZWN1cml0eS5hbGVydHMtZGVmYXVsdC0wMDAwMDEWRWdvdFQwblRUN0tNaFk4SWc3TDRSQQAWMEdVOVNnVk1TV0t3ckRxbUpkb3BzZwAAAAAAAASdvBZGQXQwWTUyTVRKQ29zaDJ1elRhWFR3AAEWRWdvdFQwblRUN0tNaFk4SWc3TDRSQQAA"
},
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"match_phrase": {
"event.module": "endpoint"
}
}
]
}
},
{
"bool": {
"should": [
{
"match_phrase": {
"kibana.alert.rule.parameters.immutable": "true"
}
}
]
}
},
{
"range": {
"@timestamp": {
"gte": "now-3h",
"lte": "now"
}
}
}
]
}
},
"size": 1000,
"sort": [
{
"@timestamp": {
"format": "strict_date_optional_time_nanos",
"order": "asc"
}
},
{
"_shard_doc": "desc"
}
],
"track_total_hits": false
}
`

const nonKibanaAlerts = `
{
"_source": false,
"fields": [
{
"field": "*",
"include_unmapped": "true"
},
{
"field": "@timestamp",
"format": "strict_date_optional_time"
}
],
"highlight": {
"fields": {
"*": {}
},
"fragment_size": 2147483647,
"post_tags": [
"@/kibana-highlighted-field@"
],
"pre_tags": [
"@kibana-highlighted-field@"
]
},
"query": {
"bool": {
"filter": [
{
"multi_match": {
"lenient": true,
"query": "user",
"type": "best_fields"
}
},
{
"range": {
"@timestamp": {
"format": "strict_date_optional_time",
"gte": "2022-01-23T14:43:19.481Z",
"lte": "2025-01-23T14:58:19.481Z"
}
}
}
],
"must": [],
"must_not": [],
"should": []
}
},
"runtime_mappings": {},
"script_fields": {},
"size": 500,
"sort": [
{
"@timestamp": {
"format": "strict_date_optional_time",
"order": "desc",
"unmapped_type": "boolean"
}
},
{
"_doc": {
"order": "desc",
"unmapped_type": "boolean"
}
}
],
"stored_fields": [
"*"
],
"track_total_hits": false,
"version": true
}
`

func TestMatchAgainstKibanaAlerts(t *testing.T) {

tests := []struct {
name string
body string
expected bool
}{
{"kibana alerts", kibanaAlerts, false},
{"non kibana alerts", nonKibanaAlerts, true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := matchAgainstKibanaAlerts()(nil, tt.body)
assert.Equal(t, tt.expected, actual)
})

}

}
5 changes: 2 additions & 3 deletions quesma/quesma/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ func configureRouter(cfg config.QuesmaConfiguration, lm *clickhouse.LogManager,
}
})

router.RegisterPathMatcher(routes.GlobalSearchPath, []string{"GET", "POST"}, func(_ map[string]string, _ string) bool {
return true // for now, always route to Quesma, in the near future: combine results from both sources
}, func(ctx context.Context, body string, _ string, params map[string]string, _ http.Header, _ url.Values) (*mux.Result, error) {
router.RegisterPathMatcher(routes.GlobalSearchPath, []string{"GET", "POST"}, matchAgainstKibanaAlerts(), func(ctx context.Context, body string, _ string, params map[string]string, _ http.Header, _ url.Values) (*mux.Result, error) {

responseBody, err := queryRunner.handleSearch(ctx, "*", []byte(body))
if err != nil {
if errors.Is(errIndexNotExists, err) {
Expand Down

0 comments on commit 0fd5a5a

Please sign in to comment.