Use GeoIP and htaccess to deny countries access to your website
I run about a dozen websites, and one of them switched over to the XenForo forum software. The problem with forums is once the spambots find it, they’re registering like crazy. My best efforts to use CAPTCHA didn’t work well. Then I added a question which uses AJAX to verify the answer against an external API. That helped but they were still able to figure out a valid answer. They then were manually verifying the registration via email. My best efforts to stop them really only slowed them down. I wanted it to end.
Using a self-hosted Piwik analytics instance I was able to determine that most of the spammers came from India and China. I could have added those two countries known IPs to my firewall, but that’s a lot of overhead. Probably would have been around 8,000 entries. That would have to be updated all the time.
Instead I decided to use Maxmind’s GeoIP database (the free versions), Apache mod_geoip and .htaccess to deny those countries. Sure – denying countries means I’m blocking my content to people who aren’t spammers, but my content isn’t translated to these countries, nor does my SEO target them. So I’m OK with this – your mileage may vary.
I’m running on CentOS 7, and here’s the steps I took to get it going
Install the GeoIP packages and the Apache httpd mod_geoip module:
yum install GeoIP GeoIP-devel GeoIP-data zlib-devel mod_geoip
Update the httpd geoip conf as below, which adds in a 2nd database which contains City information:
<IfModule mod_geoip.c> GeoIPEnable On GeoIPDBFile /usr/share/GeoIP/GeoIP.dat GeoIPDBFile /usr/share/GeoIP/GeoIPCity.dat </IfModule>
- Create this bash script which will download the databases.
#!/bin/bash #Download Maxmind GeoIP databases cd /usr/share/GeoIP mv GeoIP.dat GeoIP.dat.old mv GeoIPCity.dat GeoIPCity.dat.old /bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz /bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz gunzip GeoIP.dat.gz gunzip GeoLiteCity.dat.gz mv GeoLiteCity.dat GeoIPCity.dat
Make it executable:
chmod +x /root/geoip_updater.sh
Run the script to get a fresh copy of both databases:
Restart Apache httpd to load in the new database and module settings:
sudo systemctl httpd restart
7. Add a crontab entry to automatically download new databases every month.
# GeoIP Updater every 1st day of the month @monthly /root/geoip_updater.sh > /dev/null 2>&1
8. Open up your site’s .htaccess and add the following:
# Block Countries using GeoIP and mod_geoip SetEnvIf GEOIP_COUNTRY_CODE IN BlockCountry SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry Deny from env=BlockCountry
This will block India, China and Russia. You can add more countries to the list as you need, just use their 2 character country code. You can get a list of the country codes here: https://countrycode.org/
That’s it! I’ve seen a dramatic drop in spambot registrations after doing this.
Hopefully this helps someone – or at the very least reminds me how to do this again in the future.