Server Security in 2026: What We Learned The Hard Way
Server Security 2026
Note for readers looking for a solution: This article probably is not going to help you directly. It documents where things stand in 2026 and the journey that got here. We are still fighting these problems like everyone else. What is described here is what failed and why, not a step-by-step fix. If you are expecting a "do this and your server will be fine" guide, this is not that article.

This article documents the real-world experience of running a small public hobby server - a phpBB forum, MediaWiki wiki, webstore, and email service - under sustained botnet attack over several years. It is not a theoretical overview. Every approach described here was actually tried on a live server under real attack conditions. Every failure described here is a documented failure, not a hypothetical one.

The earlier articles on this site covered IP blocklists and common attack vectors. This article picks up where those left off, covering what happened when the standard approaches stopped being sufficient and the threat landscape continued to evolve through 2025 and into 2026. It is written to help other small server administrators understand what they are likely to face, and why the textbook answers may not be enough.

No specific configuration details or custom solution architecture are revealed here. This is a record of what failed and why, not a how-to guide.

1. The Threat Landscape in 2025–2026

The attacks documented on this server over the past several years are not targeted attacks by motivated individuals. They are automated, indiscriminate, and continuous. Botnets scan entire IP ranges systematically, identify publicly accessible servers, and add them to attack rotations. Being hit has nothing to do with being interesting or high-profile as a target. It has to do with being publicly accessible, which every internet-facing server is by definition.

The scale of compromised infrastructure available to botnets has grown substantially. Research and news coverage has documented that pirated television streaming boxes - sold in enormous volumes globally - are infected with attack malware at the factory level, before consumers ever receive them. These devices serve television content to their owners while simultaneously participating in botnet attacks on web servers around the world. The consumer has no awareness of this. The resulting pool of attack infrastructure is effectively unlimited.

Consumer ISP networks in multiple regions have been compromised at a scale where significant fractions of entire national address spaces generate attack traffic at any given time. In one documented case on this server, a major US ISP had its infrastructure compromised and used as an attack source. Brazilian networks, Southeast Asian networks, and others have contributed similarly. This is not a fringe problem - it is a systemic failure of internet infrastructure at global scale, and individual server administrators are dealing with the consequences.

2. Why IP Blocklists Are Not Enough

The earlier article on this site documented the limitations of fixed IP blocklists in detail, including test results showing around 51% match rates against all 322 FireHOL lists combined. The 2025–2026 experience reinforces and extends those findings in an important way.

Even a 50% match rate is not meaningfully protective at botnet scale. If blocklists catch half the attack traffic, the remaining half still reaches the server. At the volumes observed on this server, 50% of the attack traffic was still more than sufficient to exhaust all available CPU, database connections, and server resources entirely. The threshold for effectiveness is not “most traffic blocked” but “enough blocked that the remainder cannot exhaust server resources” - a fundamentally different and much higher bar that standard blocklists cannot meet against high-volume distributed attacks.

Blocklists are also reactive by design. They identify bad actors after reports are received and processed. Fresh attack infrastructure - newly compromised hosts, recently hacked ISPs, new residential proxy exit nodes - is not in any list for days or weeks after it begins attacking. In one documented incident, a new attack campaign from a specific ISP was tested against all available blocklists after 24 hours. Not a single attacking IP appeared in any list. The server would have been completely unprotected for the entire duration of the attack if blocklists had been the only defence.

3. Fail2ban: Effective Against Script Kiddies, Blind to Botnets

Fail2ban is the standard answer to web server attack traffic. Properly configured, it catches and bans attacking IPs before they cause significant damage. This approach was pursued thoroughly on this server - 33 jails covering every meaningful attack pattern visible in the logs, with hundreds of rules tuned to specific attack signatures.

For script kiddie attacks - repeated login attempts, known exploit probing, brute force credential stuffing from single IPs - fail2ban works well and continues to work well. That category of attack is handled.

The failure emerged at scale. At the volume of attacks hitting this server, fail2ban itself became a system resource problem:

