Block unwanted IPs from accessing your website using Apache's .htaccess file.
Block Single IP
Add to your .htaccess
file:
order allow,deny deny from 192.168.1.100 allow from all
Block Multiple IPs
order allow,deny deny from 192.168.1.100 deny from 10.0.0.50 deny from 203.0.113.0 allow from all
Block IP Range
Using CIDR notation:
order allow,deny deny from 192.168.1.0/24 allow from all
Using partial IP:
order allow,deny deny from 192.168.1. allow from all
Block by Country (Using GeoIP)
If mod_geoip is enabled:
GeoIPEnable On SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry deny from env=BlockCountry
Allow Only Specific IPs
Whitelist approach (blocks everyone except listed IPs):
order deny,allow deny from all allow from 192.168.1.100 allow from 203.0.113.50
Block Bad Bots
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} (AhrefsBot|MJ12bot|SemrushBot) [NC] RewriteRule .* - [F,L]
Rate Limiting (Apache 2.4+)
Prevent brute force attacks:
<If "%{REQUEST_URI} =~ m#^/wp-login\.php#"> SetEnvIf Remote_Addr "^" dos_attempt <RequireAll> Require all granted Require not env dos_attempt </RequireAll> </If>
Finding IPs to Block
Check your access logs:
# Most frequent IPs awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -20 # IPs hitting wp-login.php grep "wp-login.php" access.log | awk '{print $1}' | sort | uniq -c | sort -nr # 404 errors by IP awk '$9 == 404 {print $1}' access.log | sort | uniq -c | sort -nr
Testing Your Rules
Test without blocking yourself:
# Add your IP to whitelist first order allow,deny allow from YOUR.IP.HERE deny from 192.168.1.100 allow from all
Common Patterns to Block
Suspicious requests:
RewriteEngine On # Block SQL injection attempts RewriteCond %{QUERY_STRING} (union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|script|set|md5|benchmark) [NC] RewriteRule .* - [F,L] # Block common exploits RewriteCond %{REQUEST_URI} (wp-config\.php|xmlrpc\.php|/\.git|/\.env) [NC] RewriteRule .* - [F,L]
Performance Note
For many IPs (100+), use a firewall instead:
# Better performance with iptables iptables -A INPUT -s 192.168.1.100 -j DROP # Or with UFW ufw deny from 192.168.1.100
Important
- .htaccess is processed on every request - impacts performance
- Always test rules on staging first
- Keep backups of working .htaccess files
- Some hosting providers disable .htaccess overrides