Rename the program to sww and its deciding daemon to discriminator
check / check (push) Successful in 5m33s
check / check (push) Successful in 5m33s
The program is now sww, built from cmd/sww, with two modes: sww rproxy and sww discriminator. servewaf becomes discriminator everywhere it names that daemon: the package (internal/discriminator), its types, functions, files, the discriminator_line log field, and its docs and tests. smallwebwaf is left only where sneak's directive allows it: the documents' product name, the git.eeqj.de/sneak/smallwebwaf URLs, and the Go module path sneak.berlin/go/smallwebwaf. Everywhere else a name containing it takes the sww form: the package (internal/sww), metric names (sww_*), the X-Sww-* headers, the /_sww/ admin endpoints, the SWW_COMMAND setting, the OS user, and the state and rules directories. No logic changes. make check passes. Model: deepseek-v4-pro
This commit is contained in:
1 parent
7fed6b6d36
commit
d8f417b00b
97 files changed
+1945
-1912
No files matched your search
+26
-26
@@ -1,9 +1,9 @@
|
||||
// Package config reads smallwebwaf's settings, and is the one place they are
|
||||
// read. Every setting is an environment variable. The settings of `smallwebwaf
|
||||
// servewaf` start with SWWAF_, every one of them has a default, and most can be
|
||||
// given as a file instead. Those of `smallwebwaf rproxy` start with SWRP_. Each
|
||||
// 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 SWWAF_, 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. SMALLWEBWAF_COMMAND chooses which of the two
|
||||
// since rproxy never touches disk. SWW_COMMAND chooses which of the two
|
||||
// the image runs.
|
||||
package config
|
||||
|
||||
@@ -31,10 +31,10 @@ import (
|
||||
"sneak.berlin/go/smallwebwaf/internal/remotelog"
|
||||
)
|
||||
|
||||
// Config is the settings of `smallwebwaf servewaf`. A time or size limit of
|
||||
// Config is the settings of `sww discriminator`. A time or size limit of
|
||||
// zero is off.
|
||||
type Config struct {
|
||||
// ListenAddr is where servewaf listens (SWWAF_LISTEN_ADDR).
|
||||
// ListenAddr is where discriminator listens (SWWAF_LISTEN_ADDR).
|
||||
ListenAddr string
|
||||
// InstanceName is the name every log line and alert gives as instance,
|
||||
// and every metric carries as its label instance (SWWAF_INSTANCE_NAME),
|
||||
@@ -199,7 +199,7 @@ type Config struct {
|
||||
// written (SWWAF_LOG_LEVEL). It holds back no request log line.
|
||||
LogLevel slog.Level
|
||||
// AdminToken is the bearer token an admin sends for the ban endpoints
|
||||
// and /_smallwebwaf/clients/<ip> (SWWAF_ADMIN_TOKEN), "" while it is
|
||||
// and /_sww/clients/<ip> (SWWAF_ADMIN_TOKEN), "" while it is
|
||||
// unset and they are off.
|
||||
AdminToken string
|
||||
// MetricsToken is the bearer token a scraper sends for the metrics
|
||||
@@ -231,7 +231,7 @@ type Config struct {
|
||||
// attack (SWWAF_TRAP_PATHS), each starting with / and without a ?.
|
||||
TrapPaths []string
|
||||
// ErrorBurstThreshold is the most requests of a client within a minute
|
||||
// that servewaf may refuse after a rule file or Core Rule Set match; one
|
||||
// that discriminator may refuse after a rule file or Core Rule Set match; one
|
||||
// more breaks a limit (SWWAF_ERROR_BURST_THRESHOLD). 0 is off.
|
||||
ErrorBurstThreshold int64
|
||||
// LogRemoteURL is where every line on stdout is also sent
|
||||
@@ -327,7 +327,7 @@ const (
|
||||
// maxParanoiaLevel is the Core Rule Set's highest paranoia level.
|
||||
maxParanoiaLevel = 4
|
||||
// firstSetupRuleID to lastSetupRuleID are the ids the Core Rule Set
|
||||
// keeps for the rules that set it up, which smallwebwaf's own rules
|
||||
// keeps for the rules that set it up, which sww's own rules
|
||||
// have too (see internal/waf). Switching one off would undo a change
|
||||
// that no setting undoes.
|
||||
firstSetupRuleID = 900000
|
||||
@@ -370,8 +370,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 servewaf gets of a body")
|
||||
errNotCommand = errors.New("is not rproxy or servewaf")
|
||||
"is more than 64K, the most discriminator gets of a body")
|
||||
errNotCommand = errors.New("is not rproxy or discriminator")
|
||||
errNotDurationAboveZero = errors.New(
|
||||
"is not a duration above zero, such as 1h or 7d")
|
||||
errNotNumberAboveZero = errors.New(
|
||||
@@ -387,7 +387,7 @@ var (
|
||||
errNotNamedNetblock = errors.New(
|
||||
"is not a name, = and a netblock, such as office=203.0.113.0/24")
|
||||
errNotAbsolutePath = errors.New(
|
||||
"is not an absolute path, such as /var/lib/smallwebwaf")
|
||||
"is not an absolute path, such as /var/lib/sww")
|
||||
errShortToken = errors.New("is shorter than 32 characters")
|
||||
errNotMode = errors.New("is not enforce or observe")
|
||||
errNotBytesCount = errors.New("is not response, request or both")
|
||||
@@ -401,7 +401,7 @@ var (
|
||||
"is not the id of a Core Rule Set rule, a whole number such as 942100")
|
||||
errSetupRuleID = errors.New(
|
||||
"is from 900000 to 900999, the ids of the rules that set the Core Rule Set " +
|
||||
"up and of smallwebwaf's own, which cannot be switched off")
|
||||
"up and of sww's own, which cannot be switched off")
|
||||
errNotBoolean = errors.New("is not true or false")
|
||||
errNotLogRemoteURL = errors.New(
|
||||
"is not syslog+udp, syslog+tcp or syslog+tls with a host and a port, " +
|
||||
@@ -413,7 +413,7 @@ var (
|
||||
errSetTwice = errors.New("set only one of them")
|
||||
errNotWebhookURL = errors.New(
|
||||
"is not an http or https URL without a user or a fragment, " +
|
||||
"such as https://alerts.example/smallwebwaf")
|
||||
"such as https://alerts.example/sww")
|
||||
errNotWebhookHeader = errors.New(
|
||||
"is not a header name followed by : and the header's value, " +
|
||||
"such as Authorization:Bearer <token>")
|
||||
@@ -507,7 +507,7 @@ func FromEnvironment(lookupEnv func(string) (string, bool)) (*Config, error) {
|
||||
AttackBanDuration: env.durationNotOff("SWWAF_ATTACK_BAN_DURATION", "7d"),
|
||||
MaxBans: env.numberNotOff("SWWAF_MAX_BANS", "5000"),
|
||||
BanScopeV4Prefix: env.v4Prefix("SWWAF_BAN_SCOPE_V4_PREFIX", "32"),
|
||||
StateDir: env.absolutePath("SWWAF_STATE_DIR", "/var/lib/smallwebwaf"),
|
||||
StateDir: env.absolutePath("SWWAF_STATE_DIR", "/var/lib/sww"),
|
||||
StateWriteDelay: env.durationNotOff("SWWAF_STATE_WRITE_DELAY", "10s"),
|
||||
StateCounterInterval: env.durationNotOff("SWWAF_STATE_COUNTER_INTERVAL", "15m"),
|
||||
LogRequestHeaders: env.headerNames("SWWAF_LOG_REQUEST_HEADERS",
|
||||
@@ -516,7 +516,7 @@ func FromEnvironment(lookupEnv func(string) (string, bool)) (*Config, error) {
|
||||
AdminToken: env.token("SWWAF_ADMIN_TOKEN"),
|
||||
MetricsToken: env.token("SWWAF_METRICS_TOKEN"),
|
||||
MetricsTopN: env.numberNotOff("SWWAF_METRICS_TOP_N", "50"),
|
||||
RulesDir: env.value("SWWAF_RULES_DIR", "/etc/smallwebwaf/rules.d"),
|
||||
RulesDir: env.value("SWWAF_RULES_DIR", "/etc/sww/rules.d"),
|
||||
RulesEnabled: env.boolean("SWWAF_RULES_ENABLED", "true"),
|
||||
WAFMode: env.wafMode("SWWAF_WAF_MODE", WAFModeBlock),
|
||||
WAFParanoiaLevel: env.paranoiaLevel("SWWAF_WAF_PARANOIA_LEVEL", "1"),
|
||||
@@ -572,26 +572,26 @@ func FromEnvironment(lookupEnv func(string) (string, bool)) (*Config, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// Command reads only SMALLWEBWAF_COMMAND, the command the image runs and its
|
||||
// health check checks: rproxy when it is unset or empty, or servewaf. It cannot
|
||||
// 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
|
||||
// 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("SMALLWEBWAF_COMMAND")
|
||||
command, _ := lookupEnv("SWW_COMMAND")
|
||||
|
||||
switch command {
|
||||
case "", "rproxy":
|
||||
return "rproxy", nil
|
||||
case "servewaf":
|
||||
case "discriminator":
|
||||
return command, nil
|
||||
default:
|
||||
return "", fmt.Errorf("SMALLWEBWAF_COMMAND: %q %w", command, errNotCommand)
|
||||
return "", fmt.Errorf("SWW_COMMAND: %q %w", command, errNotCommand)
|
||||
}
|
||||
}
|
||||
|
||||
// ServeWAFListenAddr reads only SWWAF_LISTEN_ADDR, which may be given as a
|
||||
// file, as FromEnvironment does. The health check in servewaf's container needs
|
||||
// DiscriminatorListenAddr reads only SWWAF_LISTEN_ADDR, which may be given as a
|
||||
// file, as FromEnvironment does. The health check in discriminator's container needs
|
||||
// no other setting, so it reads no other, nor a file that another names.
|
||||
func ServeWAFListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
func DiscriminatorListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
|
||||
env := &environment{lookupEnv: lookupEnv}
|
||||
listenAddr := env.address("SWWAF_LISTEN_ADDR")
|
||||
|
||||
@@ -1395,7 +1395,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 servewaf
|
||||
// reads: a size as parseSize reads it, or off, but at most 64K, since discriminator
|
||||
// gets no more of a body than that.
|
||||
func parseWAFBodyLimit(value string) (int64, error) {
|
||||
limit, err := parseSize(value)
|
||||
|
||||
Reference in new issue
Block a user