Beyond the resource problem, fail2ban has a fundamental architectural limitation against modern botnet attacks. It is designed to catch repeated offenders from individual IP addresses. Modern botnets do not operate that way.

When Catching More Traffic Made Things Worse

A particularly frustrating discovery was that successfully improving fail2ban’s detection - getting it to catch around 95% of bad traffic - did not solve the problem. It created a new one.

As fail2ban became more effective, the accumulated block list of banned IP addresses grew continuously. Millions of IPs were banned over time. Fail2ban stores the state of all its bans in memory. The RAM consumed by the accumulated IP list grew into gigabytes - on a server with only 4GB total. Combined with the memory already consumed by the jail processes themselves, the server was being strangled by its own defences even while those defences were technically working.

The block list was also stored in ipset, the kernel-level IP set used by iptables. Ipset has a maximum capacity. At the scale of attacks being experienced, that capacity limit was reached. When fail2ban attempted to add new bans to a full ipset, it generated silent errors - bans appeared successful in fail2ban’s own logs but were never applied. The server was again reporting success while new attacking IPs passed through unblocked. Discovering this required independent verification of whether bans in fail2ban’s logs were actually appearing in the kernel ipset.

Time-limited bans were attempted as a solution to the growing list size. The idea was that banning IPs for 24 hours, a week, or a month would allow the list to cycle rather than grow indefinitely. This failed in two ways. First, the processing overhead of continuously banning and unbanning millions of IPs at scale consumed significant CPU resources - the act of managing the ban lifecycle itself became a performance problem. Second, and more fundamentally, even a full month-long ban had no effect on attack behaviour. As soon as IPs were automatically unbanned at expiry, they immediately resumed attacking. Whether the timeout was 24 hours or 30 days made no practical difference. The attack infrastructure simply resumed the moment the block was lifted. Permanent bans are the only approach with any lasting effect, which returns the problem to the memory and capacity constraints described above. There is no clean solution within this architecture.

4. The Distributed Low-Rate Botnet Problem

The attack pattern that standard tools are completely blind to is the distributed low-rate botnet. Individual IP addresses hit the server only once or twice per 24-hour period. By any standard threshold - which watches for repeated hits from single IPs - this is indistinguishable from a normal human visitor. No fail2ban rule catches it. No rate limit per IP catches it.

The impact comes from volume. When millions of IP addresses each make one or two apparently-innocent requests per day simultaneously, the cumulative traffic volume is identical to a conventional flood - except it is completely invisible to every standard detection tool available. Fail2ban, rate limiting, and blocklists are all designed around a threat model where a small number of IPs make many requests. The actual threat is a very large number of IPs making very few requests each.

Time-limited bans were attempted as a way to manage the growing block list size. This failed on multiple levels. The processing overhead of continuously banning and unbanning millions of IPs consumed significant CPU resources. More fundamentally, even a month-long ban had no effect on attack behaviour: as soon as IPs were automatically unbanned at the end of their ban period, they immediately resumed attacking. Whether the timeout was 24 hours or 30 days made no practical difference. Botnet-operated devices are not deterred by bans. The ban disappears, the attack resumes. Permanent bans are the only approach with any lasting effect, and even those are undermined by the continuous supply of fresh IPs from an effectively unlimited pool of compromised devices.

5. The IPTables Scaling Problem - and the Cascade Effect

As the block list grew into the millions of entries, a secondary problem emerged that is rarely discussed in standard server administration guides. IPTables evaluates firewall rules sequentially on every single network packet. With a block list of millions of individual entries, the time taken to traverse the rules on every packet becomes a measurable system overhead that degrades all traffic - legitimate and attack alike. The forum was running noticeably slow even between attack peaks because every packet from every legitimate user was being walked through millions of firewall rules before being allowed through.

The response to this was a significant architectural redesign - replacing individual IPTables rules with ipset. Ipset stores IP addresses in a hash table rather than a sequential list. Lookups in a hash table are effectively instant regardless of how many entries the set contains, compared to IPTables which gets progressively slower with every additional rule added. Moving to ipset resolved the per-packet slowdown and restored normal server performance under non-attack conditions. It was not a quick change - it required rewriting how bans were applied, stored and managed throughout the whole system.

