</> Damian Pawela TECH // CYBERSECURITY

[ FIELD NOTES ]

Cybersecurity

← BACK TO ALL ARTICLES

2.35 million HTTP requests. What were the bots looking for on the server, and what did Fail2ban change?

A technical case study covering nearly 11 months of traffic on Apache2: from scans for .env files and webshells, through signatures of known CVEs, to the implementation of security measures and an assessment of their effectiveness.

Every server exposed to the Internet will, sooner or later, be scanned. Bots don’t need to know which application is running on port 443; they simply send a series of requests, check common paths, look for exposed files, and test for known vulnerabilities. A quick analysis of an access.log file is enough to reveal just how automated and widespread this phenomenon is.

What does the actual scanning of a public web server look like, what are these automated bots searching for, and how can such attacks be mitigated using Apache2, Fail2ban, and iptables?

The information and conclusions presented below are based on an analysis of logs from a production server, covering a period of nearly 11 months.

HTTP Requests
2,357,178
Suspicious
570,527
Percentage
24.2%

What do server responses really tell us?

Web applications and websites function by receiving a request from a client's web browser, processing that request on the server, and returning a response. In cybersecurity analysis, we must pay attention to the requests sent to a server, how the server responds to them, and what it returns as a response.

Responses are divided into several categories:
- informational (100 – 199)
- successful (200 – 299)
- redirections (300 – 399)
- client-side errors (400 – 499)
- server-side errors (500 – 599)

The full specification can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status

Between December 2025 and October 2026, the server returned over 1.45 million 404 responses—indicating an error when an attempt was made to access an invalid URL. From a security perspective, some of these responses may be benign; for instance, a browser might have attempted to load a missing favicon.ico file or a missing css/js file. Such occurrences generally do not constitute a security incident.

However, when a single source (IP address) checks paths such as /.env, /.git/config, PHP files typically associated with webshells, and PHPUnit endpoints within a short period, it indicates a potential attack.

Most Frequently Targeted Vulnerabilities

The analyzed log was dominated by two types of attacks: searching for passwords and other access credentials, and scanning for WordPress-related targets.
The categories below overlap; therefore, they cannot be summed, as doing so would be misleading.

.env files and exposed secrets

The most common activity involved checking paths that, in a misconfigured deployment, could reveal database passwords, API keys, mail configurations, or cloud credentials. In the complete dataset, /.env appeared 16 545 times.
Other examples of such files are shown below.

/.env
/.env.local
/.env.production
/.env.bak
/api/.env
/backend/.env
/.aws/credentials
/secrets.json
/terraform.tfstate

This mechanism does not require an advanced exploit; sometimes, an incorrect DocumentRoot, a leftover backup file, or misconfigured permissions are enough. The best protection is to store passwords/tokens outside the public file tree or within server environment variables, and to restrict access at both the application and web server levels.

WordPress and forgotten installations

The statistics show 227 852 requests identified as related to WordPress. Bots searched for installers, login pages, XML-RPC endpoints, configuration files, and plugin directories. They were not limited to the domain's root directory; they also scanned paths such as /old/, /blog/, /wordpress/, and /test/.code>.
The most frequently checked paths are listed below.

/wp-admin/install.php
/wp-login.php
/xmlrpc.php
/wp-config.php.bak
/wp-content/plugins/hellopress/wp_filemanager.php
/wordpress/wp-includes/wlwmanifest.xml

Within the full dataset, 6 323 requests were recorded for /wp-admin/install.php, and 3 902 for /xmlrpc.php.

Searching for existing webshells

The logs show 27 167 matches for patterns associated with backdoors and webshells. Some bots do not look for software vulnerabilities; instead, they search for signs that someone else has already compromised the system and left behind tools for remote access—for example:

/shell.php
/wso.php
/alfa.php
/alfashell.php
/ioxi-o.php
/adminfuns.php

The mere presence of a filename does not confirm the existence of malware—especially if the log shows a 404 error. However, if such a file actually exists, you should verify its content, modification history, and whether it belongs to your legitimate deployment. It could be a remnant of a successful attack.

Exposed Git repositories

I have classified 20 413 requests as attempts to access Git resources. Files such as /.git/config or /.git/HEAD should not be publicly accessible. If CI/CD mechanisms—for example—are misconfigured, these files could make it easier to reconstruct the source code and gain insight into the application's structure and security measures.

Signatures of specific vulnerabilities

Not every scan can be mapped to a specific CVE identifier. However, some requests correspond to characteristic attempts to exploit known historical vulnerabilities.

