diff --git a/ban/service.go b/ban/service.go index 54b6c7b5..fd97e9e2 100644 --- a/ban/service.go +++ b/ban/service.go @@ -20,9 +20,9 @@ const ( pruneInterval = 10 * time.Minute writeInterval = 3 * time.Second - // strikeUnits is how finely strikes are counted: weights go down to 0.01 (e.g. 0.05 = 20 hits + // strikeUnits is how finely strikes are counted: weights go down to 0.001 (e.g. 0.05 = 20 hits // make one strike), and the token bucket only takes whole tokens - strikeUnits = 100 + strikeUnits = 1000 ) // Config is the Service's config, kept separate from server.Config to avoid an import cycle. diff --git a/ban/weights.go b/ban/weights.go index ae297b5c..f587a5f0 100644 --- a/ban/weights.go +++ b/ban/weights.go @@ -12,7 +12,7 @@ type Weights map[string]float64 // ParseWeights normalizes a list like ["42909:10","403:2","50701:0.05","*:1"] into a Weights map. A key is an // exact ntfy code, a family ("429*"), a bare HTTP status ("403" -> "403*"), or "*"; weights are ints -// >= 0 in steps of 0.01 (0 = exempt). Malformed entries are rejected so misconfiguration fails at startup. +// >= 0 in steps of 0.001 (0 = exempt). Malformed entries are rejected so misconfiguration fails at startup. func ParseWeights(entries []string) (Weights, error) { out := make(Weights, len(entries)) for _, entry := range entries { diff --git a/ban/weights_test.go b/ban/weights_test.go index d24df839..5094cb3a 100644 --- a/ban/weights_test.go +++ b/ban/weights_test.go @@ -44,7 +44,10 @@ func TestParseWeights_Fractional(t *testing.T) { require.Nil(t, err) require.Equal(t, 0.05, weights.WeightFor(50701)) require.Equal(t, 2.0, weights.WeightFor(42909)) - _, err = ParseWeights([]string{"50701:0.001"}) // Below the 0.01 resolution + weights, err = ParseWeights([]string{"50701:0.001"}) + require.Nil(t, err) + require.Equal(t, 0.001, weights.WeightFor(50701)) + _, err = ParseWeights([]string{"50701:0.0001"}) // Below the 0.001 resolution require.Error(t, err) } diff --git a/docs/config.md b/docs/config.md index a3acdf38..5ff9ff38 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2221,7 +2221,7 @@ every line is already a confirmed offender, the fail2ban jail can ban on first s ntfy error code (`42909`), a code family (`429*`, `403*`, `4*`), a bare HTTP status (`403`, short for `403*`), or `*`. The longest matching key wins. A weight of `0` exempts a code entirely (it never counts toward a ban), useful to spare a specific code from a `*` catch-all. Heavier weights ban faster; - weights may be fractional down to `0.01` (e.g. `0.05`: 20 rejections make one strike). If you do not + weights may be fractional down to `0.001` (e.g. `0.05`: 20 rejections make one strike). If you do not include a `*` rule, any code that matches nothing defaults to weight `1` (i.e. it can be banned); set `*:0` to exempt everything that is not explicitly weighted. diff --git a/docs/releases.md b/docs/releases.md index 738266c8..6f906ae1 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -2323,7 +2323,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release **Behavior changes:** -* Ban feed: weights may be fractional (down to `0.01`), auth failures (`42909`) now weigh 2 instead of 10, and a UnifiedPush push without a subscriber (`50701`) weighs 0.05, so app servers pushing to many offline phones are not banned for it +* Ban feed: weights may be fractional (down to `0.001`), auth failures (`42909`) now weigh 2 instead of 10, and a UnifiedPush push without a subscriber (`50701`) weighs 0.05, so app servers pushing to many offline phones are not banned for it * The rate limit state of a visitor is forgotten about a minute after it has fully recovered (all buckets refilled) instead of after a day without use, which frees the memory of one-off visitors such as floods of new IPs. The `visitors` stat and the `ntfy_visitors_total` metric therefore count the visitors of roughly the last minute, not of the last day ([#2126](https://github.com/binwiederhier/ntfy/pull/2126)) **Bug fixes + maintenance:**