How an automated hacking attempt brought down my WordPress site, and the step-by-step security hardening that prevented it from happening again.
The Silent Crash
It started with a familiar WordPress error that every site owner dreads: “Error establishing a database connection.” My site was completely down. No warning, no gradual slowdown – just offline.
Little did I know that this wasn’t a hosting issue or misconfiguration, but rather a security incident that had been brewing for hours.
The Investigation Begins
Step 1: Immediate Diagnosis
systemctl status mysql
# Output: inactive (dead)
MySQL had crashed. A simple restart brought the site back, but that was just treating the symptom. I needed the root cause.
Step 2: Digging into the Logs
The MySQL error log revealed the smoking gun:
2025-10-26T01:47:17.278972Z [ERROR] [InnoDB] Cannot allocate memory for the buffer pool
2025-10-26T01:47:17.280154Z [ERROR] [InnoDB] Plugin initialization aborted with error Generic error
Memory exhaustion. But why?
Step 3: Connecting the Dots
The system logs told the rest of the story:
Oct 26 01:45:15 server kernel: apache2 invoked oom-killer:
Oct 26 01:45:16 server kernel: out_of_memory: Killed process 21415 (mysqld)
The Out-of-Memory killer had terminated MySQL to save the system. But what consumed all the memory?
The Real Culprit: Automated Vulnerability Scanning
The Apache error log revealed the attack pattern:
[Tue Oct 28 07:20:46.385500 2025] script '/var/www/html/wp-content/plugins/xadm-log.php' not found
[Tue Oct 28 07:20:54.675026 2025] script '/var/www/html/wp-admin/xadm-log.php' not found
[Tue Oct 28 08:41:37.862015 2025] script '/var/www/html/wp-plain.php' not found
[Tue Oct 28 17:49:47.870481 2025] script '/var/www/html/php-info.php' not found
What was happening:
- Automated bots were scanning for common backdoors and vulnerable files
- Each request spawned Apache/PHP processes
- The 1GB RAM server couldn’t handle the concurrent load
- Memory exhaustion triggered the OOM killer
- MySQL was the casualty
The Attack Pattern Analysis
The attackers were probing for:
- Information disclosure:
phpinfo.php,info.php,pinfo.php - Common backdoors:
xadm-log.php,wp-plain.php,postnews.php - Framework vulnerabilities:
app_dev.php,frontend_dev.php
Geographical distribution:
- 51.38.121.102 (France)
- 45.138.16.215 (Russia/Netherlands)
- 43.157.203.73 (Hong Kong) – Most aggressive
- And several others…
The Security Hardening Solution
1. Immediate IP Blocking
sudo ufw deny from 51.38.121.102
sudo ufw deny from 45.138.16.215
sudo ufw deny from 43.157.203.73
2. Fail2Ban Automated Protection
Configuration:
sudo nano /etc/fail2ban/jail.d/wordpress.conf
[wordpress-hard]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/apache2/error.log
maxretry = 2
bantime = 86400
findtime = 600
[wordpress-soft]
enabled = true port = http,https filter = wordpress logpath = /var/log/apache2/error.log maxretry = 5 bantime = 3600 findtime = 600
Filter definition:
# /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^.*script '.*/.*\.php' not found or unable to stat.*client <HOST>
ignoreregex =
3. Resource Optimization
MySQL memory tuning:
# /etc/mysql/my.cnf
[mysqld]
innodb_buffer_pool_size = 64M key_buffer_size = 16M tmp_table_size = 16M max_connections = 30
Apache process limiting:
# /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
StartServers 2
MinSpareServers 2
MaxSpareServers 5
MaxRequestWorkers 30
MaxConnectionsPerChild 1000
</IfModule>
The Results
Before Protection:
- Downtime: could be for days unnoticed
- Manual intervention required: Yes
- Recurrence: Likely
After Protection:
- Automatic blocking: IPs banned within minutes of detection
- Zero downtime: Attacks handled automatically
- Resource stability: No more memory exhaustion
Fail2Ban in Action:
2025-10-28 22:24:37,521 fail2ban.actions: NOTICE [sshd] Ban 134.209.200.154
# WordPress bans now happen automatically for vulnerability scanners
Key Takeaways
- Monitor Your Logs: Regular log review catches attacks before they cause damage
- Security Through Obscurity Isn’t Enough: Even “failed” attacks can take down your server
- Automate Defense: Manual IP blocking doesn’t scale against distributed attacks
- Right-Size Your Resources: Know your server’s limits and configure services accordingly
- Defense in Depth: Combine Fail2Ban, firewall rules, and service hardening
Prevention Checklist
- [ ] Install and configure Fail2Ban
- [ ] Set up log monitoring alerts
- [ ] Harden MySQL and Apache configurations
- [ ] Implement a Web Application Firewall (WAF)
- [ ] Regular security audits and updates
- [ ] Resource monitoring with alerts
Conclusion
What seemed like a random server crash was actually a security event. The attack wasn’t sophisticated – just automated, persistent, and resource-intensive enough to overwhelm an unprepared system.
The solution wasn’t complex either: proper monitoring, automated defense, and resource management. The entire protection system was implemented with open-source tools and about an hour of configuration.
Your server will get scanned. The question isn’t if, but when – and whether you’re prepared to handle it automatically.

Leave a Reply