However ipset then introduced its own problem.

The solution to the attack was itself slowing the server. Moving to range-based blocking (/24 and /16 subnets) reduced the entry count but introduced its own problem: blocking a range based on attacks from some IPs in that range also blocks legitimate users whose IPs happen to fall in the same range. The wider the range, the more collateral damage. There is no clean resolution to this tradeoff at scale - it requires accepting that some legitimate users will be affected in exchange for keeping the server running for the majority.

This episode illustrates what became a recurring pattern throughout the entire journey: every solution revealed the next problem. Fixing fail2ban’s detection rate caused the IP list to grow too large for RAM. Solving the RAM problem by moving to ipset caused ipset to fill to capacity and silently fail. Solving the capacity problem by expanding ipset caused IPTables traversal to degrade all traffic. Solving the traversal problem by switching to range blocking caused collateral damage to legitimate users. Each step forward uncovered the next obstacle in line. The problems did not stack sequentially - they compounded, with each partial solution creating new failure modes that took additional weeks to identify and address.

6. The Chicken-and-Egg Problem of Reactive Blocking

A deeper issue with standard PREROUTING-level IP blocking is that it is inherently reactive. An IP address can only be added to the block list after it has been observed attacking the server. Every attack IP must make at least one successful request - consuming server resources - before it can be blocked. At botnet scale, where hundreds of thousands of IPs rotate through an attack campaign, the attack has always already happened before the block is applied. The blocking system is permanently one step behind.

Moving to range-based blocking helps with scale but does not solve the bootstrapping problem. The range still has to be identified through observed attack behaviour before it can be blocked, meaning the attack traffic still reaches the server until the range is identified. Solving this bootstrapping problem - blocking attack traffic before it reaches the server, without waiting for each individual IP or range to demonstrate its intent - required a fundamentally different detection approach that does not exist in standard tooling.

7. Silent Failures: When Mitigations Stop Working Without Telling You

Several distinct scenarios emerged where security measures appeared to be working but were not, sometimes for extended periods. These failures were particularly difficult to diagnose because the system’s own reporting indicated normal operation.

In one case, fail2ban’s action scripts were pointing to incorrect binary paths for the firewall tools. Bans were logged as successful - fail2ban reported correctly that IPs had been banned - but the IPs were never actually added to the kernel firewall sets. The system was reporting success while allowing attack traffic through unimpeded. The failure was only discovered through independent audit of whether banned IPs were actually appearing in the kernel sets.

In another case, automatic unban logic was written incorrectly. Fail2ban recorded that IPs should be unbanned at expiry, but the unban rules did not execute. Approximately 300,000 IP addresses accumulated that should have been automatically removed but were not, requiring a dedicated script to retrospectively process the backlog.

The consistent lesson: security systems cannot be trusted to correctly report their own failures. Independent verification that mitigations are actually doing what they claim to be doing is essential and cannot be skipped.

8. Application-Layer Optimisation: Helpful but Not Sufficient

A comprehensive range of caching and memory optimisations were implemented to reduce the resource cost of serving each request. PHP opcache was configured with 256MB memory allocation, eliminating PHP re-parsing on every request. The MySQL innodb buffer pool was increased to hold the entire database in RAM, eliminating disk reads for database queries. nginx FastCGI response caching was configured to serve repeated content without hitting PHP or MySQL at all. RAM disks were used for high-frequency data, and log writes were buffered in memory rather than written per-request.

Every one of these optimisations was genuinely beneficial. The server handled legitimate traffic more efficiently. Under botnet attack with millions of concurrent requests, the server still failed.

The fundamental problem: all of these optimisations reduce the resource cost per request. They do not reduce the number of requests. At one point, millions of 404 hits were arriving on the root domain. Even serving a cached 404 response from RAM requires accepting the TCP connection and completing the TLS handshake first. At millions of requests per hour, nginx’s connection handling capacity was overwhelmed before any caching layer was consulted. A server optimised to serve a cached response in microseconds, receiving a million requests per second, still needs to handle a million connections per second. That ceiling is determined by the network stack and connection table, not by cache efficiency.

