package proxy import ( "context" "sneak.berlin/go/smallwebwaf/internal/alerts" ) // blocklistDenied notes the blocklists that list the client, as // noteListed does, and reports whether SWWAF_BLOCKLIST_ACTION, being deny, // refuses the request. Being limit, it lowers the client's limits instead // (see limitPercentages), and being log, it does nothing more. func (rq *request) blocklistDenied() bool { listedBy := rq.h.lists.ListedBy(rq.client) rq.blocklisted = len(listedBy) > 0 rq.noteListed(listedBy, "listed by a blocklist") return rq.blocklisted && rq.h.config.BlocklistAction == "deny" } // dnsblDenied notes the DNSBL zones whose verdict lists the client, as // noteListed does, and reports whether SWWAF_REPUTATION_ACTION, being // deny, refuses the request. Being limit, it lowers the client's limits // instead (see limitPercentages), and being log, it does nothing more. A // zone without a verdict on the client is asked about it in the // background, and the request does not wait for the answer. ctx is the // request's own context. func (rq *request) dnsblDenied(ctx context.Context) bool { listedBy := rq.h.dnsbl.ListedBy(ctx, rq.client) rq.dnsblListed = len(listedBy) > 0 rq.noteListed(listedBy, "listed by a DNSBL zone") return rq.dnsblListed && rq.h.config.ReputationAction == "deny" } // noteListed adds sources, the URLs of the blocklists or the DNSBL zones, // their keys masked, that list the client, to the log line's reputation, // counts each of them in the metrics, and raises a reputation_hit alert, // with reason, for each. func (rq *request) noteListed(sources []string, reason string) { rq.line.Reputation = append(rq.line.Reputation, sources...) for _, source := range sources { rq.h.metrics.ReputationHit(source) rq.h.alerts.Raise(alerts.Alert{ Event: alerts.EventReputationHit, Client: rq.client, Netblock: clientGroup(rq.client), ASN: rq.line.ASN, ASName: rq.line.ASName, Country: rq.line.Country, Reason: reason, Detail: map[string]any{"source": source}, }) } }