Configuration

Incremental ban time with bantime.increment

Give first-time offenders a short ban and repeat attackers a long one, automatically. This page explains every bantime.* option, shows the exact ban lengths you get, and the database setting most guides forget.

Updated 7 min readChecked against fail2ban 1.1.1

To make fail2ban ban repeat offenders for longer, set bantime.increment = true in /etc/fail2ban/jail.local. The first ban of an IP lasts bantime; each later ban of the same IP doubles it (2×, 4×, 8×…) until it reaches bantime.maxtime. fail2ban counts previous bans in its SQLite database, so the database must be enabled (it is by default), and dbpurgeage decides how long an IP is remembered.

/etc/fail2ban/jail.local
[DEFAULT]
bantime            = 1h     ; first ban
bantime.increment  = true   ; repeat bans grow: 1h, 2h, 4h, 8h…
bantime.factor     = 1
bantime.maxtime    = 1w     ; never longer than a week
/etc/fail2ban/fail2ban.local
[Definition]
dbpurgeage = 30d            ; remember previous bans for a month
bash
sudo fail2ban-client reload

All bantime.* options#

These options are commented out in the stock jail.conf. Set them in [DEFAULT] for every jail or inside a single jail.

Option Default Meaning
bantime.increment off Turn incremental bans on (true).
bantime 10m The first ban and the base for every increase.
bantime.factor 1 Coefficient in the formula, or multiplier applied to bantime.multipliers.
bantime.formula ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor Python expression for the next ban time. Ignored when bantime.multipliers is set.
bantime.multipliers unset Space-separated multipliers used instead of the formula, e.g. 1 2 4 8 16 32 64.
bantime.maxtime unset (no cap) Maximum length of an increased ban.
bantime.rndtime unset Adds a random 0…N seconds to each increased ban, so bots can't predict the exact unban time.
bantime.overalljails false true counts the IP's previous bans in all jails, not only the current one.

Time values accept the usual format (1h, 1d, 1w, 5w); see time format.

How the next ban time is calculated#

When a jail bans an IP, fail2ban looks it up in the database (bips table) to find how many times it was banned before. That number is ban.Count.

  1. First ban (no previous ban recorded): the ban lasts exactly bantime. No factor, formula or multiplier is applied.
  2. Repeat ban (ban.Count ≥ 1): - Without multipliers: bantime × 2^ban.Count × factor (the exponent stops growing at 20), and never less than bantime. - With bantime.multipliers: bantime × factor × multipliers[ban.Count]. When the count runs past the end of the list, the last multiplier is used.
  3. The result is capped at bantime.maxtime, if set.
  4. A random 0…bantime.rndtime seconds is added, if set.

Because the list is indexed by the count of previous bans, the first multiplier is never used for a repeat ban. Keep it at 1 so the list reads naturally.

Previously banned IPs are also banned faster. While an IP has ban history, each new failure from it counts more than once (2× after one ban, 3× after two, 5× after three, and so on, up to maxretry). A known attacker coming back is often banned on its first or second failure.

Worked examples#

The bantime calculator does these calculations for any values. Here are the common setups.

Default formula, bantime = 1h, factor = 1, maxtime = 1w#

Ban # ban.Count Calculation Ban length
1 — bantime 1h
2 1 1h × 2 2h
3 2 1h × 4 4h
4 3 1h × 8 8h
5 4 1h × 16 16h
6 5 1h × 32 1d 8h
7 6 1h × 64 2d 16h
8 7 1h × 128 5d 8h
9+ 8+ 1h × 256 → capped 1w

Same, with factor = 2#

bantime.factor multiplies every repeat ban, so the growth starts one step ahead:

Ban # Ban length (bantime = 1h)
1 1h
2 4h
3 8h
4 16h
5 1d 8h
6 2d 16h

Multipliers 1 2 4 8 16 32 64, bantime = 10m#

This is the example from jail.conf. It grows like the formula, but stops at the last multiplier (64 × 10m = 10h 40m) without needing maxtime:

Ban # Multiplier Ban length
1 — 10m
2 2 20m
3 4 40m
4 8 1h 20m
5 16 2h 40m
6 32 5h 20m
7+ 64 10h 40m

Aggressive multipliers for a short first ban#

The second example in jail.conf, intended for bantime = 1m:

ini
bantime             = 1m
bantime.multipliers = 1 5 30 60 300 720 1440 2880

Bans run 1 min, 5 min, 30 min, 1 h, 5 h, 12 h, 1 day, then 2 days for every further ban.

How long fail2ban remembers an IP (dbpurgeage)#

This is where most incremental setups quietly fail. Ban history lives in /var/lib/fail2ban/fail2ban.sqlite3, and a purge runs every hour. An IP's last ban record is deleted once dbpurgeage plus three times that ban's length has passed since the ban started. Permanent bans (-1) are never purged.

