crowdsec/pkg/acquisition/modules/waf/utils.go

100 lines
2.7 KiB
Go
Raw Normal View History

2023-06-16 10:19:08 +00:00
package wafacquisition
import (
"fmt"
"time"
2023-07-13 14:22:21 +00:00
"github.com/crowdsecurity/coraza/v3/experimental"
"github.com/crowdsecurity/crowdsec/pkg/types"
2023-07-04 15:36:56 +00:00
"github.com/crowdsecurity/crowdsec/pkg/waf"
2023-07-19 09:57:14 +00:00
"github.com/davecgh/go-spew/spew"
2023-07-10 16:00:19 +00:00
"github.com/prometheus/client_golang/prometheus"
2023-07-04 15:36:56 +00:00
log "github.com/sirupsen/logrus"
2023-06-16 10:19:08 +00:00
)
func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
2023-06-16 10:19:08 +00:00
evt := types.Event{}
//we might want to change this based on in-band vs out-of-band ?
evt.Type = types.LOG
evt.ExpectMode = types.LIVE
//def needs fixing
evt.Stage = "s00-raw"
evt.Process = true
evt.Parsed = map[string]string{
"source_ip": r.ClientIP,
"target_host": r.Host,
"target_uri": r.URI,
"method": r.Method,
"req_uuid": r.Tx.ID(),
2023-07-18 16:12:17 +00:00
"source": "coraza",
//TBD:
//http_status
//user_agent
2023-06-16 10:19:08 +00:00
}
evt.Line = types.Line{
Time: time.Now(),
//should we add some info like listen addr/port/path ?
2023-07-18 16:12:17 +00:00
Labels: map[string]string{"type": "coraza-waf"},
2023-06-16 10:19:08 +00:00
Process: true,
Module: "waf",
Src: "waf",
Raw: "dummy-waf-data", //we discard empty Line.Raw items :)
2023-06-16 10:19:08 +00:00
}
evt.Waap = []map[string]interface{}{}
2023-06-16 10:19:08 +00:00
return evt, nil
}
func LogWaapEvent(evt *types.Event) {
log.WithFields(log.Fields{
"module": "waf",
"source": evt.Parsed["source_ip"],
"target_uri": evt.Parsed["target_uri"],
}).Infof("%s triggered %d rules [%+v]", evt.Parsed["source_ip"], len(evt.Waap), evt.Waap.GetRuleIDs())
log.Infof("%s", evt.Waap)
}
func AccumulateTxToEvent(tx experimental.FullTransaction, kind string, evt *types.Event) error {
2023-07-19 09:57:14 +00:00
log.Infof("TX %s", spew.Sdump(tx))
if tx.IsInterrupted() {
log.Infof("interrupted() = %t", tx.IsInterrupted())
log.Infof("interrupted.action = %s", tx.Interruption().Action)
if evt.Meta == nil {
evt.Meta = map[string]string{}
}
2023-07-18 16:12:17 +00:00
evt.Parsed["interrupted"] = "true"
evt.Parsed["action"] = tx.Interruption().Action
evt.Meta["waap_interrupted"] = "1"
evt.Meta["waap_action"] = tx.Interruption().Action
}
2023-07-19 09:50:42 +00:00
//log.Infof("TX %s", spew.Sdump(tx.MatchedRules()))
for _, rule := range tx.MatchedRules() {
if rule.Message() == "" {
continue
}
WafRuleHits.With(prometheus.Labels{"rule_id": fmt.Sprintf("%d", rule.Rule().ID()), "type": kind}).Inc()
corazaRule := map[string]interface{}{
"id": rule.Rule().ID(),
"uri": evt.Parsed["uri"],
"rule_type": kind,
"method": evt.Parsed["method"],
"disruptive": rule.Disruptive(),
"tags": rule.Rule().Tags(),
"file": rule.Rule().File(),
"file_line": rule.Rule().Line(),
"revision": rule.Rule().Revision(),
"secmark": rule.Rule().SecMark(),
"accuracy": rule.Rule().Accuracy(),
"msg": rule.Message(),
"severity": rule.Rule().Severity().String(),
}
evt.Waap = append(evt.Waap, corazaRule)
}
return nil
}