{"id":1842,"date":"2026-09-05T09:24:30","date_gmt":"2026-09-05T03:54:30","guid":{"rendered":"https:\/\/cpanelfree.com\/blog\/how-to-secure-linux-vps-fail2ban-ufw-ssh\/"},"modified":"2026-09-05T12:57:44","modified_gmt":"2026-09-05T07:27:44","slug":"how-to-secure-linux-vps-fail2ban-ufw-ssh","status":"publish","type":"post","link":"https:\/\/cpanelfree.com\/blog\/how-to-secure-linux-vps-fail2ban-ufw-ssh\/","title":{"rendered":"How to Secure and Harden a Linux Cloud VPS: UFW, Fail2ban &amp; SSH Hardening Checklist"},"content":{"rendered":"<h2>The Reality of Public Internet Scanners &amp; Automated Attack Bots<\/h2>\n<p>The moment you launch a fresh Linux VPS and assign it a public IPv4 address, automated malicious botnets and vulnerability scanners begin probing your server within minutes. These automated crawlers execute tens of thousands of dictionary attacks against default SSH port 22, scan for open database ports (3306, 5432), probe for unpatched Redis instances (6379), and search for exposed web panel login portals.<\/p>\n<p>Leaving a production server with default root passwords or unrestricted firewall policies is an invitation to malware compromise, ransomware extortion, and botnet recruitment. By implementing a layered defense strategy comprising unprivileged sudo users, ed25519 SSH cryptographic keys, a strict UFW firewall, and automated Fail2ban intrusion prevention, you eliminate 99.9% of automated cyber threats.<\/p>\n<p>In this enterprise hardening guide, we will step through locking down a fresh Ubuntu 24.04\/22.04 LTS server from scratch.<\/p>\n<h2>Step 1: Creating a Dedicated Sudo User and Disabling Root Login<\/h2>\n<p>Direct login as the <code>root<\/code> superuser should always be disabled. Create a dedicated administrative user account with granular <code>sudo<\/code> privileges:<\/p>\n<pre><code># Create a new administrative user\nadduser devadmin\n\n# Add user to sudo group\nusermod -aG sudo devadmin\n\n# Copy SSH authorized keys from root to new user\nmkdir -p \/home\/devadmin\/.ssh\ncp \/root\/.ssh\/authorized_keys \/home\/devadmin\/.ssh\/\nchown -R devadmin:devadmin \/home\/devadmin\/.ssh\nchmod 700 \/home\/devadmin\/.ssh\nchmod 600 \/home\/devadmin\/.ssh\/authorized_keys<\/code><\/pre>\n<h2>Step 2: Cryptographic SSH Hardening (Disabling Password Authentication)<\/h2>\n<p>Password authentication allows brute-force dictionary bots to hammer your server continuously. Enforce cryptographic public key authentication only by editing <code>\/etc\/ssh\/sshd_config<\/code>:<\/p>\n<pre><code># Custom SSH Port (Optional but reduces automated bot noise by 95%)\nPort 2222\n\n# Permit root login restrictions\nPermitRootLogin no\n\n# Enforce public key authentication only\nPubkeyAuthentication yes\nPasswordAuthentication no\nPermitEmptyPasswords no\n\n# Disconnect idle sessions after 10 minutes\nClientAliveInterval 300\nClientAliveCountMax 2\n\n# Disable X11 forwarding\nX11Forwarding no<\/code><\/pre>\n<p>Test the SSH configuration before restarting the service:<\/p>\n<pre><code># Verify syntax for errors\nsudo sshd -t\n\n# Restart SSH daemon safely\nsudo systemctl restart ssh<\/code><\/pre>\n<h2>Step 3: Configuring UFW (Uncomplicated Firewall)<\/h2>\n<p>Enforce a strict default-deny inbound network policy. Allow only essential web traffic (HTTP 80, HTTPS 443) and your designated SSH port:<\/p>\n<pre><code># Set default firewall rules\nsudo ufw default deny incoming\nsudo ufw default allow outgoing\n\n# Allow SSH on your configured port (e.g. 2222 or 22)\nsudo ufw allow 2222\/tcp comment 'SSH Port'\n\n# Allow standard web server traffic\nsudo ufw allow 80\/tcp comment 'HTTP Web'\nsudo ufw allow 443\/tcp comment 'HTTPS SSL Web'\n\n# Enable firewall\nsudo ufw enable\n\n# Verify active status\nsudo ufw status verbose<\/code><\/pre>\n<h2>Step 4: Installing and Configuring Fail2ban Intrusion Prevention<\/h2>\n<p><strong>Fail2ban<\/strong> dynamically monitors server authentication log files (such as <code>\/var\/log\/auth.log<\/code> or Nginx access logs). When an IP address fails authentication multiple times within a short window, Fail2ban automatically modifies firewall rules to ban the offending IP address for a configurable duration.<\/p>\n<pre><code># Install Fail2ban daemon\nsudo apt install -y fail2ban\n\n# Create local override configuration\nsudo cp \/etc\/fail2ban\/jail.conf \/etc\/fail2ban\/jail.local<\/code><\/pre>\n<p>Edit <code>\/etc\/fail2ban\/jail.local<\/code> to configure aggressive ban times:<\/p>\n<pre><code>[DEFAULT]\n# Ban IP for 24 hours after repeated offenses\nbantime = 86400\n\n# Look back window of 10 minutes\nfindtime = 600\n\n# Maximum failed attempts before banning\nmaxretry = 4\n\n# Ignore local loopback\nignoreip = 127.0.0.1\/8 ::1\n\n[sshd]\nenabled = true\nport = 2222\nlogpath = %(sshd_log)s\nbackend = systemd<\/code><\/pre>\n<p>Restart Fail2ban and verify active jail status:<\/p>\n<pre><code>sudo systemctl restart fail2ban\nsudo fail2ban-client status sshd<\/code><\/pre>\n<h2>Step 5: Enabling Automated Unattended Security Patches<\/h2>\n<p>Ensure that critical Linux kernel and package CVE vulnerabilities are patched automatically without requiring manual intervention:<\/p>\n<pre><code># Install unattended upgrades package\nsudo apt install -y unattended-upgrades\n\n# Enable automated security patching\nsudo dpkg-reconfigure -plow unattended-upgrades<\/code><\/pre>\n<h2>VPS Security Hardening Checklist Summary<\/h2>\n<table style=\"width: 100%;border-collapse: collapse;margin: 20px 0;border: 1px solid #334155\">\n<thead>\n<tr style=\"background-color: #0f172a;color: #38bdf8\">\n<th style=\"padding: 12px;border: 1px solid #334155\">Hardening Step<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Security Impact<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Verification Command<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Dedicated Sudo User<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Eliminates direct root exploits<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>whoami &amp;&amp; groups<\/code><\/td>\n<\/tr>\n<tr style=\"background-color: #0f172a;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Ed25519 SSH Keys Only<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Stops dictionary brute-force attacks<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>ssh -o PubkeyAuthentication=no user@ip<\/code><\/td>\n<\/tr>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>UFW Firewall (Deny Inbound)<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Blocks unauthorized port scanning<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>sudo ufw status verbose<\/code><\/td>\n<\/tr>\n<tr style=\"background-color: #0f172a;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Fail2ban Auto-Banning<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Dynamically blacklists abusive botnets<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>sudo fail2ban-client status<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Configuring Granular Fail2ban Jails for Nginx &amp; Bad Bots<\/h2>\n<p>In addition to SSH protection, you can configure Fail2ban to block web vulnerability scanners and DDoS scrapers that attempt SQL injection or probe for non-existent admin URLs (e.g., <code>\/wp-login.php<\/code> on non-WordPress sites or <code>\/phpmyadmin<\/code>). Edit <code>\/etc\/fail2ban\/jail.local<\/code>:<\/p>\n<pre><code>[nginx-http-auth]\nenabled = true\nport = http,https\nlogpath = \/var\/log\/nginx\/error.log\n\n[nginx-botsearch]\nenabled = true\nport = http,https\nlogpath = \/var\/log\/nginx\/access.log\nmaxretry = 3\nfindtime = 300\nbantime = 86400\n\n[nginx-limit-req]\nenabled = true\nport = http,https\nlogpath = \/var\/log\/nginx\/error.log\nfindtime = 600\nbantime = 7200<\/code><\/pre>\n<h2>Auditing Active Listening Network Ports with ss and lsof<\/h2>\n<p>Perform regular network port audits to ensure no unexpected processes are listening on public interfaces:<\/p>\n<pre><code># Check all listening TCP\/UDP sockets with process names\nsudo ss -tulpn\n\n# Inspect open file handles for network sockets\nsudo lsof -i -P -n | grep LISTEN<\/code><\/pre>\n<h2>Automated Security Alerting via Telegram \/ Discord Webhooks<\/h2>\n<p>Configure Fail2ban action scripts to post real-time alerts whenever a malicious IP address is banned:<\/p>\n<pre><code># Test ban action notification\nsudo fail2ban-client set sshd banip 198.51.100.1\nsudo fail2ban-client status sshd<\/code><\/pre>\n<div style=\"background-color: #0f172a;border-left: 4px solid #38bdf8;padding: 18px 24px;margin: 30px 0;border-radius: 8px\">\n<h3 style=\"color: #38bdf8;margin-top: 0\">Recommended Related Technical Guides<\/h3>\n<ul style=\"margin-bottom: 0;color: #cbd5e1\">\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/top-10-essential-linux-terminal-commands-webmasters-2026\/\" style=\"color: #38bdf8;text-decoration: underline\">Top 10 Essential Linux Terminal Commands for Webmasters<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-setup-free-ssl-certificate-lets-encrypt-certbot-apache-nginx\/\" style=\"color: #38bdf8;text-decoration: underline\">Securing Web Servers with Let&#8217;s Encrypt SSL &amp; Certbot<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-run-docker-docker-compose-cheap-linux-vps\/\" style=\"color: #38bdf8;text-decoration: underline\">Running Containerized Workloads Securely on Linux VPS<\/a><\/li>\n<\/ul>\n<\/div>\n<div style=\"background: linear-gradient(135deg, #0284c7 0%, #0369a1 100%);color: #ffffff;padding: 28px;border-radius: 12px;margin: 35px 0;text-align: center\">\n<h3 style=\"color: #ffffff;margin-top: 0;font-size: 22px\">Deploy on Fortress-Grade CpanelFree Cloud Infrastructure<\/h3>\n<p style=\"color: #e0f2fe;font-size: 15px;max-width: 650px;margin: 0 auto 18px auto\">Protect your mission-critical applications with enterprise DDoS mitigation, automated firewall management, and 100% free hosting and VPS options.<\/p>\n<p>  <a href=\"https:\/\/cpanelfree.com\/\" style=\"background-color: #ffffff;color: #0284c7;font-weight: 700;padding: 12px 28px;border-radius: 8px;text-decoration: none;display: inline-block\">Deploy Free Secure Hosting &rarr;<\/a>\n<\/div>\n<div style=\"border-left: 4px solid #38bdf8;border-radius: 8px;padding: 20px;margin: 30px 0\">\n<h3 style=\"margin-top: 0;color: #38bdf8;font-size: 18px;display: flex;align-items: center\">\n        <span style=\"margin-right: 8px\">\ud83d\udd17<\/span> Recommended Related Technical Guides:<br \/>\n    <\/h3>\n<ul style=\"margin: 10px 0 0 0;padding-left: 20px;line-height: 1.8\">\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-get-free-cloud-vps-forever\/\" style=\"color: #38bdf8;text-decoration: none;font-weight: 600\">How to Get a Free Cloud VPS Forever (Oracle, Google Cloud, AWS Free Tier)<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/oracle-cloud-always-free-vps-setup-guide\/\" style=\"color: #38bdf8;text-decoration: none;font-weight: 600\">Oracle Cloud Always Free VPS: Step-by-Step Setup &amp; ARM Ampere Guide<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/best-cheap-cloud-vps-providers\/\" style=\"color: #38bdf8;text-decoration: none;font-weight: 600\">Top 7 Best Cheap Cloud VPS Providers in 2026 (Under $5\/Month)<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-setup-vector-database-qdrant-ai-embeddings-vps\/\" style=\"color: #38bdf8;text-decoration: none;font-weight: 600\">How to Self-Host Qdrant Vector Database on Ubuntu VPS for AI LLM Semantic Search<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/#plans\" style=\"color: #10b981;text-decoration: none;font-weight: 600\">Explore $0 Free cPanel Web Hosting Plans (NVMe SSD, AutoSSL)<\/a><\/li>\n<\/ul>\n<\/div>\n<div style=\"background: linear-gradient(135deg, rgba(6, 182, 212, 0.15) 0%, rgba(59, 130, 246, 0.15) 100%);border-radius: 12px;padding: 25px;margin: 30px 0;text-align: center\">\n<h3 style=\"color: #38bdf8;margin-top: 0;font-size: 20px\">Deploy Fast, Reliable Web Hosting on CpanelFree<\/h3>\n<p style=\"color: #94a3b8;font-size: 14px;line-height: 1.6;max-width: 600px;margin: 0 auto 15px\">\n        Get genuine cPanel control, unmetered NVMe SSD storage, and free AutoSSL at $0 cost forever.\n    <\/p>\n<p>    <a href=\"https:\/\/cpanelfree.com\/#plans\" style=\"display: inline-block;background: linear-gradient(135deg, #0284c7 0%, #0369a1 100%);color: #ffffff;padding: 10px 22px;border-radius: 6px;text-decoration: none;font-weight: bold;font-size: 14px\">Claim Free Hosting Account<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Reality of Public Internet Scanners &amp; Automated Attack Bots The moment you launch a fresh Linux VPS and assign it a public IPv4 address, automated malicious botnets and vulnerability scanners begin probing your server within minutes. These automated crawlers execute tens of thousands of dictionary attacks against default SSH port 22, scan for open [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2493,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88],"tags":[],"class_list":["post-1842","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-vps"],"_links":{"self":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/1842","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/comments?post=1842"}],"version-history":[{"count":2,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/1842\/revisions"}],"predecessor-version":[{"id":2293,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/1842\/revisions\/2293"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media\/2493"}],"wp:attachment":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media?parent=1842"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/categories?post=1842"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/tags?post=1842"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}