Blocking IP addresses by country on IIS shared hosting

By | May 20, 2009

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


  
    
  
  
    
      
    
  

IpTwentyFourBlockingModule.cs – put this is in your App_Code

#region Using

using System;
using System.Web;
using System.Configuration;
using System.Collections.Specialized;

#endregion

/// 
/// Block the response to certain IP addresses
/// 
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

    /// 
    /// Checks the requesting IP address in the collection
    /// and block the response if it's on the list.
    /// 
    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();

    /// 
    /// Retrieves the IP addresses from the web.config
    /// and adds them to a StringCollection.
    /// 
    /// A StringCollection of IP addresses.
    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

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(','));
}

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 *

Comment moderation is enabled. Your comment may take some time to appear.

This site uses Akismet to reduce spam. Learn how your comment data is processed.