up
This commit is contained in:
parent
fe005f87e5
commit
5f254769ae
|
@ -68,7 +68,7 @@ func WaapEventGeneration(inEvt types.Event) (*types.Event, error) {
|
||||||
return &evt, nil
|
return &evt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
|
func EventFromRequest(r *waf.ParsedRequest) (types.Event, error) {
|
||||||
evt := types.Event{}
|
evt := types.Event{}
|
||||||
//we might want to change this based on in-band vs out-of-band ?
|
//we might want to change this based on in-band vs out-of-band ?
|
||||||
evt.Type = types.LOG
|
evt.Type = types.LOG
|
||||||
|
@ -81,7 +81,7 @@ func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
|
||||||
"target_uri": r.URI,
|
"target_uri": r.URI,
|
||||||
"method": r.Method,
|
"method": r.Method,
|
||||||
"req_uuid": r.Tx.ID(),
|
"req_uuid": r.Tx.ID(),
|
||||||
"source": "coraza",
|
"source": "crowdsec-waap",
|
||||||
|
|
||||||
//TBD:
|
//TBD:
|
||||||
//http_status
|
//http_status
|
||||||
|
@ -91,7 +91,7 @@ func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
|
||||||
evt.Line = types.Line{
|
evt.Line = types.Line{
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
//should we add some info like listen addr/port/path ?
|
//should we add some info like listen addr/port/path ?
|
||||||
Labels: map[string]string{"type": "coraza-waap"},
|
Labels: map[string]string{"type": "crowdsec-waap"},
|
||||||
Process: true,
|
Process: true,
|
||||||
Module: "waap",
|
Module: "waap",
|
||||||
Src: "waap",
|
Src: "waap",
|
||||||
|
@ -130,7 +130,7 @@ func LogWaapEvent(evt *types.Event, logger *log.Entry) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WaapRunner) AccumulateTxToEvent(evt *types.Event, req waf.ParsedRequest) error {
|
func (r *WaapRunner) AccumulateTxToEvent(evt *types.Event, req *waf.ParsedRequest) error {
|
||||||
|
|
||||||
if evt == nil {
|
if evt == nil {
|
||||||
//an error was already emitted, let's not spam the logs
|
//an error was already emitted, let's not spam the logs
|
||||||
|
|
|
@ -170,29 +170,7 @@ func (r *WaapRunner) ProcessOutOfBandRules(request *waf.ParsedRequest) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WaapRunner) Run(t *tomb.Tomb) error {
|
func (r *WaapRunner) handleInBandInterrupt(request *waf.ParsedRequest) {
|
||||||
r.logger.Infof("Waap Runner ready to process event")
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-t.Dying():
|
|
||||||
r.logger.Infof("Waf Runner is dying")
|
|
||||||
return nil
|
|
||||||
case request := <-r.inChan:
|
|
||||||
r.logger.Debugf("Requests handled by runner %s", request.UUID)
|
|
||||||
r.WaapRuntime.ClearResponse()
|
|
||||||
|
|
||||||
request.IsInBand = true
|
|
||||||
request.IsOutBand = false
|
|
||||||
|
|
||||||
//to measure the time spent in the WAF
|
|
||||||
startParsing := time.Now()
|
|
||||||
|
|
||||||
//inband WAAP rules
|
|
||||||
err := r.ProcessInBandRules(&request)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.Errorf("unable to process InBand rules: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
//create the associated event for crowdsec itself
|
//create the associated event for crowdsec itself
|
||||||
evt, err := EventFromRequest(request)
|
evt, err := EventFromRequest(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -207,60 +185,118 @@ func (r *WaapRunner) Run(t *tomb.Tomb) error {
|
||||||
r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
||||||
r.WaapRuntime.Response.InBandInterrupt = true
|
r.WaapRuntime.Response.InBandInterrupt = true
|
||||||
|
|
||||||
err = r.WaapRuntime.ProcessOnMatchRules(&request)
|
err = r.WaapRuntime.ProcessOnMatchRules(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
// Should the in band match trigger an event ?
|
||||||
|
if r.WaapRuntime.Response.SendEvent {
|
||||||
|
r.outChan <- evt
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed := time.Since(startParsing)
|
// Should the in band match trigger an overflow ?
|
||||||
WafInbandParsingHistogram.With(prometheus.Labels{"source": request.RemoteAddr}).Observe(elapsed.Seconds())
|
if r.WaapRuntime.Response.SendAlert {
|
||||||
|
waapOvlfw, err := WaapEventGeneration(evt)
|
||||||
//generate reponse for the remediation component, based on the WAAP config + inband rules evaluation
|
|
||||||
//@tko : this should move in the WaapRuntimeConfig as it knows what to do with the interruption and the expected remediation
|
|
||||||
|
|
||||||
// send back the result to the HTTP handler for the InBand part
|
|
||||||
|
|
||||||
r.logger.Infof("Response: %+v", r.WaapRuntime.Response)
|
|
||||||
|
|
||||||
request.ResponseChannel <- r.WaapRuntime.Response
|
|
||||||
|
|
||||||
request.IsInBand = false
|
|
||||||
request.IsOutBand = true
|
|
||||||
|
|
||||||
err = r.ProcessOutOfBandRules(&request)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Errorf("unable to process OutOfBand rules: %s", err)
|
r.logger.Errorf("unable to generate waap event : %s", err)
|
||||||
continue
|
return
|
||||||
|
}
|
||||||
|
r.outChan <- *waapOvlfw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *WaapRunner) handleOutBandInterrupt(request *waf.ParsedRequest) {
|
||||||
|
evt, err := EventFromRequest(request)
|
||||||
|
if err != nil {
|
||||||
|
//let's not interrupt the pipeline for this
|
||||||
|
r.logger.Errorf("unable to create event from request : %s", err)
|
||||||
}
|
}
|
||||||
err = r.AccumulateTxToEvent(&evt, request)
|
err = r.AccumulateTxToEvent(&evt, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
||||||
}
|
}
|
||||||
if in := request.Tx.Interruption(); in != nil {
|
if in := request.Tx.Interruption(); in != nil {
|
||||||
r.logger.Debugf("outband rules matched : %d", in.RuleID)
|
r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
||||||
r.WaapRuntime.Response.OutOfBandInterrupt = true
|
r.WaapRuntime.Response.OutOfBandInterrupt = true
|
||||||
err = r.WaapRuntime.ProcessOnMatchRules(&request)
|
|
||||||
|
err = r.WaapRuntime.ProcessOnMatchRules(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
}
|
// Should the match trigger an event ?
|
||||||
|
if r.WaapRuntime.Response.SendEvent {
|
||||||
if !evt.Process {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
//we generate two events: one that is going to be picked up by the acquisition pipeline (parsers, scenarios etc.)
|
|
||||||
//and a second one that will go straight to LAPI
|
|
||||||
r.outChan <- evt
|
r.outChan <- evt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should the match trigger an overflow ?
|
||||||
|
if r.WaapRuntime.Response.SendAlert {
|
||||||
waapOvlfw, err := WaapEventGeneration(evt)
|
waapOvlfw, err := WaapEventGeneration(evt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Errorf("unable to generate waap event : %s", err)
|
r.logger.Errorf("unable to generate waap event : %s", err)
|
||||||
} else if waapOvlfw != nil {
|
return
|
||||||
|
}
|
||||||
r.outChan <- *waapOvlfw
|
r.outChan <- *waapOvlfw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *WaapRunner) handleRequest(request *waf.ParsedRequest) {
|
||||||
|
r.logger.Debugf("Requests handled by runner %s", request.UUID)
|
||||||
|
r.WaapRuntime.ClearResponse()
|
||||||
|
|
||||||
|
request.IsInBand = true
|
||||||
|
request.IsOutBand = false
|
||||||
|
|
||||||
|
//to measure the time spent in the WAF
|
||||||
|
startParsing := time.Now()
|
||||||
|
|
||||||
|
//inband WAAP rules
|
||||||
|
err := r.ProcessInBandRules(request)
|
||||||
|
if err != nil {
|
||||||
|
r.logger.Errorf("unable to process InBand rules: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Tx.IsInterrupted() {
|
||||||
|
r.handleInBandInterrupt(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed := time.Since(startParsing)
|
||||||
|
WafInbandParsingHistogram.With(prometheus.Labels{"source": request.RemoteAddr}).Observe(elapsed.Seconds())
|
||||||
|
|
||||||
|
// send back the result to the HTTP handler for the InBand part
|
||||||
|
request.ResponseChannel <- r.WaapRuntime.Response
|
||||||
|
|
||||||
|
//Now let's process the out of band rules
|
||||||
|
|
||||||
|
request.IsInBand = false
|
||||||
|
request.IsOutBand = true
|
||||||
|
r.WaapRuntime.Response.SendAlert = false
|
||||||
|
r.WaapRuntime.Response.SendEvent = true
|
||||||
|
|
||||||
|
err = r.ProcessOutOfBandRules(request)
|
||||||
|
if err != nil {
|
||||||
|
r.logger.Errorf("unable to process OutOfBand rules: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Tx.IsInterrupted() {
|
||||||
|
r.handleOutBandInterrupt(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *WaapRunner) Run(t *tomb.Tomb) error {
|
||||||
|
r.logger.Infof("Waap Runner ready to process event")
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-t.Dying():
|
||||||
|
r.logger.Infof("Waf Runner is dying")
|
||||||
|
return nil
|
||||||
|
case request := <-r.inChan:
|
||||||
|
r.handleRequest(&request)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,8 @@ func (w *WaapRuntimeConfig) ClearResponse() {
|
||||||
log.Debugf("-> %p", w.Config)
|
log.Debugf("-> %p", w.Config)
|
||||||
w.Response.Action = w.Config.DefaultPassAction
|
w.Response.Action = w.Config.DefaultPassAction
|
||||||
w.Response.HTTPResponseCode = w.Config.PassedHTTPCode
|
w.Response.HTTPResponseCode = w.Config.PassedHTTPCode
|
||||||
w.Response.SendEvent = true
|
w.Response.SendEvent = false
|
||||||
|
w.Response.SendAlert = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc *WaapConfig) LoadByPath(file string) error {
|
func (wc *WaapConfig) LoadByPath(file string) error {
|
||||||
|
|
Loading…
Reference in a new issue