Count ban strikes in thousandths, so weights go down to 0.001

This commit is contained in:
binwiederhier committed 2026-11-02 01:11:46 +00:00
1 parent b9f9c562a5
commit 093012dc8d
5 files changed
+9 -6

No files matched your search

+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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 {
+4 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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:**