|
@@ -170,97 +170,133 @@ func (r *WaapRunner) ProcessOutOfBandRules(request *waf.ParsedRequest) error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
-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.logger.Debugf("Requests handled by runner %s", request.UUID)
|
|
|
- r.WaapRuntime.ClearResponse()
|
|
|
-
|
|
|
- request.IsInBand = true
|
|
|
- request.IsOutBand = false
|
|
|
+func (r *WaapRunner) handleInBandInterrupt(request *waf.ParsedRequest) {
|
|
|
+ //create the associated event for crowdsec itself
|
|
|
+ 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)
|
|
|
+ if err != nil {
|
|
|
+ r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
|
|
+ }
|
|
|
+ if in := request.Tx.Interruption(); in != nil {
|
|
|
+ r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
|
|
+ r.WaapRuntime.Response.InBandInterrupt = true
|
|
|
|
|
|
- //to measure the time spent in the WAF
|
|
|
- startParsing := time.Now()
|
|
|
+ err = r.WaapRuntime.ProcessOnMatchRules(request)
|
|
|
+ if err != nil {
|
|
|
+ r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Should the in band match trigger an event ?
|
|
|
+ if r.WaapRuntime.Response.SendEvent {
|
|
|
+ r.outChan <- evt
|
|
|
+ }
|
|
|
|
|
|
- //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
|
|
|
- evt, err := EventFromRequest(request)
|
|
|
+ // Should the in band match trigger an overflow ?
|
|
|
+ if r.WaapRuntime.Response.SendAlert {
|
|
|
+ waapOvlfw, err := WaapEventGeneration(evt)
|
|
|
if err != nil {
|
|
|
- //let's not interrupt the pipeline for this
|
|
|
- r.logger.Errorf("unable to create event from request : %s", err)
|
|
|
+ r.logger.Errorf("unable to generate waap event : %s", err)
|
|
|
+ return
|
|
|
}
|
|
|
- err = r.AccumulateTxToEvent(&evt, request)
|
|
|
+ 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)
|
|
|
+ if err != nil {
|
|
|
+ r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
|
|
+ }
|
|
|
+ if in := request.Tx.Interruption(); in != nil {
|
|
|
+ r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
|
|
+ r.WaapRuntime.Response.OutOfBandInterrupt = true
|
|
|
+
|
|
|
+ err = r.WaapRuntime.ProcessOnMatchRules(request)
|
|
|
+ if err != nil {
|
|
|
+ r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Should the match trigger an event ?
|
|
|
+ if r.WaapRuntime.Response.SendEvent {
|
|
|
+ r.outChan <- evt
|
|
|
+ }
|
|
|
+
|
|
|
+ // Should the match trigger an overflow ?
|
|
|
+ if r.WaapRuntime.Response.SendAlert {
|
|
|
+ waapOvlfw, err := WaapEventGeneration(evt)
|
|
|
if err != nil {
|
|
|
- r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
|
|
- }
|
|
|
- if in := request.Tx.Interruption(); in != nil {
|
|
|
- r.logger.Debugf("inband rules matched : %d", in.RuleID)
|
|
|
- r.WaapRuntime.Response.InBandInterrupt = true
|
|
|
-
|
|
|
- err = r.WaapRuntime.ProcessOnMatchRules(&request)
|
|
|
- if err != nil {
|
|
|
- r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
|
|
- continue
|
|
|
- }
|
|
|
+ r.logger.Errorf("unable to generate waap event : %s", err)
|
|
|
+ return
|
|
|
}
|
|
|
+ r.outChan <- *waapOvlfw
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- elapsed := time.Since(startParsing)
|
|
|
- WafInbandParsingHistogram.With(prometheus.Labels{"source": request.RemoteAddr}).Observe(elapsed.Seconds())
|
|
|
+func (r *WaapRunner) handleRequest(request *waf.ParsedRequest) {
|
|
|
+ r.logger.Debugf("Requests handled by runner %s", request.UUID)
|
|
|
+ r.WaapRuntime.ClearResponse()
|
|
|
|
|
|
- //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
|
|
|
+ request.IsInBand = true
|
|
|
+ request.IsOutBand = false
|
|
|
|
|
|
- // send back the result to the HTTP handler for the InBand part
|
|
|
+ //to measure the time spent in the WAF
|
|
|
+ startParsing := time.Now()
|
|
|
|
|
|
- r.logger.Infof("Response: %+v", r.WaapRuntime.Response)
|
|
|
+ //inband WAAP rules
|
|
|
+ err := r.ProcessInBandRules(request)
|
|
|
+ if err != nil {
|
|
|
+ r.logger.Errorf("unable to process InBand rules: %s", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- request.ResponseChannel <- r.WaapRuntime.Response
|
|
|
+ if request.Tx.IsInterrupted() {
|
|
|
+ r.handleInBandInterrupt(request)
|
|
|
+ }
|
|
|
|
|
|
- request.IsInBand = false
|
|
|
- request.IsOutBand = true
|
|
|
+ elapsed := time.Since(startParsing)
|
|
|
+ WafInbandParsingHistogram.With(prometheus.Labels{"source": request.RemoteAddr}).Observe(elapsed.Seconds())
|
|
|
|
|
|
- err = r.ProcessOutOfBandRules(&request)
|
|
|
- if err != nil {
|
|
|
- r.logger.Errorf("unable to process OutOfBand rules: %s", err)
|
|
|
- continue
|
|
|
- }
|
|
|
- err = r.AccumulateTxToEvent(&evt, request)
|
|
|
- if err != nil {
|
|
|
- r.logger.Errorf("unable to accumulate tx to event : %s", err)
|
|
|
- }
|
|
|
- if in := request.Tx.Interruption(); in != nil {
|
|
|
- r.logger.Debugf("outband rules matched : %d", in.RuleID)
|
|
|
- r.WaapRuntime.Response.OutOfBandInterrupt = true
|
|
|
- err = r.WaapRuntime.ProcessOnMatchRules(&request)
|
|
|
- if err != nil {
|
|
|
- r.logger.Errorf("unable to process OnMatch rules: %s", err)
|
|
|
- continue
|
|
|
- }
|
|
|
- }
|
|
|
+ // send back the result to the HTTP handler for the InBand part
|
|
|
+ request.ResponseChannel <- r.WaapRuntime.Response
|
|
|
|
|
|
- if !evt.Process {
|
|
|
- continue
|
|
|
- }
|
|
|
+ //Now let's process the out of band rules
|
|
|
|
|
|
- //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
|
|
|
- waapOvlfw, err := WaapEventGeneration(evt)
|
|
|
- if err != nil {
|
|
|
- r.logger.Errorf("unable to generate waap event : %s", err)
|
|
|
- } else if waapOvlfw != nil {
|
|
|
- r.outChan <- *waapOvlfw
|
|
|
- }
|
|
|
+ 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)
|
|
|
}
|
|
|
}
|
|
|
}
|