{"id":1024,"date":"2026-08-31T23:12:58","date_gmt":"2026-08-31T23:12:58","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1024"},"modified":"2026-10-15T22:02:12","modified_gmt":"2026-10-15T22:02:12","slug":"vps-fail2ban-ssh-brute-force-protection","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/","title":{"rendered":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed attempts for ten minutes \u2014 which is enough to stop a naive credential-stuffing bot but does nothing against a distributed attack that rotates source IPs every few tries. This article goes past installation and shows how to measure what Fail2ban is actually doing on your host, tune the jail parameters against real evidence, and avoid locking out legitimate users in the process. If you are still picking infrastructure for this kind of hardening, it helps to <a href=\"https:\/\/virtualserversvps.com\/#providers\">compare VPS providers<\/a> that expose firewall and security-group controls.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What the Default SSH Jail Actually Does<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban tails log files through a filter, and when the filter regex matches enough failures inside a rolling window, the action bans the source IP for a defined duration. The three parameters that control this are the ones most people never touch:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>maxretry<\/code> \u2014 failures allowed before a ban<\/li><li><code>findtime<\/code> \u2014 the rolling window in which those failures must occur<\/li><li><code>bantime<\/code> \u2014 how long the ban lasts (<code>-1<\/code> means permanent until manually removed)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The stock values are <code>maxretry=5<\/code>, <code>findtime=10m<\/code>, <code>bantime=10m<\/code>. The problem with a 10-minute ban is that a patient attacker simply waits it out. A slow, distributed attempt that stays under five failures per IP will never trip the jail at all.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Measuring Before You Tune<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Never tune <code>maxretry<\/code> downward blindly \u2014 you will lock out your own team during a busy deploy. Start by measuring. <code>fail2ban-client status sshd<\/code> gives you the current banned count and the list of IPs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo fail2ban-client status sshd\nsudo fail2ban-client get sshd maxretry\nsudo fail2ban-client get sshd findtime\nsudo fail2ban-client get sshd bantime<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For trend data, the log is more useful than the live status. Count bans over the last 24 hours:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo grep 'Ban ' \/var\/log\/fail2ban.log | awk '{print $1}' | sort | uniq -c<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see a steady stream of bans and a large banned-IP list, the jail is working and the threat is constant. If the list stays near zero while your auth log shows thousands of failed attempts, the attackers are staying under your threshold \u2014 raise the ban duration and lower the window, not the attempt count.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Tuned SSH Jail Configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Put local overrides in <code>\/etc\/fail2ban\/jail.d\/sshd.local<\/code> so package upgrades do not clobber them. This configuration assumes key-based authentication is enforced separately and that you want aggressive bans without choking on false positives from a single flaky client:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[sshd]\nenabled  = true\nport     = ssh\nfilter   = sshd\nbackend  = systemd\nmaxretry = 4\nfindtime = 600\nbantime  = 86400\nignoreip = 127.0.0.1\/8 ::1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>bantime = 86400<\/code> (24 hours) is the key change. Most distributed attacks reuse the same hosts across a day; a one-day ban materially raises the attacker&#8217;s cost. <code>findtime = 600<\/code> tightens the rolling window so four failures inside ten minutes trip the jail. Always add your own management IPs to <code>ignoreip<\/code> \u2014 this is the single most common cause of self-lockout. If you manage servers with packet-level debugging tools, the same <a href=\"https:\/\/virtualserversvps.com\/blog\/tcpdump-tshark-diagnosing-tls-handshake-failures-vps\/\">tcpdump and tshark workflow<\/a> used for TLS troubleshooting applies to confirming which IPs are actually hitting port 22.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recidive: Catching Repeat Offenders<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A single jail only sees one service&#8217;s log. The <code>recidive<\/code> jail watches Fail2ban&#8217;s own log and bans IPs that trigger repeated bans across any service, for a much longer period:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[recidive]\nenabled  = true\nlogpath  = \/var\/log\/fail2ban.log\nmaxretry = 3\nfindtime = 86400\nbantime  = 604800<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">An IP banned three times in one day is not a user with a fat-fingered password \u2014 it is a scan host. A one-week recidive ban removes it from the game entirely.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Validating the Configuration and the Filter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before reloading, dry-run the parser against your real log to confirm the filter matches what your SSH daemon writes. This catches the classic case of a jail enabled but matching nothing because the log format changed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo fail2ban-regex \/var\/log\/auth.log \/etc\/fail2ban\/filter.d\/sshd.conf\nsudo systemctl reload fail2ban\nfail2ban-client status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The regex test prints a summary of matched versus missed lines. If the &#8220;Lines: matched&#8221; count is zero, your filter and your log backend are out of sync \u2014 an extremely common silent failure that makes administrators believe they are protected when they are not.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Safe Unbanning and Operational Habits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When you inevitably need to unban someone, do it by IP rather than by flushing the whole jail, so you keep the rest of the blocklist intact:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo fail2ban-client set sshd unbanip 203.0.113.7<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Two habits prevent almost every Fail2ban incident: whitelist a jump host or management IP in <code>ignoreip<\/code>, and ensure you have a console (out-of-band) access path so a bad jail rule can never lock you out permanently. Once the jail is proven, the same principle of enforcing limits at the kernel level extends beyond bans \u2014 <a href=\"https:\/\/virtualserversvps.com\/blog\/cgroups-v2-cap-memory-oversubscribed-vps\/\">capping memory with cgroups v2<\/a> applies the identical &#8220;define a hard boundary and measure it&#8221; mindset to resource exhaustion.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Takeaway<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban is not a set-and-forget tool. The default 10-minute ban is effectively decorative against modern distributed scanning. Measure your ban rate, tighten <code>findtime<\/code>, extend <code>bantime<\/code> to a full day, add a recidive jail for repeat offenders, and always verify the filter actually matches your log format. That combination turns a default installation into a genuine layer of defense \u2014 and the whitelist plus console-access habits ensure it never locks you out of your own server.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed attempts for ten minutes \u2014&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":4,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1024","post","type-post","status-publish","format-standard","hentry","category-security-compliance"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety - Virtual Servers VPS Blog<\/title>\n<meta name=\"description\" content=\"Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety\" \/>\n<meta property=\"og:description\" content=\"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-31T23:12:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-15T22:02:12+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/\",\"name\":\"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-08-31T23:12:58+00:00\",\"dateModified\":\"2026-10-15T22:02:12+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"description\":\"Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed\",\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety - Virtual Servers VPS Blog","description":"Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/","og_locale":"en_US","og_type":"article","og_title":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety","og_description":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety","og_url":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-08-31T23:12:58+00:00","article_modified_time":"2026-10-15T22:02:12+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/","url":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/","name":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-08-31T23:12:58+00:00","dateModified":"2026-10-15T22:02:12+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"description":"Most VPS operators install Fail2ban, enable the default SSH jail, and never look at it again. That default configuration bans an IP after five failed","breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/vps-fail2ban-ssh-brute-force-protection\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Fail2ban Tuning for SSH on a VPS: Jail Parameters, Metrics, and Lockout Safety"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1024","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1024"}],"version-history":[{"count":2,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1024\/revisions"}],"predecessor-version":[{"id":1405,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1024\/revisions\/1405"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}