Configuration

bantime, findtime and maxretry explained

Three numbers decide when fail2ban bans and for how long. Here is how they interact, what the defaults are, how to write times like 1d12h, and what to set for SSH, web and mail jails.

Updated 7 min readChecked against fail2ban 1.1.1

fail2ban bans an IP when it produces maxretry failures within findtime, and the ban lasts bantime. The stock defaults are maxretry = 5, findtime = 10m and bantime = 10m: five failed logins within ten minutes earn a ten-minute ban. Times accept seconds or abbreviations (30m, 1h, 1d, 1w, 1mo, 1y), and bantime = -1 bans permanently. Set them in /etc/fail2ban/jail.local.

/etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h     ; how long the ban lasts
findtime = 10m    ; the window in which failures are counted
maxretry = 5      ; failures in that window that trigger a ban

[sshd]
enabled  = true
maxretry = 3      ; stricter for SSH
bantime  = 1d

How bantime, findtime and maxretry interact#

Think of findtime as a window that slides along with time. For each IP, fail2ban counts the failures its filter matched in the last findtime. When the count reaches maxretry, the IP is banned for bantime, and its failure counter is cleared.

Example with maxretry = 5, findtime = 10m, bantime = 1h:

Time Event Failures counted Result
12:00 1st failed login from 203.0.113.42 1 —
12:02 2nd 2 —
12:05 3rd 3 —
12:07 4th 4 —
12:08 5th 5 Banned until 13:08
13:08 ban expires 0 Unbanned automatically

A slow attacker who makes 4 attempts, waits 15 minutes and tries again never reaches 5 within 10 minutes, so findtime is what you raise to catch low-and-slow brute force. A practical detail: fail2ban doesn't store a timestamp for every failure. It keeps a counter per IP and forgets the IP once its last failure is older than findtime; if failures keep trickling in over a longer span, it scales the count down to the rate per findtime. The result behaves like a sliding window, which is what you need to reason about values.

findtime is measured against the timestamps in the log lines, not the time fail2ban reads them. When fail2ban starts and reads an existing log, failures older than findtime are ignored.

The bantime calculator converts values to seconds and shows when a ban ends, including incremental bans.

Default values#

Option Stock default (jail.conf) Notes
bantime 10m (600 s) The "default ban time". Some jails override it, e.g. apache-badbots uses 48h, recidive uses 1w.
findtime 10m (600 s) recidive uses 1d.
maxretry 5 Several jails use 1 or 2 (bad bots, shellshock, postfix-rbl).

Distro packages usually keep these, but check /etc/fail2ban/jail.d/ and ask the running server:

output
$ sudo fail2ban-client get sshd bantime
3600
$ sudo fail2ban-client get sshd findtime
600
$ sudo fail2ban-client get sshd maxretry
3

get always prints seconds. This server overrides bantime to 1 hour and maxretry to 3 for sshd.

bantime format: seconds, minutes, days, weeks#

Every time option (bantime, findtime, bantime.maxtime, dbpurgeage…) accepts plain seconds or abbreviations:

Unit Write Example Seconds
seconds s, sec, second(s) 30s 30
minutes m, mm, min, minute(s) 10m 600
hours h, hh, hour(s) 1h 3600
days d, dd, day(s) 1d 86400
weeks w, ww, week(s) 1w 604800
months mo, mon, month(s) 1mo 2629800 (30.44 days)
years y, yy, year(s) 1y 31557600 (365.25 days)
  • Combine units: 1d12h = 129600, 1h30m = 5400, 1y 6mo = 1.5 years. Expressions work too: 1hour+30min.
  • m is minutes, not months. 1m is 60 seconds; a month is 1mo.
  • Plain numbers are seconds: bantime = 3600 is the same as 1h.

Check a value before you use it:

bash
fail2ban-client --str2sec 1d12h

It prints the number of seconds (129600 here).

Common bantime values#

You want Write
1 hour bantime = 1h
1 day bantime = 1d (or 86400)
1 week bantime = 1w
1 month bantime = 1mo
1 year bantime = 1y
Permanent bantime = -1

Permanent bans: bantime = -1#