The only way to change the economics is to prevent requests from reaching the server at all. Anything that reaches the application layer is a battle already lost at sufficient scale. This conclusion, arrived at empirically through months of observation, defines where the real solution had to be built.

The Meta Crawler Incident: When nginx 444 Was Not Enough

A specific incident illustrates how far this principle extends. Large volumes of traffic were observed from the meta-externalagent user agent - the crawler used by Meta (Facebook and Instagram) to generate link previews. The traffic was verified as genuine Meta infrastructure through RIPE database registration and ASN confirmation. Despite being legitimate crawlers rather than a botnet, the sheer volume of requests was causing server resource exhaustion.

The immediate application-layer response was to return nginx 444 on all matching requests - a connection close with no response, the lightest possible server-side action available at the nginx level. Under normal circumstances this is an efficient way to shed unwanted traffic. At the volume Meta’s crawlers were generating, even nginx 444 was insufficient. The server was still being overwhelmed.

The reason is that 444 only eliminates the cost of generating and sending a response. It does not eliminate the cost of accepting the TCP connection and completing the TLS handshake, both of which happen before nginx can evaluate the user agent and return 444. At sufficient request volume, the connection establishment overhead alone - before any application logic runs at all - saturates the server’s available capacity. There is no lighter response available at the nginx level. The only lighter response is one that happens before nginx is involved, at the kernel network layer.

This is the clearest possible demonstration of why application-layer blocking - however lightweight - cannot solve a volume problem. The application layer is always too late.

9. Cloudflare: Why It Wasn’t the Answer

Cloudflare is widely recommended as a protective layer for small servers. The experience with Cloudflare on this server was not positive, for specific and documented reasons.

The forum used the Stop Forum Spam extension for phpBB, which checks new registrations and posts against a database of known spammer IP addresses. Cloudflare’s proxying caused this extension to receive Cloudflare’s IP addresses rather than the actual visitor’s IP, breaking the lookup entirely. Front-end spam protection that had been in place became non-functional.

When attempting to report attacking IP addresses to AbuseIPDB - a community threat intelligence database - Cloudflare blocked the submission requests from the server. Cloudflare also blocked the server’s IP address from accessing GitHub, preventing automated update processes and tool maintenance.

Most significantly, attack traffic was observed originating from Cloudflare’s own IP ranges. Cloudflare proxies traffic for millions of services. Attackers route traffic through it for cover. The consequence is that blocking Cloudflare IP ranges to stop attack traffic would also have broken legitimate access for any users whose traffic was proxied through Cloudflare - making it impossible to address that attack vector at all.

A service that breaks existing spam protection, blocks abuse reporting, prevents server maintenance, and simultaneously routes attack traffic toward the server it is supposedly protecting does not represent a net security improvement. The decision was made not to use Cloudflare. The risks and operational disruptions outweighed any benefit.

The Bigger Problem: Too Much of the Internet in Too Few Hands

Beyond the specific technical issues, there is a broader concern about what it means to hand your availability over to a third party of this scale. On 18 November 2025, Cloudflare suffered a major outage that took down X, Spotify, OpenAI and significant portions of Amazon Web Services at the same time. A database permissions change triggered a cascade that took a large fraction of the internet offline for several hours. Less than three weeks later, on 5 December 2025, another Cloudflare incident took down X, Substack, Canva, LinkedIn, Deliveroo and Spotify. These are not small incidents from a minor provider - these are systemic failures from the company that much of the internet has been told to trust with their availability.

When one company has enough infrastructure under its control that a single internal bug can take down X, Spotify and Amazon simultaneously, that is not a security posture. That is a single point of failure on a civilisational scale. The question of what happens to that infrastructure around politically sensitive periods - elections, major protests, periods of civil unrest - is one nobody in the industry seems to want to ask clearly. No company should have that much control over what the internet can and cannot reach. The fact that it has happened through gradual commercial consolidation rather than any deliberate act makes it no less concerning.

