{"id":4907,"date":"2026-10-01T16:02:32","date_gmt":"2026-10-01T10:32:32","guid":{"rendered":"https:\/\/cpanelfree.com\/blog\/how-to-configure-fail2ban-to-protect-nginx-and-ssh\/"},"modified":"2026-10-01T16:02:32","modified_gmt":"2026-10-01T10:32:32","slug":"how-to-configure-fail2ban-to-protect-nginx-and-ssh","status":"publish","type":"post","link":"https:\/\/cpanelfree.com\/blog\/how-to-configure-fail2ban-to-protect-nginx-and-ssh\/","title":{"rendered":"How to Configure Fail2ban to Protect Nginx and SSH"},"content":{"rendered":"<p>Every publicly accessible Linux server encounters tens of thousands of automated credential-stuffing probes and HTTP vulnerability scans daily, exhausting connection pools and degrading application responsiveness. While a static firewall establishes foundational network perimeter filtering, adaptive threat mitigation demands an intrusion prevention system capable of parsing application telemetry in real time. Whether you run agile development staging environments on <a href=\"https:\/\/cpanelfree.com\">CpanelFree<\/a> or oversee high-traffic multi-tenant production clusters, mastering Fail2ban configuration across Nginx and OpenSSH is critical for preemptive infrastructure defense.<\/p>\n<p><!-- more --><\/p>\n<h2>What Is the Recommended Way to Configure Fail2ban for Nginx and SSH?<\/h2>\n<div style=\"background:#f9f9f9;border-left:4px solid #001b41;padding:16px 20px;margin:20px 0;font-size:15px;line-height:1.6;color:#333\">\n<p style=\"margin:0\">To configure Fail2ban for Nginx and SSH, install Fail2ban and copy <code>jail.conf<\/code> to <code>jail.local<\/code>. Enable the <code>sshd<\/code>, <code>nginx-http-auth<\/code>, <code>nginx-botsearch<\/code>, and <code>nginx-limit-req<\/code> jails backed by <code>nftables<\/code> and <code>systemd<\/code> log monitoring. Define aggressive ban times, persistent recidive rules, and rate limits to block malicious automated attackers at the kernel firewall level.<\/p>\n<\/div>\n<h2>Architectural Evaluation: Default vs. Tuned Production Fail2ban<\/h2>\n<p>Deploying Fail2ban with vanilla defaults often leads to excessive memory usage, high disk I\/O, and slow linear rule evaluation under sustained attack loads. Modern Linux systems running Linux 6.x kernels require transitioning from legacy <code>iptables<\/code> user-space iterations to kernel-native <code>nftables<\/code> sets, coupled with <code>systemd-journald<\/code> log consumption instead of unbuffered Python file polling.<\/p>\n<figure class=\"wp-block-table is-style-regular\">\n<table style=\"width:100%;border-collapse:collapse;margin:24px 0;font-size:15px;text-align:left\">\n<thead style=\"background:#001b41;color:#ffffff\">\n<tr>\n<th style=\"padding:12px 16px;border-bottom:2px solid #001b41\">Feature \/ Metric<\/th>\n<th style=\"padding:12px 16px;border-bottom:2px solid #001b41\">Standard \/ Default<\/th>\n<th style=\"padding:12px 16px;border-bottom:2px solid #001b41\">Tuned \/ Production<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Packet Filter Engine<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">iptables-multiport (O(N) chain traversal)<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">nftables sets (O(1) hash table lookup)<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Log Ingestion Mechanism<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Polling file reader (High disk I\/O)<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">systemd \/ pyinotify event stream<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Ban Enforcement Strategy<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Static 10-minute linear ban<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">Exponential recidive jail (up to 30 days)<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Memory Footprint (Heavy Load)<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">~160MB RAM (Unbounded regex buffers)<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">~35MB RAM (Tuned SQLite database &amp; GC)<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Connection Drop Latency<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Application-level 4xx\/5xx responses<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">Kernel TCP RST \/ Drop (Zero socket exhaustion)<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">IPv6 Dual-Stack Support<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7\">Requires separate ip6tables chains<\/td>\n<td style=\"padding:12px 16px;border-bottom:1px solid #e7e7e7;color:#20B038;font-weight:600\">Unified inet table (IPv4 + IPv6 atomic rules)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Fail2ban Core Mechanics: Decoupling Log Parsing from Kernel Filtering<\/h2>\n<p>At its architectural core, Fail2ban functions as an event-driven state engine. Rather than continuously intercepting packets at the network interface\u2014which would introduce unacceptable latency in high-throughput environments\u2014Fail2ban decouples packet inspection from traffic ingestion. Nginx and OpenSSH write request telemetry to their designated log destinations (either disk files or the <code>systemd-journald<\/code> binary socket). Fail2ban continuously evaluates these streams against structured regular expressions known as <em>filters<\/em>.<\/p>\n<p>When an incoming client IP address triggers a predefined threshold of filter violations (<code>maxretry<\/code>) within a specified temporal window (<code>findtime<\/code>), the Fail2ban server daemon executes an asynchronous <em>action<\/em>. In modern production environments, this action dynamically injects the offending IP into an active Linux firewall table or set. Once registered in the kernel firewall, subsequent connection attempts from that IP are dropped at the network layer (Layer 3\/4) before reaching Nginx worker processes or the OpenSSH authentication subsystem. This prevents CPU cycle exhaustion, thread starvation, and connection backlog saturation.<\/p>\n<blockquote class=\"wp-block-quote\" style=\"background:#f9f9f9;border-left:4px solid #001b41;padding:16px 20px;margin:24px 0\">\n<p><strong style=\"color:#001b41\">Architecture Note:<\/strong> Never edit <code>\/etc\/fail2ban\/jail.conf<\/code> directly. Distribution package upgrades routinely overwrite <code>jail.conf<\/code>, wiping custom security rules. Always place your production overrides inside <code>\/etc\/fail2ban\/jail.local<\/code> or modular drop-in files under <code>\/etc\/fail2ban\/jail.d\/*.local<\/code>.<\/p>\n<\/blockquote>\n<h2>Prerequisites and Modern Stack Installation<\/h2>\n<p>Before configuring custom jails, ensure that Fail2ban and <code>nftables<\/code> are installed on your Linux distribution. We recommend <code>nftables<\/code> as the default backend because it eliminates the O(N) chain traversal performance penalty associated with legacy <code>iptables<\/code>.<\/p>\n<p>On Debian, Ubuntu, and derivative systems:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Update package repositories and install fail2ban with nftables\nsudo apt update &amp;&amp; sudo apt install -y fail2ban nftables python3-systemd\n\n# Verify systemd service status\nsudo systemctl enable fail2ban\nsudo systemctl enable nftables\nsudo systemctl start nftables<\/code><\/pre>\n<p>On Enterprise Linux (RHEL, Rocky Linux, AlmaLinux 9\/10):<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Install EPEL repository and Fail2ban packages\nsudo dnf install -y epel-release\nsudo dnf install -y fail2ban fail2ban-systemd nftables\n\n# Enable and start services\nsudo systemctl enable --now nftables\nsudo systemctl enable --now fail2ban<\/code><\/pre>\n<h2>Securing OpenSSH: The First Line of Defense<\/h2>\n<p>Public-facing SSH servers are bombarded by automated dictionary attacks within minutes of provisioning. While transitioning from password-based authentication to Ed25519 cryptographic keys and binding SSH to non-standard ports mitigates automated intrusions, threat actors can still flood the SSH daemon with incomplete handshakes, exhausting <code>MaxStartups<\/code> slots and locking out legitimate systems engineers.<\/p>\n<p>Fail2ban monitors OpenSSH authentication events via <code>systemd-journald<\/code>. When repeated <code>Failed password<\/code>, <code>Invalid user<\/code>, or <code>Connection closed by authenticating user<\/code> patterns emerge, the offending host is isolated for an extended duration. Furthermore, implementing the <code>recidive<\/code> jail guarantees that repeat offenders face escalating 30-day bans rather than short-lived temporary penalties.<\/p>\n<h2>Shielding Nginx Web Services: Mitigating Scanners, Auth Abuse, and Layer 7 Floods<\/h2>\n<p>Web applications deployed on Nginx encounter three distinct categories of hostile automated traffic:<\/p>\n<ul>\n<li><strong>Authentication Brute-Force:<\/strong> Relentless attempts against HTTP Basic Auth, internal monitoring dashboards, or staging gates returning HTTP 401 Unauthorized.<\/li>\n<li><strong>Vulnerability Probing &amp; Path Traversal:<\/strong> Automated botnets scanning for exposed environment files (<code>.env<\/code>), configuration backups (<code>wp-config.php.bak<\/code>), git repositories (<code>.git\/config<\/code>), or arbitrary execution endpoints (<code>phpmyadmin<\/code>, <code>setup.php<\/code>).<\/li>\n<li><strong>Layer 7 Request Floods:<\/strong> High-frequency HTTP GET\/POST floods designed to exhaust PHP-FPM worker pools or Node.js event loops. In Nginx, this is combated by pairing the <code>limit_req_zone<\/code> directive with a dedicated Fail2ban error log jail.<\/li>\n<\/ul>\n<p>To enable rate-limit tracking in Nginx, configure your global HTTP block in <code>\/etc\/nginx\/nginx.conf<\/code>:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Define a shared memory rate limit zone inside the http { ... } block\nlimit_req_zone $binary_remote_addr zone=general_req_limit:20m rate=15r\/s;\nlimit_req_status 429;\nlimit_req_log_level warn;<\/code><\/pre>\n<p>Inside your target virtual host server block, apply the limit zone to vulnerable routes:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code>server {\n    server_name example.com;\n    \n    # Enforce rate limiting across API and application entry points\n    location \/ {\n        limit_req zone=general_req_limit burst=25 nodelay;\n        try_files $uri $uri\/ \/index.php?$args;\n    }\n\n    # Restrict administrative paths\n    location ~* \/(wp-login\\.php|administrator|xmlrpc\\.php) {\n        limit_req zone=general_req_limit burst=5 nodelay;\n        auth_basic \"Restricted Access\";\n        auth_basic_user_file \/etc\/nginx\/.htpasswd;\n        include fastcgi_params;\n        fastcgi_pass unix:\/run\/php\/php-fpm.sock;\n    }\n}<\/code><\/pre>\n<blockquote class=\"wp-block-quote\" style=\"background:#f9f9f9;border-left:4px solid #001b41;padding:16px 20px;margin:24px 0\">\n<p><strong style=\"color:#001b41\">Security Best Practice:<\/strong> When Nginx sits behind a Content Delivery Network (CDN) such as Cloudflare or an AWS Application Load Balancer, the connecting IP address in socket logs is the proxy&#8217;s IP. Banning this IP with Fail2ban would inadvertently block the entire CDN edge! You must configure Nginx&#8217;s <code>ngx_http_realip_module<\/code> to restore client visibility, or deploy API-level ban actions that push blacklist entries directly to your CDN edge.<\/p>\n<\/blockquote>\n<h2>Complete Production Configuration Files<\/h2>\n<p>Below is the unified production-grade <code>\/etc\/fail2ban\/jail.local<\/code> file. It defines optimized defaults, integrates with <code>nftables<\/code>, and activates specialized jails for SSH, Nginx HTTP authentication, aggressive scanner mitigation, and rate-limit enforcement.<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># ====================================================================\n# Enterprise Production Jail Configuration: \/etc\/fail2ban\/jail.local\n# Target Services: OpenSSH &amp; Nginx Web Server (nftables backend)\n# ====================================================================\n\n[DEFAULT]\n# Whitelist trusted CIDR blocks, management VPNs, and loopback\nignoreip = 127.0.0.1\/8 ::1 192.168.1.0\/24 10.8.0.0\/24\n\n# Default ban parameters\nbantime  = 1h\nfindtime = 10m\nmaxretry = 5\n\n# Use modern nftables backend for O(1) set lookup performance\nbanaction = nftables-multiport\nbanaction_allports = nftables-allports\n\n# Backend log engine (systemd provides structured low-overhead access)\nbackend = systemd\n\n# Protocol and reporting settings\nprotocol = tcp\nmta = sendmail\n\n# --------------------------------------------------------------------\n# 1. SSH PROTECTION JAIL\n# --------------------------------------------------------------------\n[sshd]\nenabled  = true\nport     = ssh,22\nmode     = aggressive\nmaxretry = 3\nfindtime = 15m\nbantime  = 24h\n\n# --------------------------------------------------------------------\n# 2. RECIDIVE JAIL: PERSISTENT BANS FOR SERIAL REPEAT OFFENDERS\n# --------------------------------------------------------------------\n[recidive]\nenabled  = true\nlogpath  = \/var\/log\/fail2ban.log\nbanaction = nftables-allports\nbantime  = 30d\nfindtime = 1d\nmaxretry = 3\n\n# --------------------------------------------------------------------\n# 3. NGINX HTTP AUTHENTICATION PROTECTION\n# --------------------------------------------------------------------\n[nginx-http-auth]\nenabled  = true\nport     = http,https\nfilter   = nginx-http-auth\nlogpath  = \/var\/log\/nginx\/error.log\nbackend  = auto\nmaxretry = 4\nfindtime = 10m\nbantime  = 12h\n\n# --------------------------------------------------------------------\n# 4. NGINX VULNERABILITY SCANNER &amp; BOT DEFENSE\n# --------------------------------------------------------------------\n[nginx-botsearch]\nenabled  = true\nport     = http,https\nfilter   = nginx-botsearch\nlogpath  = \/var\/log\/nginx\/access.log\nbackend  = auto\nmaxretry = 2\nfindtime = 15m\nbantime  = 48h\n\n# --------------------------------------------------------------------\n# 5. NGINX LAYER 7 RATE LIMIT EXHAUSTION DEFENSE\n# --------------------------------------------------------------------\n[nginx-limit-req]\nenabled  = true\nport     = http,https\nfilter   = nginx-limit-req\nlogpath  = \/var\/log\/nginx\/error.log\nbackend  = auto\nmaxretry = 5\nfindtime = 5m\nbantime  = 6h\n\n# --------------------------------------------------------------------\n# 6. NGINX BAD BOTS &amp; CRAWLERS\n# --------------------------------------------------------------------\n[nginx-badbots]\nenabled  = true\nport     = http,https\nfilter   = apache-badbots\nlogpath  = \/var\/log\/nginx\/access.log\nbackend  = auto\nmaxretry = 2\nfindtime = 30m\nbantime  = 24h<\/code><\/pre>\n<p>To detect Layer 7 rate-limiting events logged by Nginx, create the custom filter definition at <code>\/etc\/fail2ban\/filter.d\/nginx-limit-req.local<\/code>:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Fail2ban filter configuration for Nginx rate limiting\n# Path: \/etc\/fail2ban\/filter.d\/nginx-limit-req.local\n\n[Definition]\n# Matches Nginx error log lines generated by limit_req module\nfailregex = ^\\s*\\[error\\] \\d+#\\d+: \\*\\d+ limiting requests, excess: [\\d\\.]+ by zone \"[^\"]+\", client: &lt;HOST&gt;,\n\nignoreregex =<\/code><\/pre>\n<p>To enhance path probing detection for arbitrary exploit scripts, ensure <code>\/etc\/fail2ban\/filter.d\/nginx-botsearch.local<\/code> includes aggressive regex patterns:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Fail2ban filter configuration for Nginx bot scanning\n# Path: \/etc\/fail2ban\/filter.d\/nginx-botsearch.local\n\n[Definition]\nfailregex = ^&lt;HOST&gt; - \\S+ \\[.*?\\] \"(?:GET|POST|HEAD) \\\/(?:wp-login\\.php|xmlrpc\\.php|phpmyadmin|pma|\\.env|\\.git|eval-stdin\\.php|actuator|telescope).*?\" (?:400|403|404|405)\n\nignoreregex =<\/code><\/pre>\n<p>To ensure Fail2ban and kernel packet drop paths execute with maximum efficiency under network pressure, apply the following sysctl parameters in <code>\/etc\/sysctl.d\/99-security-hardening.conf<\/code>:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># \/etc\/sysctl.d\/99-security-hardening.conf\n# Mitigate TCP SYN floods and optimize connection drop latency\nnet.ipv4.tcp_syncookies = 1\nnet.ipv4.tcp_max_syn_backlog = 8192\nnet.ipv4.tcp_synack_retries = 2\nnet.ipv4.tcp_fin_timeout = 15\n\n# Drop invalid packets immediately\nnet.ipv4.conf.all.rp_filter = 1\nnet.ipv4.conf.default.rp_filter = 1\nnet.core.somaxconn = 65535<\/code><\/pre>\n<h2>Operational Verification and Runtime Management<\/h2>\n<p>Once configuration files are written, reload Fail2ban to initialize jails and verify operational telemetry:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Validate configuration syntax before restarting\nsudo fail2ban-client -d\n\n# Reload all jails\nsudo fail2ban-client reload\n\n# Inspect overall system jail status\nsudo fail2ban-client status<\/code><\/pre>\n<p>You can inspect the operational state of individual jails, including active ban counts and IP address lists:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Query detailed status of the SSH and Nginx jails\nsudo fail2ban-client status sshd\nsudo fail2ban-client status nginx-botsearch\n\n# Inspect the live nftables set populated by Fail2ban\nsudo nft list set inet f2b-table f2b-sshd<\/code><\/pre>\n<p>If an administrator or legitimate user triggers an accidental lockout, unban the IP address instantly without restarting the daemon:<\/p>\n<pre class=\"wp-block-code\" style=\"background:#f3f3f3;color:#333;padding:16px;border-left:4px solid #001b41;font-family:monospace;font-size:13px\"><code># Unban a specific IP from a designated jail\nsudo fail2ban-client set sshd unbanip 198.51.100.24\n\n# Unban an IP across all active jails\nsudo fail2ban-client unban 198.51.100.24<\/code><\/pre>\n<h2>Scaling Beyond Host-Level Defense: Dedicated Cloud Infrastructure<\/h2>\n<p>While dynamic host-level filtering with Fail2ban shields single-node Linux systems from routine scanner noise, mission-critical e-commerce platforms, SaaS APIs, and multi-tenant databases demand hardware-accelerated perimeter protection and dedicated compute throughput. For workloads requiring high-concurrency processing with zero price hikes, migrating to <a href=\"https:\/\/merahost.org\" target=\"_blank\" rel=\"noopener\">MeraHost Enterprise Cloud<\/a> gives you access to isolated NVMe storage, native LiteSpeed acceleration, and carrier-grade automated anti-DDoS mitigation that drops volumetric floods upstream before packets ever hit your hypervisor.<\/p>\n<h2>Frequently Asked Questions<\/h2>\n<details class=\"wp-block-group\" style=\"background:#f9f9f9;border:1px solid #e7e7e7;border-radius:4px;padding:14px;margin-bottom:12px\">\n<summary style=\"cursor:pointer;font-weight:600;color:#001b41\">Does Fail2ban introduce CPU latency during high-volume DDoS attacks?<\/summary>\n<p style=\"margin-top:10px;color:#444\">Fail2ban is designed as an intrusion prevention system for distributed brute-force and scanner attacks, not as a volumetric Layer 3\/4 DDoS mitigation appliance. When attacked at hundreds of thousands of requests per second, log disk I\/O and regular expression matching can cause high CPU utilization. For high-volume attacks, upstream scrubbing or edge firewalls should be deployed alongside Fail2ban.<\/p>\n<\/details>\n<details class=\"wp-block-group\" style=\"background:#f9f9f9;border:1px solid #e7e7e7;border-radius:4px;padding:14px;margin-bottom:12px\">\n<summary style=\"cursor:pointer;font-weight:600;color:#001b41\">Why is nftables preferred over iptables for Fail2ban?<\/summary>\n<p style=\"margin-top:10px;color:#444\">Legacy iptables performs linear O(N) chain traversal, causing packet inspection latency to scale linearly as thousands of IPs are banned. Modern nftables implements indexed set data structures that execute in constant O(1) time regardless of whether your blacklist contains 10 or 100,000 banned IP addresses.<\/p>\n<\/details>\n<details class=\"wp-block-group\" style=\"background:#f9f9f9;border:1px solid #e7e7e7;border-radius:4px;padding:14px;margin-bottom:12px\">\n<summary style=\"cursor:pointer;font-weight:600;color:#001b41\">How can I test a Fail2ban regex without triggering an active ban?<\/summary>\n<p style=\"margin-top:10px;color:#444\">You can test regex matching safely using the <code>fail2ban-regex<\/code> diagnostic utility. Execute <code>sudo fail2ban-regex \/var\/log\/nginx\/error.log \/etc\/fail2ban\/filter.d\/nginx-limit-req.local<\/code> to see matched lines, capture groups, and processing speed without altering live firewall tables.<\/p>\n<\/details>\n<details class=\"wp-block-group\" style=\"background:#f9f9f9;border:1px solid #e7e7e7;border-radius:4px;padding:14px;margin-bottom:12px\">\n<summary style=\"cursor:pointer;font-weight:600;color:#001b41\">How do I prevent Fail2ban from banning Cloudflare proxy IPs?<\/summary>\n<p style=\"margin-top:10px;color:#444\">Add Cloudflare&#8217;s published IP ranges to your <code>ignoreip<\/code> directive in <code>jail.local<\/code>, and configure Nginx with <code>set_real_ip_from<\/code> directives paired with <code>real_ip_header CF-Connecting-IP;<\/code>. This ensures Nginx logs true client IPs while preventing Fail2ban from severing your edge CDN connection.<\/p>\n<\/details>\n<div class=\"wp-block-group has-background\" style=\"background:#f9f9f9;border:1px solid #e7e7e7;border-radius:8px;padding:32px;margin:40px 0;text-align:center\">\n<h3 style=\"color:#001b41;margin-top:0;font-size:24px;font-weight:700\">Deploy Enterprise-Grade Production Infrastructure<\/h3>\n<p style=\"color:#444;font-size:16px;line-height:1.6;max-width:680px;margin:12px auto 24px auto\">Need guaranteed performance with zero price hikes? Host mission-critical workloads on <strong style=\"color:#001b41\">MeraHost<\/strong> with pure Enterprise NVMe, LiteSpeed Web Server, and Same Renewal Price, Always (starting at \u20b999\/mo).<\/p>\n<div class=\"wp-block-buttons\" style=\"display:flex;gap:16px;justify-content:center;flex-wrap:wrap\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link\" href=\"https:\/\/merahost.org\" style=\"background:#001b41;color:#ffffff;font-weight:700;padding:12px 28px;border-radius:4px;text-decoration:none;display:inline-block;font-size:15px\" target=\"_blank\" rel=\"noopener\">Explore MeraHost NVMe Cloud &rarr;<\/a><\/div>\n<div class=\"wp-block-button is-style-outline\"><a class=\"wp-block-button__link\" href=\"https:\/\/cpanelfree.com\" style=\"background:transparent;color:#001b41;font-weight:600;padding:12px 24px;border:2px solid #001b41;border-radius:4px;text-decoration:none;display:inline-block;font-size:15px\">Deploy Free Staging on CpanelFree<\/a><\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Protect Nginx and SSH from brute-force scans with Fail2ban. Deploy production jails, nftables integration, and custom regex filters.<\/p>\n","protected":false},"author":1,"featured_media":4906,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64],"tags":[57,69,177,87,101],"class_list":["post-4907","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security","tag-almalinux","tag-cyber-security","tag-databases-performance","tag-devops","tag-sysadmin"],"_links":{"self":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4907","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=4907"}],"version-history":[{"count":0,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4907\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media\/4906"}],"wp:attachment":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media?parent=4907"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/categories?post=4907"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/tags?post=4907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}