Read every setting through viper and rename the settings (closes #211)
check / check (push) Failing after 3m27s

Every setting of discriminator and rproxy is read through viper, in place
of the os.LookupEnv function Main passed down. NewViper turns AutomaticEnv
and AllowEmptyEnv on, so a setting that is set but empty reads as set. A
setting may also be given as a file, the _FILE form, which rproxy's
settings now have too; rproxy still writes nothing to disk.

The settings are renamed. Discriminator's take the prefix SWW_WAF_,
rproxy's take SWW_RPROXY_, and the shared SWW_COMMAND keeps SWW_. The Core
Rule Set's settings take SWW_WAF_CORE_RULE_SET_ rather than SWW_WAF_WAF_.
Every place a name appeared changed: the code, the viper keys, tests,
documents, examples, the README's settings table and the image files.

Model: deepseek-v4-pro
This commit is contained in:
sneak committed 2026-11-07 06:41:11 +00:00
1 parent beb503b233
commit 68da92f414
89 files changed
+2027 -1916

No files matched your search

+16 -16
View File
@@ -23,12 +23,12 @@ import (
// The reputation settings.
const (
blocklistURLs = "SWW_BLOCKLIST_URLS"
blocklistAction = "SWW_BLOCKLIST_ACTION"
asnLimitPercentURL = "SWW_ASN_LIMIT_PERCENT_URL"
blocklistURLs = "SWW_WAF_BLOCKLIST_URLS"
blocklistAction = "SWW_WAF_BLOCKLIST_ACTION"
asnLimitPercentURL = "SWW_WAF_ASN_LIMIT_PERCENT_URL"
)
// The actions of SWW_BLOCKLIST_ACTION and SWW_REPUTATION_ACTION:
// The actions of SWW_WAF_BLOCKLIST_ACTION and SWW_WAF_REPUTATION_ACTION:
// limitHalf gives a listed client half of every limit, and limitQuarter a
// quarter.
const (
@@ -127,7 +127,7 @@ func TestBlocklistsComeAfterTheCountryListsAndSkipAllowNets(t *testing.T) {
loadLists(t, server, map[string][]string{dropURL: {fromDE, fromKP}})
// fromKP's country refuses it before the list is looked at, and fromDE,
// in SWW_ALLOW_NETS, is not checked at all: neither is noted, nor
// in SWW_WAF_ALLOW_NETS, is not checked at all: neither is noted, nor
// alerted.
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionCountryDenied))
wantReputation(t, s.get(fromDE, http.StatusOK, requestlog.ActionForward))
@@ -224,7 +224,7 @@ func TestASNLimitPercentFileCountsAsTheSettingDoesTheLowerWinning(t *testing.T)
},
{"none, for an AS number the file does not list", nil, asnKP + ":25", none, none},
{
"SWW_ASN_BYTES_PERCENT's in place of the file's for the byte limits",
"SWW_WAF_ASN_BYTES_PERCENT's in place of the file's for the byte limits",
map[string]string{asnBytesPercent: asnDE + ":100"}, asnDEQuarter, fromURL, none,
},
} {
@@ -312,9 +312,9 @@ func TestEachBlocklistThatListsAClientRaisesAnAlertOncePerCooldownAndIsCounted(
// The DNSBL settings.
const (
dnsblZones = "SWW_DNSBL_ZONES"
dnsblResolver = "SWW_DNSBL_RESOLVER"
reputationAction = "SWW_REPUTATION_ACTION"
dnsblZones = "SWW_WAF_DNSBL_ZONES"
dnsblResolver = "SWW_WAF_DNSBL_RESOLVER"
reputationAction = "SWW_WAF_REPUTATION_ACTION"
)
// The DNSBL zones these tests name, which are never asked about the
@@ -370,7 +370,7 @@ func TestEachReputationActionForAClientADNSBLZoneLists(t *testing.T) {
for _, from := range []string{fromDE, fromKP} {
for i := range 3 {
line := s.get(from, tc.statuses[i], tc.actions[i])
// In the order SWW_DNSBL_ZONES names them.
// In the order SWW_WAF_DNSBL_ZONES names them.
wantReputation(t, line, listedBy[from]...)
wantPercent(t, "limit_percent", line.LimitPercent,
line.LimitPercentSetting, tc.percent)
@@ -416,7 +416,7 @@ func TestDNSBLZonesComeAfterTheBlocklistsAndSkipAllowNets(t *testing.T) {
loadVerdicts(server, map[string][]string{fromKP: {dnsblZone}, fromDE: {dnsblZone}})
// The blocklist refuses fromKP before its verdict is looked at, and
// fromDE, in SWW_ALLOW_NETS, is not checked at all: neither is noted
// fromDE, in SWW_WAF_ALLOW_NETS, is not checked at all: neither is noted
// for the zone, nor alerted, nor asked about.
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionDenied),
dropURL)
@@ -609,7 +609,7 @@ func TestRequestFromAClientWithoutAVerdictHasTheZoneAskedAboutIt(t *testing.T) {
// The AbuseIPDB settings, and accountKey, the key the tests set.
const (
abuseIPDBKey = "SWW_ABUSEIPDB_KEY"
abuseIPDBKey = "SWW_WAF_ABUSEIPDB_KEY"
accountKey = "abuseipdb-key-0123456789abcdef"
)
@@ -800,7 +800,7 @@ func TestEachReputationActionForAClientAbuseIPDBScoresAtOrOverTheMinimum(t *test
rateLimitPerMinute: fourAMinute, abuseIPDBKey: accountKey,
reputationAction: tc.action,
})
// At SWW_ABUSEIPDB_MIN_SCORE, 75 by default, and just under it.
// At SWW_WAF_ABUSEIPDB_MIN_SCORE, 75 by default, and just under it.
loadScores(server, map[string]int64{fromDE: 75, fromKP: 74})
for i := range 3 {
@@ -851,7 +851,7 @@ func TestAbuseIPDBHitRaisesAnAlertWithTheScoreOncePerCooldownAndIsCounted(
// The alert is made as a DNSBL zone's is, with the score besides.
waiting := queue.Snapshot().Waiting[alerts.DestinationWebhook]
if len(waiting) != 1 || waiting[0].Event != alerts.EventReputationHit ||
waiting[0].Reason != "scored by AbuseIPDB at or over SWW_ABUSEIPDB_MIN_SCORE" ||
waiting[0].Reason != "scored by AbuseIPDB at or over SWW_WAF_ABUSEIPDB_MIN_SCORE" ||
waiting[0].Detail["source"] != abuseipdb || waiting[0].Detail["score"] != int64(90) ||
queue.Suppressed() != 1 {
t.Errorf("alerts waiting %+v, %d held back, want AbuseIPDB's reputation_hit "+
@@ -922,7 +922,7 @@ func TestBanNotesNameEachReputationSourceThatListedTheClient(t *testing.T) {
abuseIPDBKey: accountKey, reputationAction: actionLog,
})
// Every source lists client, and none otherClient, whose score is
// under SWW_ABUSEIPDB_MIN_SCORE, 75 by default.
// under SWW_WAF_ABUSEIPDB_MIN_SCORE, 75 by default.
loadLists(t, server, map[string][]string{dropURL: {client}})
loadVerdicts(server, map[string][]string{client: {dnsblZone}, otherClient: nil})
loadScores(server, map[string]int64{client: score, otherClient: 74})
@@ -971,7 +971,7 @@ func verdictsFetched() time.Time {
}
// loadVerdicts puts into server's DNSBL, for each client listedBy names,
// a verdict of each zone SWW_DNSBL_ZONES names, fetched at
// a verdict of each zone SWW_WAF_DNSBL_ZONES names, fetched at
// verdictsFetched, as reputation.json would at start: one that lists the
// client from each zone listedBy gives for it, and one that does not from
// each other zone.