336 lines
7.3 KiB
Go
336 lines
7.3 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"io/ioutil"
|
|
"iwarma.ru/console/correlator/es"
|
|
"iwarma.ru/console/correlator/events"
|
|
"iwarma.ru/console/correlator/util"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"iwarma.ru/console/correlator/rules"
|
|
)
|
|
|
|
func TestAddRulesHandler(t *testing.T) {
|
|
|
|
util.SetupTest(t)
|
|
defer util.TearDownTest(t)
|
|
|
|
client, err := es.NewElastic()
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
err = events.ClearIndex(client, events.GetAggregatedIndexName(), events.GetNormalizedIndexName())
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
// Prepare store
|
|
store := rules.NewRuleStore(client)
|
|
|
|
rulesStr := `
|
|
[
|
|
{
|
|
"name":"Test2",
|
|
"depth":"600s",
|
|
"id":"4",
|
|
"predicat":{
|
|
"name":"top_predicat",
|
|
"type":"query_string",
|
|
"field":"destination_host",
|
|
"value":[
|
|
{
|
|
"name":"top_predicat_child1",
|
|
"type":"match",
|
|
"field":"sign_category",
|
|
"value":"Firewall",
|
|
"parent":"top_predicat"
|
|
},
|
|
{
|
|
"name":"top_predicat_child2",
|
|
"type":"match",
|
|
"field":"device_vendor",
|
|
"value":"armaif",
|
|
"parent":"top_predicat"
|
|
}
|
|
],
|
|
"parent":"top_predicat"
|
|
},
|
|
"actions":[
|
|
{
|
|
"type":"firewall",
|
|
"quick":true,
|
|
"action":"pass",
|
|
"armaif":"1",
|
|
"sensor":{
|
|
"ip":"1.1.1.1",
|
|
"key":"3uIhK/pCIKaLhkv9cmYg4V7DQ1Adt4zZLovThtbfaYzqr1YUdG4DdK6lKuqEjq0vfrDac2KczPbm7dwW",
|
|
"scheme":"http",
|
|
"secret":"5bYfRxkmDwFFY3WL/AHIooFTVQwHdDYSGT8I/6zvzwiSPAMrc9YNNS1CMRoSerxtUnkXRm2ZTEe4LtWo"
|
|
},
|
|
"enabled":true,
|
|
"gateway":"",
|
|
"protocol":"any",
|
|
"sequence":"5000",
|
|
"direction":"in",
|
|
"interface":"lan",
|
|
"ipprotocol":"inet",
|
|
"source_net":"any",
|
|
"description":"",
|
|
"source_port":"",
|
|
"destination_net":"any",
|
|
"destination_port":""
|
|
}
|
|
],
|
|
"multi":false
|
|
}
|
|
]`
|
|
|
|
body := bytes.NewBuffer([]byte(rulesStr))
|
|
|
|
request := httptest.NewRequest("POST", "/add_many/", body)
|
|
request.Header.Add("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
|
|
handler := AddRulesHandler(store)
|
|
handler(w, request)
|
|
|
|
resp := w.Result()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Bad response status code: %v", resp.StatusCode)
|
|
}
|
|
|
|
// Let's check what we have
|
|
stat := store.GetStat()
|
|
|
|
if stat.RuleCount != 1 {
|
|
t.Errorf("Bad rule count. Expect 1 got %v", stat.RuleCount)
|
|
}
|
|
}
|
|
|
|
func TestAddRulesHandler2(t *testing.T) {
|
|
util.SetupTest(t)
|
|
defer util.TearDownTest(t)
|
|
|
|
client, err := es.NewElastic()
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
err = events.ClearIndex(client, events.GetAggregatedIndexName(), events.GetNormalizedIndexName())
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
// Prepare store
|
|
store := rules.NewRuleStore(client)
|
|
|
|
rulesStr := `
|
|
[
|
|
{
|
|
"name":"Test2",
|
|
"depth":"600s",
|
|
"id":"4",
|
|
"predicat":{
|
|
"name":"top_predicat",
|
|
"type":"query_string",
|
|
"field":"",
|
|
"value":[
|
|
{
|
|
|
|
"type":"query_string",
|
|
"field":"sign_category",
|
|
|
|
"operands":"sign_category:\"Firewall\""
|
|
},
|
|
{
|
|
|
|
"type":"query_string",
|
|
"field":"",
|
|
"operands":"device_vendor:\"armaif\" ",
|
|
|
|
}
|
|
],
|
|
|
|
},
|
|
"actions":[
|
|
{
|
|
"type":"firewall",
|
|
"quick":true,
|
|
"action":"pass",
|
|
"armaif":"1",
|
|
"sensor":{
|
|
"ip":"1.1.1.1",
|
|
"key":"3uIhK/pCIKaLhkv9cmYg4V7DQ1Adt4zZLovThtbfaYzqr1YUdG4DdK6lKuqEjq0vfrDac2KczPbm7dwW",
|
|
"scheme":"http",
|
|
"secret":"5bYfRxkmDwFFY3WL/AHIooFTVQwHdDYSGT8I/6zvzwiSPAMrc9YNNS1CMRoSerxtUnkXRm2ZTEe4LtWo"
|
|
},
|
|
"enabled":true,
|
|
"gateway":"",
|
|
"protocol":"any",
|
|
"sequence":"5000",
|
|
"direction":"in",
|
|
"interface":"lan",
|
|
"ipprotocol":"inet",
|
|
"source_net":"any",
|
|
"description":"",
|
|
"source_port":"",
|
|
"destination_net":"any",
|
|
"destination_port":""
|
|
}
|
|
],
|
|
"multi":false
|
|
}
|
|
]`
|
|
|
|
body := bytes.NewBuffer([]byte(rulesStr))
|
|
|
|
request := httptest.NewRequest("POST", "/add_many/", body)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler := AddRulesHandler(store)
|
|
handler(w, request)
|
|
|
|
resp := w.Result()
|
|
|
|
if resp.StatusCode != http.StatusBadRequest {
|
|
t.Errorf("Bad response status code: %v", resp.StatusCode)
|
|
}
|
|
|
|
// Let's check what we have
|
|
stat := store.GetStat()
|
|
|
|
if stat.RuleCount != 0 {
|
|
t.Errorf("Bad rule count. Expect 0 got %v", stat.RuleCount)
|
|
}
|
|
}
|
|
|
|
func TestClearStoreHandler(t *testing.T) {
|
|
util.SetupTest(t)
|
|
defer util.TearDownTest(t)
|
|
|
|
client, err := es.NewElastic()
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
err = events.ClearIndex(client, events.GetAggregatedIndexName(), events.GetNormalizedIndexName())
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
// Prepare store
|
|
store := rules.NewRuleStore(client)
|
|
|
|
actions := make([]rules.Action, 1)
|
|
action := rules.TestAction{
|
|
PerformError: true,
|
|
ParseInterfaceError: false,
|
|
MarshalError: false,
|
|
UnmarshalError: false,
|
|
}
|
|
actions[0] = &action
|
|
|
|
store.AddRules(rules.Rule{
|
|
Id: "1",
|
|
Name: "TestRule",
|
|
Description: "Some long description",
|
|
Multi: false,
|
|
Depth: time.Second * 30,
|
|
Predicate: rules.NewPredicate("", "device_vendor:TestDevice"),
|
|
Actions: actions,
|
|
})
|
|
|
|
request := httptest.NewRequest("GET", "/clear/", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler := ClearStoreHandler(store)
|
|
handler(w, request)
|
|
|
|
resp := w.Result()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Bad response status code: %v", resp.StatusCode)
|
|
}
|
|
|
|
// Check what we have
|
|
stat := store.GetStat()
|
|
if stat.RuleCount != 0 {
|
|
t.Errorf("Bad rule count. Expect 0, got %v", stat.RuleCount)
|
|
}
|
|
}
|
|
|
|
func TestCorrelatorStatHandler(t *testing.T) {
|
|
util.SetupTest(t)
|
|
defer util.TearDownTest(t)
|
|
|
|
client, err := es.NewElastic()
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
err = events.ClearIndex(client, events.GetAggregatedIndexName(), events.GetNormalizedIndexName())
|
|
if err != nil {
|
|
t.Errorf("%v", err)
|
|
return
|
|
}
|
|
|
|
// Prepare store
|
|
store := rules.NewRuleStore(client)
|
|
|
|
actions := make([]rules.Action, 1)
|
|
action := rules.TestAction{
|
|
PerformError: true,
|
|
ParseInterfaceError: false,
|
|
MarshalError: false,
|
|
UnmarshalError: false,
|
|
}
|
|
actions[0] = &action
|
|
|
|
store.AddRules(rules.Rule{
|
|
Id: "1",
|
|
Name: "TestRule",
|
|
Description: "Some long description",
|
|
Multi: false,
|
|
Depth: time.Second * 30,
|
|
Predicate: rules.NewPredicate("", "device_vendor:TestDevice"),
|
|
Actions: actions,
|
|
})
|
|
|
|
request := httptest.NewRequest("GET", "/stat/", nil)
|
|
w := httptest.NewRecorder()
|
|
duration := time.Second * 30
|
|
ruleStore := rules.NewRuleStore(client)
|
|
eventsStore := events.NewAggregatedEventStore(client, events.TimeWindow{
|
|
Begin: time.Now().UTC(),
|
|
End: time.Now().UTC().Add(duration),
|
|
})
|
|
handler := StatHandler(eventsStore, ruleStore)
|
|
handler(w, request)
|
|
|
|
resp := w.Result()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Bad response status code: %v", resp.StatusCode)
|
|
}
|
|
|
|
// Let's check response
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
|
|
if string(body) != `{"aggregator":{"events_processed":0,"events_aggregated":0,"average_iteration":{"value":"0s"}},"correlator":{"rule_count":0,"average_time":{"value":"0s"},"average_rule_time":{},"incident_count":0,"events_count":0,"errors":{}}}` {
|
|
t.Errorf("Bad response: %v", string(body))
|
|
}
|
|
}
|