{"id":881,"date":"2026-08-13T23:49:36","date_gmt":"2026-08-13T23:49:36","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=881"},"modified":"2026-08-19T22:12:36","modified_gmt":"2026-08-19T22:12:36","slug":"fail2ban-setup-linux-vps-ssh-security","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/","title":{"rendered":"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Any Linux VPS with SSH exposed to the internet starts collecting brute-force attempts within hours of its first boot. A typical fresh instance sees thousands of failed logins per day from scripted dictionaries and botnets. Fail2ban is the standard, low-cost defense: it watches log files, counts failures per source IP, and temporarily bans offenders via the firewall. This guide walks through a safe setup for SSH and web logins \u2014 including the whitelisting and testing steps that keep you from locking yourself out of your own server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How fail2ban works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban runs a daemon that tails log files (by default <code>\/var\/log\/auth.log<\/code> on Debian and Ubuntu), matches entries against regex filters, and increments a counter per source IP. When the counter crosses <code>maxretry<\/code> within <code>findtime<\/code> seconds, it applies a jail action \u2014 usually adding a firewall rule that drops traffic from that IP for <code>bantime<\/code> seconds. It is reactive, not preventive: it does not stop the first few attempts, but it makes sustained brute force impractical and keeps your logs readable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install and enable<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>sudo apt update &amp;&amp; sudo apt install -y fail2ban<\/code><\/li>\n<li><code>sudo systemctl enable --now fail2ban<\/code><\/li>\n<li><code>sudo systemctl status fail2ban<\/code> \u2014 confirm it is active (running)<\/li>\n<li><code>sudo fail2ban-client status<\/code> \u2014 the default <code>sshd<\/code> jail should be listed<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">On Ubuntu 22.04+, Debian 12, and newer images, fail2ban detects the host firewall backend automatically and uses <code>nftables<\/code> when the system firewall is nftables-based (which includes default ufw on modern Ubuntu). It coexists with ufw cleanly; just avoid enabling both the iptables and nftables backends at the same time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The config model: jail.conf vs jail.local<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Never edit <code>\/etc\/fail2ban\/jail.conf<\/code> directly \u2014 package updates overwrite it. Put your overrides in <code>\/etc\/fail2ban\/jail.local<\/code>. The settings that matter most:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Setting<\/th><th>Default<\/th><th>Practical recommendation<\/th><\/tr><\/thead><tbody><tr><td><code>bantime<\/code><\/td><td>10m<\/td><td>1h\u201324h for SSH; longer for repeat offenders<\/td><\/tr><tr><td><code>findtime<\/code><\/td><td>10m<\/td><td>Time window in which failures are counted<\/td><\/tr><tr><td><code>maxretry<\/code><\/td><td>5<\/td><td>3\u20135 for SSH<\/td><\/tr><tr><td><code>ignoreip<\/code><\/td><td>127.0.0.1\/8<\/td><td>Add your own static IP \u2014 never ban yourself<\/td><\/tr><tr><td><code>backend<\/code><\/td><td>auto<\/td><td><code>systemd<\/code> reads from journald, immune to log rotation issues<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Lock down SSH without locking yourself out<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Whitelist your static IP first. In <code>\/etc\/fail2ban\/jail.local<\/code>, set <code>ignoreip = 127.0.0.1\/8 ::1 203.0.113.7<\/code> (replace with your real IP) under the <code>[sshd]<\/code> section.<\/li>\n<li>Restart the service: <code>sudo systemctl restart fail2ban<\/code><\/li>\n<li>Verify the jail is loaded: <code>sudo fail2ban-client status sshd<\/code><\/li>\n<li>Test a ban manually: <code>sudo fail2ban-client set sshd banip 198.51.100.23<\/code>, then <code>sudo fail2ban-client set sshd unbanip 198.51.100.23<\/code>.<\/li>\n<li>Optional: set <code>bantime.increment = true<\/code> so repeat offenders get progressively longer bans.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Two extra steps make SSH much quieter: switch to key-based authentication and set <code>PasswordAuthentication no<\/code> in <code>\/etc\/ssh\/sshd_config<\/code>. Fail2ban then only needs to cover the remaining fallback paths, and the volume of log noise drops sharply. If you administer many servers from one office IP, keep that IP in <code>ignoreip<\/code> on every host.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Protect web logins too<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH is not the only brute-force target. WordPress, phpMyAdmin, and other web logins get hammered as well, and fail2ban ships jails for the common cases:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>nginx-http-auth<\/code> \u2014 bans IPs that fail HTTP basic auth repeatedly (log: <code>\/var\/log\/nginx\/error.log<\/code>)<\/li>\n<li><code>apache-badbots<\/code> \/ <code>nginx-botsearch<\/code> \u2014 bans known bad bots and bogus request patterns<\/li>\n<li><code>wordpress<\/code> \u2014 a community filter matching repeated <code>wp-login.php<\/code> failures<\/li>\n<li><code>recidive<\/code> \u2014 a meta-jail that gives longer bans to IPs banned in multiple other jails<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Enable any of these by adding the jail name to <code>enabled<\/code> in <code>jail.local<\/code> and pointing <code>logpath<\/code> at the real log file, then verify with <code>sudo fail2ban-client status nginx-http-auth<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing without drama<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List banned IPs: <code>sudo fail2ban-client status sshd<\/code><\/li>\n<li>Verify the firewall action end to end with a manual <code>banip<\/code>\/<code>unbanip<\/code>.<\/li>\n<li>Simulate failures: attempt three wrong passwords (<code>ssh baduser@your-server<\/code>) and watch <code>sudo tail -f \/var\/log\/fail2ban.log<\/code> for the ban event.<\/li>\n<li>If you ban yourself: connect through your provider&#8217;s out-of-band console (VNC or browser terminal) and run <code>sudo fail2ban-client unbanip YOUR_IP<\/code>, or flush the chain directly \u2014 the chain name is shown in <code>fail2ban-client status sshd<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Jail never bans:<\/strong> the <code>logpath<\/code> is wrong or logrotate truncated the file \u2014 switch to <code>backend = systemd<\/code> to read from journald instead.<\/li>\n<li><strong>Bans disappear after reboot:<\/strong> bans are in-memory by default; that is normal. Ensure <code>systemctl enable fail2ban<\/code> so the service itself survives reboots.<\/li>\n<li><strong>Clock drift:<\/strong> fail2ban is time-sensitive. Keep chrony or NTP running, or <code>findtime<\/code> windows and ban expiry misbehave.<\/li>\n<li><strong>High CPU from fail2ban:<\/strong> usually log scanning over huge files \u2014 rotate logs and exclude noisy services from filters.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban is not a replacement for key-only SSH and a properly configured firewall \u2014 it is the layer that absorbs the noise. Combined with automatic security updates, it covers the two most common ways VPSes get compromised. And when you pick a host, <a href=\"https:\/\/virtualserversvps.com\/#providers\">compare providers on our comparison table<\/a> for the basics, then <a href=\"https:\/\/virtualserversvps.com\/#features\">see the full specs and pricing<\/a> before committing \u2014 a provider with out-of-band console access turns &#8220;I banned myself&#8221; into a five-minute fix instead of a support ticket.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Any Linux VPS with SSH exposed to the internet starts collecting brute-force attempts within hours of its first boot. A typical fresh instance sees thousands of failed logins per day&#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":1,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-881","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 Attacks Without Locking Yourself Out - 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-linux-vps-ssh-security\/\" \/>\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 Attacks Without Locking Yourself Out\" \/>\n<meta property=\"og:description\" content=\"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-13T23:49:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-19T22:12:36+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\/fail2ban-setup-linux-vps-ssh-security\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/\",\"name\":\"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-08-13T23:49:36+00:00\",\"dateModified\":\"2026-08-19T22:12:36+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out\"}]},{\"@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 Attacks Without Locking Yourself Out - 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-linux-vps-ssh-security\/","og_locale":"en_US","og_type":"article","og_title":"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out","og_description":"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out","og_url":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-08-13T23:49:36+00:00","article_modified_time":"2026-08-19T22:12:36+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\/fail2ban-setup-linux-vps-ssh-security\/","url":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/","name":"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-08-13T23:49:36+00:00","dateModified":"2026-08-19T22:12:36+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/fail2ban-setup-linux-vps-ssh-security\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Fail2ban on a VPS: Block SSH Attacks Without Locking Yourself Out"}]},{"@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\/881","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=881"}],"version-history":[{"count":2,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/881\/revisions"}],"predecessor-version":[{"id":921,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/881\/revisions\/921"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}