With the stock dbpurgeage = 1d:

Last ban length IP forgotten after
1h 1d 3h
8h 2d
1d 4d

So a bot that comes back a week later starts again at ban #1. To remember repeat offenders for longer, raise dbpurgeage in fail2ban.local (details on the fail2ban.conf page):

/etc/fail2ban/fail2ban.local
[Definition]
dbpurgeage = 30d

A larger value makes the database bigger, but it holds one row per banned IP per jail, which is small even on busy servers. Check the current value:

output
$ sudo fail2ban-client get dbpurgeage
Current database purge age is:
`- 86400seconds

Two more things reset the history:

  • Unbanning by hand (fail2ban-client unban <IP> or set <jail> unbanip <IP>) deletes the IP's records from the database, so its next ban counts as the first. See unban an IP.
  • No database. With dbfile = :memory: the history is lost at every restart; with dbfile = None incremental bans don't work at all and fail2ban logs ban time increment is not available as long jail database is not set.

bantime.overalljails: count bans across jails#

By default an IP banned by sshd and later by postfix-sasl starts at ban #1 in each jail. With bantime.overalljails = true, fail2ban adds up the IP's bans in every jail, so an attacker probing several services escalates faster:

ini
[DEFAULT]
bantime.increment    = true
bantime.overalljails = true

The ban itself is still per jail: each jail blocks its own ports. For an all-ports ban of repeat offenders, use recidive.

bantime.increment vs recidive#

Both punish repeat offenders; they work differently and combine well.

Feature bantime.increment recidive jail
Trigger Same IP banned again by the same jail (or any jail with overalljails) IP banned maxretry times within findtime across jails, read from fail2ban's log
Effect Longer ban in the original jail, on its ports Separate ban on all ports
Needs The database (default) fail2ban's own log in a file or the journal
Tuning factor, multipliers, maxtime, dbpurgeage bantime, findtime, maxretry of [recidive]

A common setup is increment in [DEFAULT] with a cap of one week, plus recidive for an all-ports ban. Remember that bantime.maxtime in [DEFAULT] also caps recidive's repeat bans; give [recidive] its own bantime.maxtime if you want them to exceed it. The jail.local example shows the full combination.

Permanent bans for repeat offenders#

To ban an IP forever after a certain number of bans, use multipliers and make the last step huge, or rely on a permanent recidive jail. There's no "-1" multiplier, but a very large one has the same practical effect:

/etc/fail2ban/jail.local
[sshd]
enabled             = true
bantime             = 1h
bantime.increment   = true
# 1h, 1d, 1w, then about 10 years
bantime.multipliers = 1 24 168 87600

For a true -1 ban, enable [recidive] with bantime = -1. That's simpler to reason about and survives dbpurgeage, because permanent bans are never purged.

Check that it works#

fail2ban logs the increase when it extends a ban. Watch for Increase Ban lines in /var/log/fail2ban.log:

bash
sudo grep -E "Increase Ban|is bad" /var/log/fail2ban.log | tail

And the effective ban length of each banned IP:

bash
sudo fail2ban-client get sshd banip --with-time

The + <seconds> part of each line is that ban's individual length, which grows for repeat offenders.

FAQ#

How do I enable incremental ban time in fail2ban?#

Add bantime.increment = true to [DEFAULT] (or one jail) in /etc/fail2ban/jail.local, optionally with bantime.factor, bantime.maxtime and bantime.multipliers, then run sudo fail2ban-client reload. The database must be enabled (dbfile in fail2ban.conf, on by default).

What does bantime.factor do?#

It multiplies repeat bans. With the default formula, the second ban is bantime × 2 × factor, the third bantime × 4 × factor, and so on. factor = 1 doubles each time; factor = 2 starts at 4×. The first ban is always the plain bantime.

Why does bantime.increment not work?#

The usual causes: it isn't enabled in the jail that bans (check sudo fail2ban-client -d | grep increment), the database is disabled (dbfile = :memory: or None), the IP was forgotten because dbpurgeage (default 1 day) expired, or it was unbanned manually, which deletes its history.

What is the maximum ban time with bantime.increment?#

Whatever bantime.maxtime is set to. Without it, the default formula keeps doubling until the exponent reaches 20 (about a million times bantime), and multipliers stop at the last value in the list. Always set bantime.maxtime unless your multipliers already end where you want.

Does bantime.increment work across jails?#

Only with bantime.overalljails = true. By default an IP's previous bans are counted per jail. With overalljails, bans from every jail are added together, but the resulting ban still applies only to the jail that triggered it.

Spotted something wrong or out of date? Tell us — every page is checked against the current fail2ban release.