Signature / CVE What is being checked? Interpretation
CVE-2017-9841 eval-stdin.php in PHPUnit Risk of code execution if the vulnerable file is publicly accessible.
CVE-2024-4577 auto_prepend_file=php://input PHP-CGI pattern; a specific CVE relates to particular Windows configurations.
CVE-2021-3129 /_ignition/execute-solution Identification of vulnerable Laravel Ignition configurations.
CVE-2022-22947 /actuator/gateway/routes Identification of Spring Cloud Gateway; not proof of a complete exploit.

As part of the analysis, I categorized 16 989 requests related to PHPUnit and 1 843 related to PHP-CGI.

What does this mean? Public-facing services are often scanned for technologies that are not even installed on them. The actual risk must always be assessed in the context of the technologies in use, the deployment method, and the specific versions of the components.

Practical analysis of Apache2 logs

Using the standard Apache combined log format, we can quickly extract requests, methods, and HTTP status codes. Example entry (synthetic, with a sample IP address):

xxx.xxx.xxx.xxx - - [19/May/2026:10:15:21 +0200] "GET /.env HTTP/1.1" 404 285 "-" "curl/8.0"

Most active months

Following the implementation of Fail2ban in July 2026, the number of suspicious requests reaching Apache dropped significantly. The full monthly data is provided below.

Month Total HTTP requests Suspicious requests Share
2025-12* 110 583 43 590 39.4%
2026-01 163 915 57 91735.3%
2026-02 409 056 62 573 15.3%
2026-03 322 254 84 460 26.2%
2026-04 273 416 73 828 27.0%
2026-05 261 759 85 796 32.8%
2026-06 370 994 80 880 21.8%
2026-07 / installation and configuration of FAIL2BAN 109 697 18 827 17.2%
2026-08 105 620 17 832 16.9%
2026-09 126 257 26 228 20.8%
2026-10* 103 627 18 596 17.9%
* December from 11/12, October to 25/10.

The monthly average from March to June was approximately 81.2 thousand suspicious requests. In July and August, these figures dropped to around 18 thousand. This is consistent with how firewall-level blocking works: blocked connections do not subsequently appear in the logs.Apache.

Protection: Fail2ban, Apache2, and iptables

Fail2ban is a useful security layer that analyzes logs, identifies patterns, and can block traffic sources either temporarily or permanently.

Example filter for sensitive files

File apache-sensitive-data.conf:

[Definition]
failregex = ^<HOST> \S+ \S+ \[[^\]]+\] "(?:GET|POST|HEAD) /(?:\.env(?:[.? /]|$)|\.git/(?:config|HEAD)(?:[? ]|$))[^\"]*" (?:200|403|404) \d+ .*$
ignoreregex =

This is an example of a narrow filter for the standard combined log format.

Example iptables jail configuration

File /apache-sensitive-data.local:

[apache-sensitive-probes]
enabled = true
filter = apache-sensitive-probes
logpath = /var/log/apache2/access.log
backend = auto
port = http,https
banaction = iptables-multiport
maxretry = 2
findtime = 600
bantime = 86400

Two matches within 10 minutes can trigger a 24-hour ban. Naturally, these thresholds should be adjusted based on traffic volume, monitoring sources, the presence of a reverse proxy, and the acceptable risk of false positives.

Conclusions from the analysis

What should be implemented alongside Fail2ban?

  • Keep passwords and other access credentials outside the DocumentRoot. Block public access to .env files, backups, repositories, and key files.
  • Do not expose testing tools. A production server should not provide access to unnecessary tools like PHPUnit, debuggers, or profilers.
  • Regularly update dependencies. This applies especially to PHP, CMS platforms, plugins, and libraries.
Composer and npm.
  • Disable directory listing. In Apache, use Options -Indexes in the appropriate context.
  • Restrict administrative and diagnostic endpoints. Use VPNs, allowlists, authentication, and environment separation.
  • Collect telemetry from multiple layers. Apache, Fail2ban, iptables, the application, and reverse proxies/WAFs.
  • Monitor for false positives. Do not ban users for single requests—for example, accessing /robots.txt, /favicon.ico, or triggering standard 404 errors.
  • How to measure the effectiveness of your protection?

    Metric What it tells us
    Suspicious requests per day The volume of traffic reaching Apache.
    Unique sources Whether traffic originates from a few scanners or many different addresses.
    Fail2ban bans and re-bans Whether rules are being triggered and if sources are returning.
    200 responses for sensitive paths Which events require manual verification.
    False positive rate Whether the protection is negatively affecting legitimate users.
    KEY TAKEAWAY

    A server does not need to be the target of a specific attacker to face daily attempts to exploit known vulnerabilities. Protection begins with observation: you need to know what is being scanned, what is responding, and which security measures are actually working.