Microsoft and the Two-Year Email Blocking Battle

The Cloudflare situation is not unique. A two-year battle with Microsoft over email deliverability illustrates exactly the same dynamic on a smaller but more personally disruptive scale.

Microsoft was blocking email from this server’s IP. Anyone with a Hotmail, Outlook or Microsoft 365 address was not receiving notifications, password resets, or any other forum emails. The Microsoft Sender Support tool was used to request delisting. Requests were processed. The IP was cleared. Within days it was blocked again. The cycle repeated for over two years. Microsoft’s own support staff confirmed there was no identifiable reason for the block - no spam reports, no policy violations, nothing specific that could be addressed. The system was blocking the IP for reasons their own staff could not explain, and the only resolution offered was to submit another delisting request every few days indefinitely. That is a fulltime job and not a solution.

The practical outcome was that large numbers of forum members never received emails, and there was nothing that could be done about it. No amount of correct configuration, good sending practices, low bounce rates or spam complaint rates made any difference. A large company’s broken automated system was causing real disruption to real users, and the company in question either could not or would not fix it.

Google has operated similarly in other contexts. A business listing was removed without explanation, an appeal was submitted, the appeal was rejected with no specific reasoning given. The original Google principle of "do no harm" appears to have been quietly retired somewhere along the way.

The pattern is consistent across large companies. When they get big enough, the internal systems that interface with small operators become automated, opaque, and effectively unaccountable. There is no escalation path that reaches anyone with the authority or motivation to actually fix a broken process. The little operator just absorbs the disruption and keeps submitting tickets into the void. This is not a coincidence or a series of isolated failures. It is what happens when scale removes the incentive to care about individual cases.

For this reason, running infrastructure that depends on the goodwill or correct functioning of large third-party services is not something I am prepared to do. The technical failures are bad enough. The complete absence of effective recourse when those failures occur is worse. Keeping control of my own stack, with all the work that entails, is preferable to being at the mercy of automated systems operated by organisations too large to be held accountable for what those systems do.

10. User Agent Filtering: Trivially Spoofed, Collateral-Damage Heavy

User agent string filtering - blocking requests that identify themselves as known-bad bots or scrapers - appears straightforward and is widely recommended. In practice it proved unreliable.

Bad actors spoof user agents trivially. A botnet operator can configure any user agent string they choose. One documented botnet was observed sending perfectly consistent, apparently legitimate Chrome browser user agent strings from thousands of different IPs. The user agent offered no useful signal whatsoever.

Legitimate traffic uses unexpected user agents. Search engine crawlers, feed readers, accessibility tools, and monitoring services frequently use old, unusual, or non-standard user agent strings. This is a long-standing and widely-complained-about problem in the web community that has never been adequately resolved. Blocking by user agent risks blocking these legitimate services.

A particularly time-consuming category involved traffic spoofing the Googlebot user agent. Blocking any request claiming to be Googlebot risks blocking the genuine Google crawler, with serious consequences for search engine indexing. The only reliable resolution was to verify each IP address claiming to be Googlebot against Google’s actual published IP ranges before making a blocking decision - requiring a dedicated verification script. A further script was then needed to periodically audit the entire block list to ensure no genuine Google IPs had been trapped. This verification overhead was generated entirely by attackers exploiting the trust that must be extended to legitimate search engine crawlers.

A further complication: the majority of legitimate crawlers and good bots do not publish their IP address ranges. Unlike Google and a handful of major search engines, most legitimate automated services provide no way to verify their identity beyond their user agent string - which is trivially spoofable. Every decision in this area involves accepting either false positives (blocking legitimate bots) or false negatives (allowing attack traffic through). There is no clean solution.

11. Mobile Networks and Residential ISPs: The Insoluble Problem

One of the most frustrating discoveries came when the botnet detection scripts began classifying where attack traffic was actually originating from. The assumption going in was that botnets ran from cheap cloud hosting - datacenters, VPS providers, proxy services. Those are easy to block. They are concentrated, identifiable by ASN, and blocking a /16 datacenter range carries essentially zero risk of affecting real users.

