Banned prefixes, with expiry.
A ban is keyed on the same prefix every other piece of state uses (see
Limen.IP.prefix/3), so checking one is a single ETS lookup. Expired bans
are ignored on lookup and removed later by Limen.State.Sweeper.
Each ban records the mode of whatever created it. A ban created by a policy in dry-run mode is looked up and reported exactly like any other, but never enforced, so a dry-run policy can never block traffic, not even through state it leaves behind.
A ban's action says what banned clients get: :deny (a 403) or :maze
(the slow pages of Limen.Maze, for clients caught by a Limen.Trap).
The list holds at most :max_bans entries; further bans are refused.
When clustering is enabled (see Limen.Cluster), bans and unbans made on
this node are also queued for broadcast; bans received from other nodes
are not broadcast again.
Summary
Functions
Bans prefix for ttl seconds.
Lists active bans, soonest to expire first.
Returns the active ban for prefix at now (milliseconds), if any.
Removes expired bans and returns how many were removed.
Lifts the ban on prefix.
Types
@type action() :: :deny | :maze
@type ban() :: %{ prefix: Limen.IP.prefix(), expires_at: integer(), reason: term(), mode: :dry_run | :enforce, origin: origin(), action: action() }
@type origin() :: :policy | :admin | :trap | :remote
Functions
@spec ban(Limen.Instance.t(), Limen.IP.prefix(), pos_integer(), keyword()) :: :ok | {:error, :full}
Bans prefix for ttl seconds.
If the prefix is already banned, the ban is extended when the new one lasts
longer, escalated to :enforce when either ban enforces, and to the maze
when either sends there: a client caught in a trap stays caught. Bans of
the same prefix made at the same time all take effect.
Options
:reason- recorded with the ban and reported in decisions.:mode-:enforce(default) or:dry_run.:action-:deny(default) or:maze.:origin-:policy,:admin(default),:trapor:remote.:now- the current system time in milliseconds.
@spec list(Limen.Instance.t(), integer()) :: [ban()]
Lists active bans, soonest to expire first.
@spec lookup(Limen.Instance.t(), Limen.IP.prefix() | nil, integer()) :: ban() | nil
Returns the active ban for prefix at now (milliseconds), if any.
@spec sweep(Limen.Instance.t(), integer()) :: non_neg_integer()
Removes expired bans and returns how many were removed.
@spec unban(Limen.Instance.t(), Limen.IP.prefix(), keyword()) :: :ok
Lifts the ban on prefix.