Blocking IP addresses by country on IIS shared hosting

On a shared hosting environment you often won’t have access to ban IP addresses on the IIS level and my shared host didn’t offer the Firewall module for Plesk so I had to come up with a programmatic way of blocking large blocks of IPs. You can setup in your web.config file something called a HTTPModule that works before the page is delivered to the client computer. For this sample I added a key and value to my web.config file that holds my comma separated IP list that I want to block. Since I’m running a site that is focused on the United States there isn’t much overlap on the /24 block area 255.255.255.* so I am only checking the first 3 digit blocks for matches. When a request comes in IpTwentyFourBlockingModule will check the users IP address against the key value blockiptwentyfour to see if there is a match and if it is a match will return 403 forbidden to the client browser, banned!

Coming up with a IP list is another problem. I found IP Location Tools that gives out an API that generates a updated list of IPs for a given country. The problem is the list gets broken out into IP blocks other than /24, you’ll see all ranges of IP blocks that get very complicated very fast and more than I wanted to try and pull off in a days work. I wrote a Flash ActionScript 3 application to consume this data and give me a list of unique IPs 255.255.255 that I could then drop in as the value for blockiptwentyfour. I then added IP tracking for new users and have had to ban some rogue /24 blocks that escaped this list but its kept them at bay and more manageable for now. I’ve already had a colleague suggest that this is still only a stopgap at best and I should develop some kind of throttling system to help prevent spam when I’m not around to watch the site like a hawk.

web.config

1
2
3
4
5
6
7
8
9
10
<configuration>
  <appSettings>
    <add key="blockiptwentyfour" value="41.210.29,41.210.28" />
  </appSettings>
  <system.web>
    <httpModules>
      <add name="IpTwentyFourBlockingModule" type="IpTwentyFourBlockingModule" />
    </httpModules>
  </system.web>
</configuration>

IpTwentyFourBlockingModule.cs – put this is in your App_Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#region Using
 
using System;
using System.Web;
using System.Configuration;
using System.Collections.Specialized;
 
#endregion
 
/// <summary>
/// Block the response to certain IP addresses
/// </summary>
public class IpTwentyFourBlockingModule : IHttpModule
{
 
    #region IHttpModule Members
 
    void IHttpModule.Dispose()
    {
        // Nothing to dispose; 
    }
 
    void IHttpModule.Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }
 
    #endregion
 
    /// <summary>
    /// Checks the requesting IP address in the collection
    /// and block the response if it's on the list.
    /// </summary>
    private void context_BeginRequest(object sender, EventArgs e)
    {
        string ip = HttpContext.Current.Request.UserHostAddress;
        string[] tempIpArray = ip.Split('.');
        string iptwentyfour = tempIpArray[0] + "." + tempIpArray[1] + "." + tempIpArray[2];
 
        if (_IpAdresses.Contains(iptwentyfour))
        {
            HttpContext.Current.Response.StatusCode = 403;
            HttpContext.Current.Response.End();
        }
    }
 
    private static StringCollection _IpAdresses = FillBlockedIps();
 
    /// <summary>
    /// Retrieves the IP addresses from the web.config
    /// and adds them to a StringCollection.
    /// </summary>
    /// <returns>A StringCollection of IP addresses.</returns>
    private static StringCollection FillBlockedIps()
    {
        StringCollection col = new StringCollection();
        string raw = ConfigurationManager.AppSettings.Get("blockiptwentyfour");
 
        foreach (string ip in raw.Split(','))
        {
            col.Add(ip.Trim());
        }
 
        return col;
    }
}

collectipaddresses.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import flash.events.*;
import flash.net.*;
 
var myRequest:URLRequest = new URLRequest("http://iplocationtools.com/country_query.php?country=CI,SN,GH,NA,NG")
var loader:URLLoader = new URLLoader();
 
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(myRequest);
 
function handleComplete(event:Event):void
{
	var loader:URLLoader = URLLoader(event.target);
	//trace(loader.data.replace(/\n/g, "|"));
	var ipArray:Array = loader.data.replace(/\n/g, "|").split("|");
	trace(ipArray.length);
	setTwentyFourBlock(ipArray);
}
 
function setTwentyFourBlock(ipArray:Array)
{
    var	shortIpArray:Array = new Array();
 
	var	lastUniqueIp:String = "";
 
	for each(var ip:String in ipArray)
	{
		var tempIpArray:Array = ip.split(".");
		var stringCurrentIp:String = tempIpArray[0]+"."+tempIpArray[1]+"."+tempIpArray[2]+".0";
		if(stringCurrentIp != lastUniqueIp)
		{
			lastUniqueIp = stringCurrentIp;
			shortIpArray.push(stringCurrentIp);
		}
	}
 
	trace(shortIpArray.length);
	trace(shortIpArray.join(','));
}

All of this work has really kept my free online dating site almost spam free for now but I’m adding IP blocks I’ve missed from time to time.

2 thoughts on “Blocking IP addresses by country on IIS shared hosting

  1. Pingback: [RESOLVED]How to implement Geo Block in ASP.Net? | ASP Questions & Answers

  2. Pingback: [RESOLVED]How to implement Geo Block in ASP.Net? | ASP Web Form Data Control

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>