Before we start, one word about orientation. On the right, you will notice links to the multiple pages in this series about website optimization. If you haven't done so yet, I suggest you also visit my main page about website optimization.
Blocking IPs and Visitors by Country
If you inspect your web traffic, you may have noticed a surprising number of visitors from countries such as China, Russia, Poland, India and Brazil. Maybe your website only offers local information about your small town in Louisiana. Can that many people from overseas can be interested in your local news?
The answers hides in your website's error logs. There, you will see that many of these visitors are trying to access files and folders that do not exist, hoping to hack into your site, perhaps to turn your server into a spamming zombie.
Some webmasters decide to block all traffic from a number of handpicked countries, sacrificing the few legitimate visitors from China who were looking at your site because they planned to fly in next week to catch a movie at the community hall.
There are several ways to deny traffic from a particular country. To my knowledge, all these methods rely on matching the visitor's IP address to some kind of IP geolocation table.
None of the solutions are perfect: determined visitors will be able to access your site through proxies.
Method 1: Maintaining a List on Your Server
To preface, let me state that this is by far my least favorite method.
There are several sites with free lists of IPs for specific countries, ready to download, sites such as Okean for Chinese and Korean IPs, Wizcrafts for Chinese, Russian and Nigerian IPs, Country IP Blocks for a full list of countries, and BlockACountry for another huge list of countries. I don't know how well any of these lists is maintained.
Once you have a list, you can block the IPs in htaccess or httpd.conf. In my view, this is a cumbersome way of blocking visitors from certain countries, because IPs change all the time. Do you want to update your IP country table all the time?
If you did want to use this method, you might add lines like these to your .htaccess:
Order allow,deny Allow from all Deny from 58.14.0.0/15 Deny from 58.16.0.0/16 … etc. (huge list of IP addresses or ranges)
Method 2: Custom Rule in CloudFlare
Update: I do not recommend this method anymore. Click the link to read why I no longer use CloudFlare. I will leave this material here for reference.
On my page about how to block traffic from certain IPs, I explain the free CloudFlare service, in Beta as of Q3 2010.
On a CloudFlare-enabled site, you can add custom rules to block specific IPs or even specific countries. It is fast to implement, and it is extremely convenient because you don't need to update the list of IPs for the countries that you want to block. CloudFlare does that for you.
This method is perfect if you want to use the same rules across all sites. However, it may be that you want to block Russia across most sites, but that one of your sites happens to have many legitimate visitors from Russia. For such situations, you can use Method 3.
Method 3: CloudFlare plus Apache Configuration
If you have several sites and need greater control over which countries you block for each site, you can take advantage of a feature of CloudFlare: the CF-IPCountry variable it inserts in request headers, a variable that contains the geolocation data looked up by CloudFlare.
You can then tweak Apache configuration files to block visitors based on CF-IPCountry.
Flavor 1: Simplest Technique on Shared Hosts
For this technique, you only edit the ".htaccess" file at the root of your web pages. Paste the following at the top of htaccess, just below the "AddHandler" line if any:
SetEnvIf CF-IPCountry CN BuzzOff=1
SetEnvIf CF-IPCountry RU BuzzOff=1
SetEnvIf CF-IPCountry IN BuzzOff=1
Order allow,deny
Allow from all
Deny from env=BuzzOff
In this example, notice "CN", "RU" and "IN" in the first three lines. These stand for China, Russia and India. Edit those to suit your needs (and add or remove as many lines as you like) by consulting the list of internet country abbreviations.
Depending on your needs, you can create different htaccess code for each of your sites.
I suggest you test the implementation by blocking your own country on one of your sites (but make sure you have FTP access to remove the block from your htaccess!)
Flavor 2: Simple Technique for Many Countries on Multiple Sites (Private Hosts only)
Here is an implementation that works great when you maintain a large list of countries that you want to block on multiple sites. For this implementation, you need access to httpd.conf, which is rarely the case on shared hosts.
First, in httpd.conf, paste something like the following before the VirtualHost section, editing the example to add whichever countries you want to block and remove whichever countries you do not want to block. To choose which countries to ban, visit a list of country abbreviations.
SetEnvIf CF-IPCountry BD BuzzOff=1
SetEnvIf CF-IPCountry CN BuzzOff=1
SetEnvIf CF-IPCountry HR BuzzOff=1
SetEnvIf CF-IPCountry HU BuzzOff=1
SetEnvIf CF-IPCountry ID BuzzOff=1
SetEnvIf CF-IPCountry IN BuzzOff=1
SetEnvIf CF-IPCountry LU BuzzOff=1
SetEnvIf CF-IPCountry LV BuzzOff=1
SetEnvIf CF-IPCountry PH BuzzOff=1
SetEnvIf CF-IPCountry PK BuzzOff=1
SetEnvIf CF-IPCountry PL BuzzOff=1
SetEnvIf CF-IPCountry RO BuzzOff=1
SetEnvIf CF-IPCountry RU BuzzOff=1
SetEnvIf CF-IPCountry SI BuzzOff=1
SetEnvIf CF-IPCountry SK BuzzOff=1
SetEnvIf CF-IPCountry TH BuzzOff=1
SetEnvIf CF-IPCountry TW BuzzOff=1
SetEnvIf CF-IPCountry UA BuzzOff=1
SetEnvIf CF-IPCountry VN BuzzOff=1
Then, for each of the websites for which you want to block these countries, open your .htaccess and paste these lines near the top, right below the "AddHandler" line if any:
Order allow,deny
Allow from all
Deny from env=BuzzOff
Below, there is a more complex example for situations where a country is not always blocked.
Don't forget to restart Apache! Here's a tutorial on SetEnvIf if you'd like to tweak the code. And here's some reading on the Order allow,deny directive.
Flavor 3: Blocking a Country on All Sites Except One
Let's say you want to block Russia on all sites except one.
Using "Flavor 2" from above, in httpd.conf, instead of the above, you would have something like:
SetEnvIf CF-IPCountry RU IsRussia=1
SetEnvIf CF-IPCountry CN BuzzOff=1
SetEnvIf CF-IPCountry IN BuzzOff=1
… (other countries to be blocked)
For sites where you don't want to block Russia, your .htaccess would look like this:
Order allow,deny
Allow from all
Deny from env=BuzzOff
For sites where you do want to block Russia, your .htaccess would look like this:
Order allow,deny
Allow from all
Deny from env=IsRussia
Deny from env=BuzzOff
This example should give you an idea of how to further customize country blocking for each site.
China (Russia, etc) is Still Showing in my CloudFlare Threats!
If you have used Method 3, it is normal that your blocked countries will still appear in the list of threats of your CloudFlare dashboard. Why? CloudFlare is your first line of defense. Visitors from China first go to the CloudFlare DNS. There, they may be challenged (and show in your Threats Panel).
The visitors that CloudFlare doesn't block are routed to your server, where they should be blocked by the techniques shown above. Therefore, such visitors should not show in stats reports of pages actually seen, such as those produced by Google Analytics.
Thursday, 15 September 2011
Blocking IPs and Visitors by Country
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment