Escalating expiration

Use ladder() in Expires in, on the Add to list action, to keep a value on the list longer with each repeat offence. For example, an IP blocked for the first time leaves the list after 1 hour, and a repeat-offending IP stays for 2 days.

Syntax

ladder(<index>, <expiration>, <expiration>, ...)
  • Index: a field ($attempts) or a reading published by an earlier action (%blocks.cells.ip.value), with a numeric value. A fixed number, such as ladder(1, 1h, 4h), is rejected when the rule is saved.
  • Expirations: from 1 to 10 expirations, each a whole number followed by m, h or d. Each expiration is between 5m and 2 years.

The index picks the expiration by position, counted from 0:

Index Expiration picked
0 the first
1, 2, … the expiration at that position
past the last expiration the last
decimal rounded down: 2.7 picks position 2
missing or negative the first

With ladder(%blocks.cells.ip.value, 1h, 4h, 16h), index 0 picks 1 hour, index 1 picks 4 hours and index 2 or higher picks 16 hours.

Blocking repeat offenders

The index is usually the count of earlier blocks of the same value. The blocks analysis has a no-trigger cell ip, which counts events by $ip over 30 days. The rule records an event in that analysis only when the IP actually enters the list:

Condition 1:  "ip_velocity" in %risk.triggered_cells
Actions:      Run analysis: blocks                               (result: blocks)
              Add to list → $ip to @blocked_ips,
                expires in ladder(%blocks.cells.ip.value, 1h, 4h, 16h, 2d)   (result: ip_blocked)

Condition 2:  %ip_blocked.added == true
Actions:      Record analysis: blocks

The action’s Result field publishes %ip_blocked.added. The reading is true only when the run put the IP on the list. While the IP is on the list, the following events read false and do not count as a new block. In a burst of events from the same IP, only one run reads true.

The ip cell thus counts the IP’s blocks, not each suspicious event:

Block Count in the ip cell Expiration on the list
first 0 1 hour
second 1 4 hours
third 2 16 hours
fourth onwards 3 or more 2 days

The cell’s window defines how long a block counts as a repeat offence. In the example, an IP with no blocks in 30 days goes back to the 1-hour expiration.

Points to consider

  • The expiration never shortens: if the value is already on the list, the run keeps the longer of the current expiration and the one picked, as described in Add to list.
  • Observation and simulation do not write to the list: in observation and in simulation, the action does not add the value and does not publish the result.