Rename discriminator to waf everywhere (closes #312)
check / check (push) Successful in 5m58s

The command is now `sww waf`, and the package is `internal/waf`. Types,
functions, files, tests, comments, docs, the Dockerfile, the runit
script, `script/`, compose examples, the log field `waf_line` and the
`X-From-Waf` test header follow. No behaviour changes, and no setting
changes name: rproxy already finds the waf through `SWRP_WAF_BACKEND`.

Done with one `sed -i` (Discriminator and DISCRIMINATOR to WAF,
discriminator to waf) over the files `git grep -i discriminator`
listed, as sneak allowed for this rename, then `git mv` for the
package and files. By hand afterwards: the header's spelling, which
the linter requires, and the padding after `waf` in `sww`'s usage
text.

Model: opus-5-5
This commit was merged in pull request #319.
This commit is contained in:
clawbot committed 2026-11-11 02:43:16 +01:00
1 parent ad36dd1775
commit f7e3190654
89 files changed
+1454 -1489

No files matched your search

+13 -13
View File
@@ -1,6 +1,6 @@
// Package config reads sww's settings, and is the one place they are
// read. Every setting is an environment variable. The settings of `sww
// discriminator` start with SWW_, every one of them has a default, and most can be
// waf` start with SWW_, every one of them has a default, and most can be
// given as a file instead. Those of `sww rproxy` start with SWRP_. Each
// of them but SWRP_WAF_BACKEND has a default, and none can be given as a file,
// since rproxy never touches disk. SWW_COMMAND chooses which of the two
@@ -32,10 +32,10 @@ import (
"sneak.berlin/go/smallwebwaf/internal/remotelog"
)
// Config is the settings of `sww discriminator`. A time or size limit of
// Config is the settings of `sww waf`. A time or size limit of
// zero is off.
type Config struct {
// ListenAddr is where discriminator listens (SWW_LISTEN_ADDR).
// ListenAddr is where waf listens (SWW_LISTEN_ADDR).
ListenAddr string
// InstanceName is the name every log line and alert gives as instance,
// and every metric carries as its label instance (SWW_INSTANCE_NAME),
@@ -239,7 +239,7 @@ type Config struct {
// attack (SWW_TRAP_PATHS), each starting with / and without a ?.
TrapPaths []string
// ErrorBurstThreshold is the most requests of a client within a minute
// that discriminator may refuse after a rule file or Core Rule Set match; one
// that waf may refuse after a rule file or Core Rule Set match; one
// more breaks a limit (SWW_ERROR_BURST_THRESHOLD). 0 is off.
ErrorBurstThreshold int64
// LogRemoteURL is where every line on stdout is also sent
@@ -378,8 +378,8 @@ var (
errNeedsDBPath = errors.New("it names the file to look clients up in")
errDBPathUnused = errors.New("only file reads it")
errOver64K = errors.New(
"is more than 64K, the most discriminator gets of a body")
errNotCommand = errors.New("is not rproxy or discriminator")
"is more than 64K, the most waf gets of a body")
errNotCommand = errors.New("is not rproxy or waf")
errNotDurationAboveZero = errors.New(
"is not a duration above zero, such as 1h or 7d")
errNotNumberAboveZero = errors.New(
@@ -627,7 +627,7 @@ func FromEnvironment(
}
// Command reads only SWW_COMMAND, the command the image runs and its
// health check checks: rproxy when it is unset or empty, or discriminator. It cannot
// health check checks: rproxy when it is unset or empty, or waf. It cannot
// be given as a file. Any other value is an error that names the setting.
func Command(lookupEnv func(string) (string, bool)) (string, error) {
command, _ := lookupEnv("SWW_COMMAND")
@@ -635,17 +635,17 @@ func Command(lookupEnv func(string) (string, bool)) (string, error) {
switch command {
case "", "rproxy":
return "rproxy", nil
case "discriminator":
case "waf":
return command, nil
default:
return "", fmt.Errorf("SWW_COMMAND: %q %w", command, errNotCommand)
}
}
// DiscriminatorListenAddr reads only SWW_LISTEN_ADDR, which may be given as a
// file, as FromEnvironment does. The health check in discriminator's container needs
// WAFListenAddr reads only SWW_LISTEN_ADDR, which may be given as a
// file, as FromEnvironment does. The health check in waf's container needs
// no other setting, so it reads no other, nor a file that another names.
func DiscriminatorListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
func WAFListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
env := &environment{lookupEnv: lookupEnv}
listenAddr := env.address("SWW_LISTEN_ADDR")
@@ -1610,7 +1610,7 @@ func parseSize(value string) (int64, error) {
}
// parseWAFBodyLimit reads the most of a request body the Core Rule Set
// reads: a size as parseSize reads it, or off, but at most 64K, since discriminator
// reads: a size as parseSize reads it, or off, but at most 64K, since waf
// gets no more of a body than that.
func parseWAFBodyLimit(value string) (int64, error) {
limit, err := parseSize(value)
@@ -1955,7 +1955,7 @@ func ParseASN(value string) (string, error) {
return "AS" + strconv.FormatUint(number, 10), nil
}
// The tags a request can get that the settings can name, as discriminator
// The tags a request can get that the settings can name, as waf
// writes them. The prefixes are followed by a value.
const (
ASNTagPrefix = "asn="
+2 -2
View File
@@ -636,11 +636,11 @@ func TestInvalidCoreRuleSetSettingStopsTheStart(t *testing.T) {
wafBodyLimit, "128KB",
`"128KB" is not a size such as 512K, 100M or 5G, or off`,
},
{wafBodyLimit, "65K", `"65K" is more than 64K, the most discriminator ` +
{wafBodyLimit, "65K", `"65K" is more than 64K, the most waf ` +
`gets of a body`},
{
wafBodyLimit, "65537",
`"65537" is more than 64K, the most discriminator gets of a body`,
`"65537" is more than 64K, the most waf gets of a body`,
},
} {
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
+6 -6
View File
@@ -22,12 +22,12 @@ type RProxy struct {
// TrustedProxies are the netblocks whose X-Forwarded-For is believed
// (SWRP_TRUSTED_PROXIES).
TrustedProxies []netip.Prefix
// WAFBackend is discriminator's URL (SWRP_WAF_BACKEND).
// WAFBackend is waf's URL (SWRP_WAF_BACKEND).
WAFBackend *url.URL
// Timeout is how long rproxy waits for discriminator's answer to a question,
// Timeout is how long rproxy waits for waf's answer to a question,
// and to a report (SWRP_TIMEOUT_MS). It cannot be off.
Timeout time.Duration
// DefaultDisposition is what is done with a request when discriminator cannot be
// DefaultDisposition is what is done with a request when waf cannot be
// connected to, does not answer at all, or does not answer within Timeout:
// allow or deny (SWRP_DEFAULT_DISPOSITION).
DefaultDisposition string
@@ -50,7 +50,7 @@ type RProxy struct {
var (
errNeedsWAFBackend = errors.New(
"is required: it is discriminator's URL, such as http://discriminator:8080")
"is required: it is waf's URL, such as http://waf:8080")
errNotDisposition = errors.New("is not allow or deny")
errNotMilliseconds = errors.New(
"is not a whole number of milliseconds above zero, such as 2000")
@@ -124,7 +124,7 @@ func (c *RProxy) LogValue() slog.Value {
return slog.GroupValue(c.settings...)
}
// wafBackend reads the setting that is discriminator's URL, which must be set.
// wafBackend reads the setting that is waf's URL, which must be set.
func (e *environment) wafBackend(name string) *url.URL {
value := e.value(name, "")
if value == "" {
@@ -139,7 +139,7 @@ func (e *environment) wafBackend(name string) *url.URL {
return backend
}
// disposition reads the setting that is what is done with a request when discriminator
// disposition reads the setting that is what is done with a request when waf
// cannot be connected to, does not answer at all, or does not answer in time:
// allow or deny.
func (e *environment) disposition(name, defaultValue string) string {
+3 -3
View File
@@ -24,7 +24,7 @@ const (
rproxyMaxResponse = "SWRP_MAX_RESPONSE_SIZE"
rproxyRequestTime = "SWRP_MAX_REQUEST_TIME_MS"
rproxyAnswerTime = "SWRP_MAX_RESPONSE_TIME_MS"
backendURL = "http://discriminator:8080"
backendURL = "http://waf:8080"
rproxyDefaultAddr = ":8080"
rproxyDefaultApp = "http://127.0.0.1:8081"
notASize = "a lot"
@@ -114,8 +114,8 @@ func TestRProxyInvalidSettingsAreRefused(t *testing.T) {
name, value string
}{
{wafBackend, ""},
{wafBackend, "discriminator:8080"},
{wafBackend, "http://discriminator:8080/path"},
{wafBackend, "waf:8080"},
{wafBackend, "http://waf:8080/path"},
{rproxyTimeout, "0"},
{rproxyTimeout, "-1"},
{rproxyTimeout, off},