My WordPress blog hosted on https://adib.express/ was deployed on a Kubernetes on-premise cluster by the end of December 2025, but it was not until January 1, 2026, that I secured it and opened the firewalls to make it publicly accessible.
As a frontend, I have HAProxy which serves on both ports 80 and 443.
Typical HAProxy log entry shows as follows:
2026-01-03T21:29:10.939487+00:00 vps-2153e875 haproxy[351604]: 79.116.218.196:58439 [03/Jan/2026:21:29:10.793] all~ wordpress_80/kube-service-web 0/0/7/ki/145 200 12740 - - ---- 2/2/0/0/0 0/0 "GET https://adib.express/ HTTP/2.0"
The current log file is ‘/var/log/haproxy.log’ and it’s rotated daily, and by the time I was collecting this information it was January 3, 2026, so the file ‘haproxy.log.1’ had all the events from January 2, 2026. Let’s check this log, and extract the requests which experienced 404 (Not Found) error responses, most of them generated by requests from bots/botnets/attackers.
root@vps-2153e875:~# cat /var/log/haproxy.log.1 | grep ' 404 '| awk -F'"' '{print $2}' | awk '{print $1,$2}' | sort | uniq -c | sort -rn
10 GET https://adib.express/wordpress/wp-admin/setup-config.php
9 GET /adminfuns.php
6 GET /images/
6 GET /admin.php
6 GET /about.php
5 GET /wp-good.php
5 GET /goods.php
5 GET /css/
5 GET /assets/images/
5 GET /.env
...
3 GET /adminfuns.php/.well-known/acme-challenge/file.php
3 GET /admin/function.php
3 GET /admin/controller/extension/extension/vx.php
...
3 GET /.git/config
...
2 GET /wp-includes/js/crop/cropper.php
2 GET /wp-includes/js/crop/about.php
2 GET /wp-editor.php
2 GET /wp-content/upgrade/
2 GET /wp-content/themes/twentythirteen/
...
1 GET /0x.php
1 GET /0.php
...
1 GET /+CSCOE+/logon.html
On the previous requests list, we can see that some of them are trying to find sensitive information like ‘.env‘ (files containing environment variables used by some applications) and ‘.git/config‘ configuration files. Other requests are trying to scan WordPress plugins/themes paths ‘wp-*‘ which could have vulnerabilities, while other requests are trying to check the existence of other applications (/+CSCOE+/logon.html – Cisco Adaptive Security Appliance WebVPN portal). The file ‘0x.php‘ is related to Malware files (webshell/backdoor) installed on compromised servers which allow attackers to upload files, run commands, or steal information/data. These are just a few examples of what any Web service available on the Internet receives continuously.
On HAProxy I restricted the access to WordPress paths like {/login, /wp-login.php, /wp-admin, /xmlrpc.php} by requesting an additional ‘HTTP Basic Authentication’ to access to those paths. This will reduce the attempts of logins from botnets/attackers on WordPress login page. Let’s now see how many requests tried and failed to access to the restricted area by looking 401 (Unauthorized) errors.
root@vps-2153e875:~# cat /var/log/haproxy.log.1 | grep ' 401 '| awk -F'"' '{print $2}' | awk '{print $1,$2}' | sort | uniq -c | sort -rn
8 GET https://adib.express/wp-admin/setup-config.php
3 GET /wp-admin/includes/rk2.php
3 GET /wp-admin/images/atomlib.php
2 GET /xmlrpc.php
2 GET /wp-admin/network/admin.php
2 GET /wp-admin/js/
2 GET /wp-admin/css/colors/blue/
2 GET /wp-admin/css/colors/
2 GET /wp-admin/classwithtostring.php
1 GET https://adib.express/xmlrpc.php?rsd
1 GET https://adib.express/login
1 GET /wp-login.php
1 GET /wp-admin/z.php
1 GET /wp-admin/index.php
1 GET /wp-admin/includes/chosen.php
1 GET /wp-admin/includes/
1 GET /wp-admin/alfa.php
1 GET /wp-admin/a.php
1 GET /login.php
1 GET /login.html
1 GET /login
I also set a rate limit configuration on HAProxy (in another Post I’ll cover all those configurations) in order to return http 429 (Too Many Requests) to those IPs which are requesting more than 60 requests in less than one minute, and then use Fail2ban to block them in the firewall temporarily for some time. Below you have the list of the IPs which received a 429 response code because they reached the http requests rate limit. Looking on AbuseIPDB.com by those IPs, we can see that they are reported as having malicious activity.
root@vps-2153e875:~# cat /var/log/haproxy.log.1 | grep ' 429 ' | awk '{print $4}' | sed 's/:.*//' | sort -u
143.198.70.149
172.104.241.92
20.184.35.52
20.42.220.101
4.189.160.96
4.190.195.159
4.190.203.84
4.194.133.126
4.230.44.177
52.141.42.203
52.147.68.81
74.176.56.30
74.225.136.96
Looking at the log details for one particular of those IPs I found something strange. The IP ‘143.198.70.149‘ was able to make http GET/POST requests and get http 200 return code on the path ‘/xmlrpc.php‘ although I previously restricted access to that path.
2026-01-02T07:13:49.683431+00:00 vps-2153e875 haproxy[1112]: 143.198.70.149:50718 [02/Jan/2026:07:13:49.544] all~ wordpress_80/kube-service-web 0/0/1/137/138 200 958 - - ---- 1/1/0/0/0 0/0 "GET //xmlrpc.php?rsd HTTP/1.1"
...
2026-01-02T07:13:50.371694+00:00 vps-2153e875 haproxy[1112]: 143.198.70.149:50718 [02/Jan/2026:07:13:50.256] all~ wordpress_80/kube-service-web 0/0/0/114/114 200 573 - - ---- 1/1/0/0/0 0/0 "POST //xmlrpc.php HTTP/1.1"
Regarding the above requests, I noticed the double forward slash on the paths (//xmlrpc.php) which allowed the attacker to bypass my restrictions. To solve this, I just added a setting on HAProxy to redirect (http 301 Moved Permanently) to the requester to a single forward slash path when the request comes with several slashes. Here is the curl test output after applying this change.
$ curl -I https://adib.express//xmlrpc.php?rsd
HTTP/1.1 301 Moved Permanently
content-length: 0
location: /xmlrpc.php
$ curl -I https://adib.express/xmlrpc.php?rsd
HTTP/1.1 401 Unauthorized
content-length: 112
cache-control: no-cache
content-type: text/html
www-authenticate: Basic realm="basicauthRequired"
Looking at the HAProxy logs, I also noticed that bots were accessing successfully on the following paths, the WordPress API, from where they can list the WordPress users. After that, I restricted access to the ‘/wp-json’ endpoint in order to avoid bots scrapping and copying parts of my site’s content and avoid exploiting possible vulnerabilities.
/wp-json/wp/v2/users/
/?author=1
/feed/atom/
This is why it’s worth taking a look from time to time on logs, we can find interesting things there.
This is my first post. I’ll continue writing more articles in the next days and next weeks.
Adib Ahmed Akhtar