The reality was different. In one analysis session the scripts identified over 50,000 attacking IPs. The vast majority were not on datacenter ranges at all. They were on mobile carriers and residential ISPs - T-Mobile, Telkomsel, Pakistan Telecom, Iraqi broadband providers, Vietnamese ISP ranges, UK residential broadband. Botnets had shifted tactics away from cloud servers and onto compromised phones and home routers on consumer networks. This created a blocking problem with no clean answer.

Blocking an entire /16 of a mobile carrier would remove thousands of real users. Not blocking it left the attack traffic flowing. The automatic blocking scripts were written to skip ISP and mobile ranges specifically for this reason - the collateral damage was too severe. But the botnet was large enough that leaving those ranges unblocked was unsustainable as well. A separate manual process was needed to handle them, accepting some collateral damage as unavoidable.

The core problem is Carrier Grade NAT (CGNAT). Mobile networks assign a single public IP address to thousands of devices simultaneously. A botnet operating through compromised phones shares that IP with hundreds of genuine mobile users on the same carrier. Blocking the IP blocks all of them. The behaviour in practice was stark - an IP would generate clear attack traffic, then legitimate user traffic would appear from the same address, then attack traffic again, sometimes cycling within minutes as the carrier reassigned the address between different devices. There was no reliable way to distinguish attack from legitimate use based on IP address alone.

Residential ISPs compound this with DHCP reassignment. An IP flagged for scraper activity at 2pm may belong to a completely different household customer by 4pm because the ISP rotated the address. Ban the scraper, accidentally ban an innocent user who happened to receive the same IP hours later. This was observed in practice - a residential UK broadband address would show a clear attack pattern, get banned, then show a 200 response from what was almost certainly a different person on the same ISP-assigned address after the ban was in place.

Session token attacks added another layer to this. Vietnamese ISP ranges were specifically observed in attacks using fabricated phpBB session IDs - hundreds of IPs within the same /24 subnet hitting the forum with fake session tokens. The same /24 on a Vietnamese ISP contains many different customers sharing infrastructure, so blocking the /24 to stop the session attack would also block every legitimate Vietnamese user on that segment of the carrier network.

This problem has no viable technical solution at the individual server level. Mobile network operators would need to identify and isolate infected devices on their own infrastructure. That is a problem of global consumer device security that is entirely outside any individual server administrator’s control. The practical outcome was a forum advisory telling users not to access the site through mobile data connections. That is not a satisfying outcome, but it is an honest one. Some problems exist above the level where they can be solved.

12. Account-Based Attacks and Sleeper Accounts

Not all attacks came from the network layer. A more subtle category involved the forum’s own account system. Accounts were registered and established apparent legitimacy over extended periods - making genuine-looking posts over months or even years - before activating for spam or abuse once the account had accrued sufficient post count to pass new-member moderation thresholds. These accounts were indistinguishable from genuine members during the dormancy period.

In separate incidents, existing genuine member accounts were compromised and used to post spam or abuse. These carried all the trust signals of long-standing community members, making them harder to detect automatically than new registrations.

The consequence is that forum moderation cannot rely solely on account age and post count as trust signals. Accounts that appear legitimate may not be. This requires ongoing manual vigilance alongside automated tools.

13. The HTTP/2 Bomb Vulnerability - June 2026

In June 2026, a significant new vulnerability was publicly disclosed affecting nginx, Apache, Microsoft IIS, and other web servers running HTTP/2. The vulnerability - CVE-2026-49975 - exploits the HPACK header compression mechanism in HTTP/2 combined with flow control to achieve server memory exhaustion from a single connection.

The attack sends HTTP/2 requests with nearly empty headers that nevertheless require large per-entry bookkeeping allocations on the server side. A zero-byte flow control window prevents the server from freeing that memory. A single attacker on a standard residential internet connection can hold approximately 32GB of server RAM in around 20 seconds. The fix requires nginx 1.29.8 or above, which adds a maximum header count limit.

