sudo apt-get install libapache2-mod-geoip
sudo a2enmod geoip
sudo apt-get install geoip-database
Add to your Apache virtual host configuration or .htaccess:
# Enable GeoIP
GeoIPEnable On
GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
# Block specific countries (example: CN for China, RU for Russia)
SetEnvIf GEOIP_COUNTRY_CODE ^(CN|RU)$ BlockCountry
Order Allow,Deny
Allow from all
Deny from env=BlockCountry
# Custom error page
ErrorDocument 403 /blocked.html
Create blocked.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Access Denied</title>
</head>
<body>
<h1>Access Denied</h1>
<p>We apologize, but access to this website is not available in your region.</p>
</body>
</html>
sudo a2enmod ratelimit
Add to your Apache configuration:
# Enable rate limiting module
<IfModule mod_ratelimit.c>
# Limit bandwidth to 400KB/s per IP
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 400
</IfModule>
# Limit requests per minute
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSLogDir "/var/log/mod_evasive"
</IfModule>
sudo apt-get install fail2ban
Create /etc/fail2ban/jail.local:
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/apache2/access.log
maxretry = 3
findtime = 300
bantime = 3600
Create /etc/fail2ban/filter.d/wordpress.conf:
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
^<HOST> .* "POST /xmlrpc.php
ignoreregex =
Add to /etc/fail2ban/jail.local:
[joomla]
enabled = true
filter = joomla
logpath = /var/log/apache2/access.log
maxretry = 3
findtime = 300
bantime = 3600
Create /etc/fail2ban/filter.d/joomla.conf:
[Definition]
failregex = ^<HOST> .* "POST /administrator/index.php.*
^<HOST> .* "POST /index.php\?option=com_users.*
^<HOST> .* "POST /index.php\?option=com_login.*
ignoreregex =
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo apt-get install libapache2-mod-security2
sudo a2enmod security2
cd /etc/modsecurity
sudo wget https://github.com/coreruleset/coreruleset/archive/v3.3.2.tar.gz
sudo tar xvf v3.3.2.tar.gz
sudo mv coreruleset-3.3.2 owasp-crs
sudo mv owasp-crs/crs-setup.conf.example owasp-crs/crs-setup.conf
Edit /etc/modsecurity/modsecurity.conf:
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecResponseBodyAccess On
SecResponseBodyLimit 524288
# Basic protection rules
SecRule REQUEST_HEADERS:Content-Type "text/html" \
"id:1234,phase:1,deny,status:403,msg:'HTML content type not allowed'"
# WordPress-specific rules
SecRule REQUEST_URI "@contains wp-admin" \
"chain,phase:2,id:2000,deny,status:403,msg:'Unauthorized wp-admin access'"
SecRule REMOTE_ADDR "!@ipMatch 192.168.1.1"
# Joomla-specific rules
SecRule REQUEST_URI "@contains /administrator/" \
"chain,phase:2,id:2100,deny,status:403,msg:'Unauthorized administrator access'"
SecRule REMOTE_ADDR "!@ipMatch 192.168.1.1"
SecRule REQUEST_URI "@contains com_users" \
"chain,phase:2,id:2101,deny,status:403,msg:'Unauthorized user component access'"
SecRule REQUEST_METHOD "POST"
# Protect against SQL injection
SecRule ARGS "@detectSQLi" \
"id:3000,phase:2,deny,status:403,msg:'SQL Injection detected'"
# Protect against XSS
SecRule ARGS "@detectXSS" \
"id:4000,phase:2,deny,status:403,msg:'XSS Attack detected'"
Add to your Apache configuration:
<IfModule security2_module>
Include /etc/modsecurity/modsecurity.conf
Include /etc/modsecurity/owasp-crs/crs-setup.conf
Include /etc/modsecurity/owasp-crs/rules/*.conf
</IfModule>
# Update GeoIP database
sudo geoipupdate
# Update ModSecurity rules
cd /etc/modsecurity/owasp-crs
sudo git pull
# Check Fail2ban status
sudo fail2ban-client status
sudo fail2ban-client status wordpress
sudo fail2ban-client status joomla
# Monitor Apache access logs
sudo tail -f /var/log/apache2/access.log | grep "403"
# Monitor ModSecurity logs
sudo tail -f /var/log/modsec_audit.log
# Monitor Fail2ban logs
sudo tail -f /var/log/fail2ban.log
- Add to .htaccess for additional Joomla protection:
# Protect configuration.php
<Files configuration.php>
order allow,deny
deny from all
</Files>
# Protect administrator directory
<Files administrator>
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
require valid-user
</Files>
# Block access to specific file types
<FilesMatch "\.(ini|log|sh|sql)$">
Order allow,deny
Deny from all
</FilesMatch>
- Secure tmp and logs directories:
chmod 750 /path/to/joomla/tmp
chmod 750 /path/to/joomla/logs
After implementing these measures, test your website:
- Use a VPN to test country blocking
- Use Apache Bench to test rate limiting:
ab -n 1000 -c 10 http://your-website.com/
- Test Fail2ban by attempting multiple failed logins
- Use OWASP ZAP or similar tools to test WAF effectiveness
- Always backup your configuration files before making changes
- Test in a staging environment first
- Monitor logs regularly for false positives
- Keep all security modules and rules updated
- Document any custom rules or modifications
For additional security measures, consider:
- Implementing SSL/TLS (Let's Encrypt)
- Regular security audits
- DDoS protection services
- Regular backups
- User access control
Need help with implementation? Create an issue in this repository or contact your system administrator.