Rename the program to sww and its deciding daemon to discriminator (closes #218) (#221)
check / check (push) Failing after 1m34s

This commit was merged in pull request #221.
This commit is contained in:
clawbot committed 2026-11-07 06:51:06 +01:00
1 parent 2e2f6f7175
commit beb503b233
106 files changed
+3302 -3275

No files matched your search

+29 -29
View File
@@ -1,6 +1,6 @@
// Package requestlog writes the lines smallwebwaf prints on stdout: one
// JSON object per request, two from servewaf and a short one from rproxy, marked
// "type":"request", and the process's own messages as JSON lines marked
// Package requestlog writes the lines sww prints on stdout: one
// JSON object per request, two from discriminator and a short one from rproxy,
// marked "type":"request", and the process's own messages as JSON lines marked
// "type":"process".
package requestlog
@@ -14,10 +14,10 @@ import (
"sneak.berlin/go/smallwebwaf/internal/ratelimit"
)
// The action a request line names: what servewaf did with the request.
// The action a request line names: what discriminator did with the request.
const (
// ActionForward is a request servewaf allowed, which rproxy passes to the
// app.
// ActionForward is a request discriminator allowed, which rproxy passes to
// the app.
ActionForward = "forward"
// ActionTooLarge is a request over the header limits.
ActionTooLarge = "too_large"
@@ -33,17 +33,17 @@ const (
// rule.
ActionRuleBlocked = "rule_blocked"
// ActionWAFBlocked is a request refused because the Core Rule Set
// scored it at or over SWWAF_WAF_ANOMALY_THRESHOLD.
// scored it at or over SWW_WAF_ANOMALY_THRESHOLD.
ActionWAFBlocked = "waf_blocked"
// ActionDenied is a request refused because its client is in
// SWWAF_DENY_NETS, in a blocklist while SWWAF_BLOCKLIST_ACTION is deny,
// SWW_DENY_NETS, in a blocklist while SWW_BLOCKLIST_ACTION is deny,
// or listed by a DNSBL zone, or scored a hit by AbuseIPDB, while
// SWWAF_REPUTATION_ACTION is deny.
// SWW_REPUTATION_ACTION is deny.
ActionDenied = "denied"
// ActionCountryDenied is a request refused for its client's country.
ActionCountryDenied = "country_denied"
// ActionAdmin is a request servewaf answered at one of its own endpoints,
// or a question about a path under /_smallwebwaf/.
// ActionAdmin is a request discriminator answered at one of its own
// endpoints, or a question about a path under /_sww/.
ActionAdmin = "admin"
)
@@ -56,14 +56,14 @@ const OffenceLimit = "limit"
// that broke the error burst.
const LimitHitErrorBurst = "error_burst"
// The servewaf_line a request line names, which says which of servewaf's two
// lines about a question it is.
// The discriminator_line a request line names, which says which of
// discriminator's two lines about a question it is.
const (
// ServeWAFLineDecision is servewaf's line at its decision.
ServeWAFLineDecision = "decision"
// ServeWAFLineReport is servewaf's line when rproxy's report comes, with
// the decision's fields and the report's together.
ServeWAFLineReport = "report"
// DiscriminatorLineDecision is discriminator's line at its decision.
DiscriminatorLineDecision = "decision"
// DiscriminatorLineReport is discriminator's line when rproxy's report
// comes, with the decision's fields and the report's together.
DiscriminatorLineReport = "report"
)
// timeLayout is RFC 3339 with milliseconds.
@@ -76,9 +76,9 @@ const timeLayout = "2006-01-02T15:04:05.000Z07:00"
//nolint:tagliatelle // docs/request-log.md names the fields in snake_case
type Line struct {
Type string `json:"type"`
// ServeWAFLine is ServeWAFLineDecision or ServeWAFLineReport on servewaf's
// two lines about a question.
ServeWAFLine string `json:"servewaf_line,omitempty"`
// DiscriminatorLine is DiscriminatorLineDecision or DiscriminatorLineReport
// on discriminator's two lines about a question.
DiscriminatorLine string `json:"discriminator_line,omitempty"`
// The standard web log fields. Scheme is how the client reached rproxy, or
// the trusted proxy in front of it.
@@ -98,7 +98,7 @@ type Line struct {
UserAgent string `json:"user_agent"`
// Request detail. RequestID is the id rproxy made for the request, or for a
// request to servewaf's own endpoints a new one. ForwardedFor is the
// request to discriminator's own endpoints a new one. ForwardedFor is the
// X-Forwarded-For header as received. ClientGroup is the netblock the
// client is counted as. ASN, ASName and Country are the client's AS
// number, AS name and country, as looked up.
@@ -112,14 +112,14 @@ type Line struct {
ContentType string `json:"content_type,omitempty"`
// ContentLength is the length of its body the request announced.
ContentLength int64 `json:"content_length,omitempty"`
// RequestHeaders are the headers SWWAF_LOG_REQUEST_HEADERS names that
// RequestHeaders are the headers SWW_LOG_REQUEST_HEADERS names that
// the request carried, by name in lower case.
RequestHeaders map[string]string `json:"request_headers,omitempty"`
HasAuthorization bool `json:"has_authorization,omitempty"`
HasCookie bool `json:"has_cookie,omitempty"`
// Response detail, of servewaf's own answer. Aborted is true when rproxy, or
// the admin's tool, went away before the answer.
// Response detail, of discriminator's own answer. Aborted is true when
// rproxy, or the admin's tool, went away before the answer.
ResponseContentType string `json:"response_content_type,omitempty"`
Aborted bool `json:"aborted,omitempty"`
@@ -128,7 +128,7 @@ type Line struct {
// WouldAction is, in observe mode, the action enforce mode would have
// taken with a request it would have refused: ActionDenied,
// ActionBanned, ActionCountryDenied, ActionRateLimited,
// ActionRuleBlocked, ActionWAFBlocked, or, in servewaf, ActionTooLarge
// ActionRuleBlocked, ActionWAFBlocked, or, in discriminator, ActionTooLarge
// for the header limits.
WouldAction string `json:"would_action,omitempty"`
// LimitPercent and LimitPercentSetting are, for a request the rate
@@ -201,7 +201,7 @@ type RProxyLine struct {
// if that is sooner. DurationResponse runs from then until the answer ends.
DurationRequest float64 `json:"duration_request"`
DurationResponse float64 `json:"duration_response"`
// Disposition is the valid disposition servewaf answered or, while
// Disposition is the valid disposition discriminator answered or, while
// DefaultDisposition is true, the value of SWRP_DEFAULT_DISPOSITION. It is ""
// when neither gave one.
Disposition string `json:"disposition,omitempty"`
@@ -250,8 +250,8 @@ func Milliseconds(d time.Duration) float64 {
// NewProcessLogger returns the logger for the process's own messages:
// JSON lines on w, marked "type":"process", with the time in the same form
// as a request line's, and instanceName, SWWAF_INSTANCE_NAME, as instance.
// It writes only the messages at level, SWWAF_LOG_LEVEL, or more severe;
// as a request line's, and instanceName, SWW_INSTANCE_NAME, as instance.
// It writes only the messages at level, SWW_LOG_LEVEL, or more severe;
// the request lines Write writes are never held back.
func NewProcessLogger(w io.Writer, instanceName string, level slog.Level) *slog.Logger {
handler := slog.NewJSONHandler(w, &slog.HandlerOptions{