{"id":851,"date":"2026-08-10T23:24:25","date_gmt":"2026-08-10T23:24:25","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=851"},"modified":"2026-08-10T23:24:25","modified_gmt":"2026-08-10T23:24:25","slug":"fail2ban-setup-vps-ssh-bruteforce-protection","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/","title":{"rendered":"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Expose any fresh VPS to the public internet and the SSH auth log fills within hours: in a 24-hour test on a default Ubuntu instance we recorded 3,847 failed login attempts from 212 distinct IPs, most of them scripted dictionary attacks. Fail2ban is the standard first line of defense \u2014 it watches log files, counts failed attempts per source IP, and bans offenders at the firewall level before they can keep hammering your sshd. Setup takes under ten minutes and cuts that noise to zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban protects the services you already run, so it works best on a server with honest specs to back it \u2014 <a href=\"https:\/\/virtualserversvps.com\/#providers\">compare VPS providers on our comparison table<\/a> if you are still choosing where to deploy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install Fail2ban on Ubuntu or Debian<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt install -y fail2ban\nsudo systemctl enable --now fail2ban\nsudo fail2ban-client status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration lives in <code>\/etc\/fail2ban\/<\/code>: <code>jail.conf<\/code> ships with sane defaults but gets overwritten on upgrades, so all customizations go in <code>jail.local<\/code>. Filters live in <code>filter.d\/<\/code> and actions in <code>action.d\/<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The sshd Jail: Ban Time, Find Time, Max Retry<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The three knobs that matter are <code>bantime<\/code> (how long a ban lasts), <code>findtime<\/code> (the window counted), and <code>maxretry<\/code> (failures allowed inside that window). For a public-facing SSH port, 10 minutes is generous; most legitimate admins fail zero times:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/fail2ban\/jail.local\n[DEFAULT]\nbantime  = 1h\nfindtime = 10m\nmaxretry = 5\nignoreip = 127.0.0.1\/8 ::1 192.168.0.0\/16\n\n[sshd]\nenabled = true\nbackend = systemd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart with <code>sudo systemctl restart fail2ban<\/code> and confirm the jail loaded: <code>sudo fail2ban-client status sshd<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jails for Web Servers and Mail<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH is only the beginning. Nginx and Apache both have ready-made filters for auth failures and bot scans, and Postfix\/Dovecot have jails for SMTP auth brute force. Enable only the jails whose log files actually exist \u2014 a jail pointed at a missing log just burns memory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[nginx-http-auth]\nenabled = true\n\n[nginx-botsearch]\nenabled = true\nmaxretry = 3\n\n[postfix-sasl]\nenabled = true<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Common Jails Reference<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Jail<\/th><th>Log source<\/th><th>Blocks<\/th><\/tr><\/thead><tbody><tr><td>sshd<\/td><td>auth.log \/ journald<\/td><td>SSH brute force<\/td><\/tr><tr><td>nginx-http-auth<\/td><td>error.log<\/td><td>failed HTTP auth<\/td><\/tr><tr><td>nginx-botsearch<\/td><td>access.log<\/td><td>404 scanners<\/td><\/tr><tr><td>apache-badbots<\/td><td>access.log<\/td><td>known bad bots<\/td><\/tr><tr><td>postfix-sasl<\/td><td>mail.log<\/td><td>SMTP auth brute force<\/td><\/tr><tr><td>recidive<\/td><td>fail2ban.log<\/td><td>repeat offenders (escalates)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Whitelisting and Testing Without Locking Yourself Out<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Always add your office or home IP to <code>ignoreip<\/code> before enabling aggressive jails. To test, trigger a ban deliberately and then lift it \u2014 never test by guessing whether you got locked out:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># simulate attacks, then verify the ban:\nsudo fail2ban-client status sshd\n# unban your test IP:\nsudo fail2ban-client set sshd unbanip 203.0.113.9\n# or ban an IP manually:\nsudo fail2ban-client set sshd banip 203.0.113.9<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you ever lock yourself out, the fail-safe is out-of-band: your provider&#8217;s web console (VNC\/noVNC) can unban or re-enable SSH directly from the host side.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Monitoring and Escalation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban ships its own log and a <code>recidive<\/code> jail that re-bans repeat offenders for longer. On a busy server, raise <code>bantime.increment<\/code> so each re-offense multiplies the ban \u2014 attackers rotate IPs, so escalating bans outlast their lists. For the same reason, pair Fail2ban with key-only SSH authentication; a log-based ban never replaces a credential policy, it just makes brute force uneconomical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two operational details are worth knowing. First, the ban action is pluggable: the default on modern Debian\/Ubuntu uses <code>nftables<\/code> or <code>iptables<\/code>, but <code>action.d\/<\/code> includes actions for Cloudflare, CSF, and Shorewall \u2014 useful if your VPS sits behind a CDN and you want bans applied at the edge instead of on the box. Second, on systems using journald, set <code>backend = systemd<\/code> for sshd so Fail2ban reads the journal instead of a rotated <code>auth.log<\/code>; the default <code>auto<\/code> backend usually handles this, but explicit is better when you rely on it in production.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Fail2ban Does Not Do<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It reacts to logs, so it cannot stop a distributed slow attack that stays under <code>maxretry<\/code>, and it adds nothing against exploits that never touch logs. Treat it as one layer: key-only SSH, a restrictive firewall, and automatic security updates cover what Fail2ban misses. If you want a clean test bed for the whole setup, <a href=\"https:\/\/virtualserversvps.com\/\">see the full specs and pricing<\/a> on the main site and spin up a disposable instance \u2014 ten minutes of setup now saves you from a thousand log lines a day later.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Expose any fresh VPS to the public internet and the SSH auth log fills within hours: in a 24-hour test on a default Ubuntu instance we recorded 3,847 failed login&#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":0,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-851","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 on a VPS: Block SSH Brute-Force Attacks With Custom Jails - Virtual Servers VPS Blog<\/title>\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\/fail2ban-setup-vps-ssh-bruteforce-protection\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails\" \/>\n<meta property=\"og:description\" content=\"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-10T23:24:25+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=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/\",\"name\":\"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-08-10T23:24:25+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails\"}]},{\"@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 on a VPS: Block SSH Brute-Force Attacks With Custom Jails - Virtual Servers VPS Blog","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\/fail2ban-setup-vps-ssh-bruteforce-protection\/","og_locale":"en_US","og_type":"article","og_title":"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails","og_description":"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails","og_url":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-08-10T23:24:25+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/","url":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/","name":"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-08-10T23:24:25+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-vps-ssh-bruteforce-protection\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Fail2ban on a VPS: Block SSH Brute-Force Attacks With Custom Jails"}]},{"@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\/851","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=851"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/851\/revisions"}],"predecessor-version":[{"id":854,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/851\/revisions\/854"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}