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(','));
}
Pingback: [RESOLVED]How to implement Geo Block in ASP.Net? | ASP Questions & Answers
Pingback: [RESOLVED]How to implement Geo Block in ASP.Net? | ASP Web Form Data Control