This vulnerability is directly relevant to the broader pattern documented throughout this article. Botnets were already observed adopting HTTP/2 in early 2026, abandoning the HTTP/1.1 protocol that had previously been a reliable distinguishing signal between attack bots and legitimate browsers. When botnets shifted to HTTP/2, standard HTTP-level filtering became substantially less effective. The CVE disclosure explains part of why HTTP/2 became an attractive attack vector: it offered a novel and severe resource exhaustion mechanism that bypassed all existing caching and rate-limiting defences entirely.

The lesson: the attack landscape does not stand still. Techniques that were reliable signals last year may be actively weaponised next year. Security measures that rely on fixed signals rather than adaptive detection have a limited effective lifespan.

14. Geographic Blocking as Last Resort

As attack volumes from certain regions became unsustainable, geographic blocking - blocking entire countries’ IP ranges - became necessary despite the significant collateral damage to legitimate users from those regions. This is not a decision taken lightly. It affects real users who have nothing to do with the attacks and simply happen to be on the same national network infrastructure as the attacking devices.

The scale that forced it: entire national ISP networks were generating attack traffic at volumes that individual IP blocking could not keep pace with. The VPS hosting provider itself made the same decision independently, blocking entire countries at their infrastructure level. When the hosting provider is making the same call, it validates that the problem is not unique to one server and that geographic blocking has become a necessary tool of last resort in this environment.

The regions generating the heaviest and most sustained attack traffic have been Brazil, India (particularly Jio and Airtel infrastructure), Vietnam, Indonesia, Pakistan, Iraq, Turkey, Mexico, and broader Southeast Asia, Africa, and the Middle East. For a retro Atari computing community, legitimate traffic from these regions is minimal. Blocking them removes a very large proportion of attack traffic with relatively little risk of losing genuine visitors or customers. That calculus would look very different for a site with a genuinely global audience.

The practical implication of this is sobering. Approximately 17% of the publicly routable internet is now blocked at the network level on this server. That figure grows regularly. It is a direct measure of how comprehensively consumer devices are infected with botnet malware across large parts of the global internet. When you have to block almost a fifth of the internet to keep a small hobby forum running, that is not a server administration problem. That is a global infrastructure problem that nobody has solved and few are even seriously trying to.

15. Where We Are in 2026

The server that was struggling to sustain 10,000 forum hits under attack conditions in early 2025 is now absorbing 60,000+ forum hits at peak under comparable attack conditions, with the wiki, store, and site adding roughly 100 times that in additional traffic. The largest attack in the server’s history, experienced in mid-2026, produced zero user-visible impact. Nobody noticed.

That outcome required abandoning every standard tool described in this article - not because those tools are useless, but because at the scale and sophistication of the attacks encountered, none of them were sufficient. The solution that works operates at the network and kernel level before traffic reaches any application layer, uses adaptive behavioural detection rather than static signatures or per-IP thresholds, handles the blocking of millions of IP addresses without per-packet traversal overhead, and was built empirically from months of observation of real attack traffic on a live system.

No off-the-shelf tool does all of this. It required custom development informed by direct operational experience of what the actual attacks look like in practice. That knowledge cannot be acquired from documentation or theory. It can only be acquired by running a public server under sustained attack and watching carefully what happens.

Tools Designed for a Different Era

It is worth being honest about what fail2ban and IP blocklists were originally designed for. Ten to twenty years ago, the dominant threat to small servers was email-related - spam bots trying to relay through open mail servers, credential stuffing against SMTP, brute force login attempts from a relatively small number of IPs. Fail2ban and blocklists were built to answer that threat. They did, and they did it well.

That threat still exists but it is a small fraction of what servers now face. The volumetric botnet attack from millions of compromised consumer devices, operating at low rate per IP, targeting web infrastructure across every port and endpoint, is a fundamentally different problem from what the standard toolset was designed to handle. Applying 2005-era solutions to 2026-era attacks is not going to work. The tools are not broken. They are just answering the wrong question.