bantime = -1 means the ban never expires. Only exactly -1 is treated as permanent; other negative numbers are not. Permanent bans survive restarts (they're stored in /var/lib/fail2ban/fail2ban.sqlite3) and stay until you unban the IP by hand.

Think twice before making a busy jail permanent: botnet IPs are reused and reassigned, the ban list grows forever, and a legitimate user who mistyped a password five times is locked out for good. Two better ways to be harsh on repeat offenders:

  • Incremental bans: every new ban of the same IP is longer (1h, 2h, 4h…), up to a cap.
  • The recidive jail: IPs banned again and again by other jails get a long, all-ports ban.

If you do want permanent bans, use them where false positives are near impossible, such as a recidive jail or a honeypot port.

What do maxretry = 0 and bantime = 0 do?#

  • maxretry = 0 does not disable banning. The check is "failures ≥ maxretry", so the first matching line bans the IP, exactly like maxretry = 1. To stop a jail from banning, disable the jail (enabled = false) or whitelist the addresses.
  • bantime = 0 is not permanent: the ban expires at once and the IP is unbanned within seconds. Use -1 for permanent.
  • maxretry = 1 is legitimate for filters where a single match is unambiguous (exploit attempts, honeypots, postfix-rbl).

Starting points, not rules. Tighten them if your logs show attacks getting through, loosen them if real users get banned.

Jail maxretry findtime bantime Why
sshd (keys only, passwords disabled) 3 10m 1h + increment Legitimate users don't fail key auth repeatedly
sshd (passwords allowed) 5 10m 1h + increment Leave room for typos
nginx-http-auth, apache-auth 5 10m 1h Humans mistype; browsers retry
nginx-botsearch, apache-botsearch 2 10m 1d Scanners, no human hits these paths
postfix-sasl, dovecot 5 10m 1h Mail clients retry saved wrong passwords
Web app logins (WordPress, Nextcloud…) 5 10m 1h Shared office IPs: don't be too strict
recidive 5 1d 1w Stock values; catches repeat offenders

Two rules of thumb:

  • findtime ≥ the interval between attempts you want to catch. Many botnets space attempts minutes apart; findtime = 1h with maxretry = 5 catches them where 10m doesn't. A longer window also keeps more IPs in memory, which is rarely an issue.
  • Pair a moderate bantime with bantime.increment instead of one very long ban. First-time offenders (often your own users) are released quickly; persistent attackers escalate to days.

Set values per jail#

Values in [DEFAULT] apply to every jail; a value in a jail section replaces it for that jail only:

/etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled  = true
maxretry = 3

[nginx-botsearch]
enabled  = true
maxretry = 2
bantime  = 1d

[postfix-sasl]
enabled  = true
findtime = 1h

Apply with sudo fail2ban-client reload. You can also change values on the running server for testing (lost at the next reload or restart):

output
$ sudo fail2ban-client set sshd bantime 86400
86400

Current bans that weren't individually extended by bantime.increment follow the jail's bantime, so raising or lowering it also moves their expiry. Check when each current ban ends:

output
$ sudo fail2ban-client get sshd banip --with-time
203.0.113.42 	2026-10-25 18:36:10 + 3600 = 2026-10-25 19:36:10
192.0.2.15 	2026-10-25 18:36:14 + 3600 = 2026-10-25 19:36:14
192.0.2.16 	2026-10-25 18:36:14 + 3600 = 2026-10-25 19:36:14

Each line reads: banned at 18:36:10, for 3600 seconds, released at 19:36:10.

FAQ#

What is findtime in fail2ban?#

findtime is the time window in which failures are counted. An IP is banned when it reaches maxretry failures within the last findtime. With the defaults (findtime = 10m, maxretry = 5), five failures in ten minutes cause a ban; failures spread over a longer period don't.

What is the default ban time in fail2ban?#

bantime = 10m (600 seconds) in the stock jail.conf. Some predefined jails override it, for example recidive bans for 1w. Check your effective value with sudo fail2ban-client get sshd bantime, which prints seconds.

How do I set bantime to 1 day, 1 week or 1 year?#

Use abbreviations in jail.local: bantime = 1d, bantime = 1w, bantime = 1y (or the seconds: 86400, 604800). For months write 1mo, because 1m means one minute. Units combine, e.g. 1d12h. Reload with sudo fail2ban-client reload.

What does maxretry = 0 do?#

It bans on the first failure, exactly like maxretry = 1, because fail2ban bans when the failure count is greater than or equal to maxretry. It does not disable the jail. To stop a jail from banning, set enabled = false.

Does changing bantime affect IPs that are already banned?#

Usually yes. In the running server, a ban without its own ban time (one not extended by bantime.increment) expires at ban start plus the jail's current bantime. Verify with sudo fail2ban-client get <jail> banip --with-time. To end bans immediately, use fail2ban-client unban <IP> or unban --all.

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