Traffic from email attacks, for what it is worth, has largely disappeared from this server’s logs. It is almost never seen now. The botnets have moved on. The attack surface has shifted entirely to web infrastructure, and the tools most commonly recommended to defend it are the ones that were written to defend something else.

The State of Small Communities

The concern is not just for this server. Many small online communities are struggling with the same problems and have far fewer resources to throw at them. The typical response, when things get bad enough, is to put everything behind Cloudflare because it appears to be a quick fix. As documented in this article, Cloudflare creates its own significant problems - broken integrations, blocked tooling, attack traffic routed through its own infrastructure, and the fundamental concern of handing availability to an organisation large enough that a single internal bug took down X, Spotify, and portions of Amazon Web Services simultaneously in November 2025.

More and more small communities will go that route anyway, because the alternative - months of custom development, empirical testing under live attack, architectural redesign, and ongoing vigilance - is simply beyond what most volunteers running hobby servers can sustain. The result is an increasing concentration of the community web behind a small number of intermediaries, with all the single-point-of-failure risk that entails.

For other small server administrators facing similar problems, the most useful thing this article can offer is an honest account of how long and how difficult the path was, and which directions lead to dead ends. The standard approaches are worth trying because they handle real categories of attack. They are not worth expecting to be sufficient against sophisticated distributed botnets. Understanding that distinction earlier would have saved months of work.

The attack types will continue to evolve. They always do. There is no endpoint at which the problem can be considered solved. There is only the current state of equilibrium, maintained through ongoing vigilance, until the next shift in the threat landscape requires adaptation again. That is the reality of running a publicly accessible server in 2026, and anyone who tells you otherwise is selling something.

Where Does It End?

Currently approximately 17% of the publicly routable internet is blocked at the network level on this server, and that figure grows steadily. At the current rate it will not be long before it reaches 25%. That number is worth sitting with for a moment. One quarter of the internet generating predominantly bad traffic is not a server configuration problem. It is a global consumer device infection problem on a scale that nobody in any position of authority appears to be seriously addressing.

Last year it became necessary to block the entire of Brazil. Not selected Brazilian ISPs, not specific ranges - the whole country. The volume of attack hits from Brazilian infrastructure was high enough and consistent enough that there was no surgical alternative. The entire country had to come off the table. That is not a statement about Brazilian people. It is a statement about how comprehensively the consumer device infrastructure of an entire nation can be compromised by malware without the government, the ISPs, or the device manufacturers doing anything effective about it.

The same pattern is visible across the Middle East, large parts of Africa, Southeast Asia, and increasingly parts of South America beyond Brazil. Infected pirate TV boxes shipped from factories, compromised home routers, mobile devices loaded with malware - the scale of consumer device infection in these regions is measurable precisely because it shows up as attack traffic against publicly accessible servers like this one. We can see it. We measure it. We block it. Nobody fixes it.

On Geo-blocking and the Question of Discrimination

Some people describe geographic blocking as geo-discrimination. That framing does not hold up to scrutiny. Keeping those doors open does not help the people behind them. It means the server goes down for everyone, including all the legitimate users who are not in those regions. Blocking an infected network is not discrimination against the people on it. It is a defence against the infrastructure they happen to share with millions of compromised devices.

As a free service, there are no legal obligations I am aware of that require me to keep my server accessible to any particular country or region. The EU has various regulations around digital services but as far as I can determine none that compel a free hobby site to accept traffic from networks actively attacking it. I reserve the right to block access to my own services as I see fit. If governments object to geo-blocking, the correct response is to fix the infected networks in their own countries that are making it necessary, not to go after the server administrators who are trying to protect their services against those networks.

In all seriousness, small communities and hobby server operators arguably have grounds to seek some form of accountability for the disruption these infected networks cause. The costs in time, server resources, custom development work, and service disruption are real and sustained. Where is the help from governments or ISPs for the small operators absorbing this damage? The answer, consistently, is silence. The same governments that might object to geo-blocking have shown no interest in addressing the infected consumer infrastructure that makes it necessary. That contradiction is not something I have any power to resolve. I can only protect the server, document what the problem looks like from where I sit, and carry on.