Friends, Technology, Web2.0 - What I am reading

    [Home] [Recent] [Site Map]

   

动态封杀与解封IP

我们在应对网站的恶意请求时候,一个解决方法就是把有问题的请求IP封杀掉。

如果想快速处理这种问题,就需要编写一段代码,达到一定门槛,自动封杀。再复杂点就是不是永久封杀,还可以自动在一定时间后解封。

封杀的逻辑代码看后面提供的。

需要说明的是:IIS7时,情况发生了不同。

 

下面的代码,在处理封杀IP时候,不论IIS6还是IIS7 都可以把需要封杀的IP加入封杀列表。但是需要注意的是我们代码写的是全部替换原先的数据。但是在IIS7下,执行的效果是原先的不替换,新加一批封杀IP。当然IIS7下,如果新加的IP原来就有了,则会报如下异常:

System.Runtime.InteropServices.COMException was caught
  Message="当文件已存在时,无法创建该文件。 (异常来自 HRESULT:0x800700B7)"
  Source="System.DirectoryServices"
  ErrorCode=-2147024713
  StackTrace:
       在 System.DirectoryServices.DirectoryEntry.CommitChanges()
       在 IIS_Security_ConsoleApplication.Program.IPDeny() 位置 D:\MyCodes\IIS_Security_ConsoleApplication\IIS_Security_ConsoleApplication\Program.cs:行号 109
  InnerException:

这就是说,IIS7, 我们可以通过编程接口增加封杀IP名单,但是没发通过编程接口剔出封杀IP。

 

参考代码:

这里提供了两套参考代码,其实原理都是一样的。

在IIS 6 下,都没有任何问题, IIS 7 下都会有没发删除原先已有数据的问题。

代码一:


using System.DirectoryServices;
using System.Reflection;
using System;

class Program
{

static void IPDeny()
{

try
{
string serverName = "localhost";
// retrieve the directory entry for the root of the IIS server
System.DirectoryServices.DirectoryEntry IIS = new System.DirectoryServices.DirectoryEntry(
string.Format("IIS://{0}/w3svc/1/root", serverName));

// retrieve the list of currently denied IPs
Console.WriteLine("Retrieving the list of currently denied IPs.");

// get the IPSecurity property
Type typ = IIS.Properties["IPSecurity"][0].GetType();
object IPSecurity = IIS.Properties["IPSecurity"][0];


// retrieve the IPDeny list from the IPSecurity object
Array origIPDenyList = (Array)typ.InvokeMember("IPDeny", BindingFlags.DeclaredOnly | BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, IPSecurity, null);

// 罗列已经被拒绝的地址
foreach (string s in origIPDenyList)
Console.WriteLine("Before: " + s);

// check GrantByDefault. This has to be set to true,
// or what we are doing will not work.
bool bGrantByDefault = (bool)typ.InvokeMember("GrantByDefault", BindingFlags.DeclaredOnly | BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, IPSecurity, null);

Console.WriteLine("GrantByDefault = " + bGrantByDefault);
if (!bGrantByDefault)
{
// 必须设置 默认允许访问
typ.InvokeMember("GrantByDefault", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.SetProperty, null, IPSecurity, new object[] { true });
}


// 更新被拒绝的IP列表
// 注意这里是完全替换
// 如果你想保留原先的拒绝列表,需要原先的拒绝列表也在这个数组中

Console.WriteLine("Updating the list of denied IPs.");

object[] newIPDenyList = new object[4];
newIPDenyList[0] = "192.168.1.21, 255.255.255.255";
newIPDenyList[1] = "192.168.1.22, 255.255.255.255";
newIPDenyList[2] = "192.168.1.23, 255.255.255.255";
newIPDenyList[3] = "192.168.1.24, 255.255.255.255";

Console.WriteLine("Calling SetProperty");

// add the updated list back to the IPSecurity object
typ.InvokeMember("IPDeny", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.SetProperty, null, IPSecurity, new object[] { newIPDenyList });



IIS.Properties["IPSecurity"][0] = IPSecurity;

Console.WriteLine("Commiting the changes.");

// commit the changes
IIS.CommitChanges();
IIS.RefreshCache();

// 检查更新后的数据
Console.WriteLine("Checking to see if the update took.");

IPSecurity = IIS.Properties["IPSecurity"][0];
Array y = (Array)typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.GetProperty, null, IPSecurity, null);

foreach (string s in y)
Console.WriteLine("After: " + s);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString());
}

}
}

 

代码二:

        using System.DirectoryServices;
using System.Reflection;
using System;



static void SetIPSecurityProperty(string metabasePath, string member, string item)
{
// metabasePath is of the form "IIS://<servername>/<path>"
// for example "IIS://localhost/SMTPSVC/1"
// member is of the form "IPGrant|IPDeny|DomainGrant|DomainDeny"
// item is of the form "<ipaddress|domain>", for example, 157.56.236.15 or domain.microsoft.com
Console.WriteLine("\nEnumerating the IPSecurity property at {0}:", metabasePath);

try
{
if (("IPGrant" != member) && ("IPDeny" != member) && ("DomainGrant" != member) && ("DomainDeny" != member))
{
Console.WriteLine(" Failed in SetIPSecurityProperty; second param must be one of IPGrant|IPDeny|DomainGrant|DomainDeny");
}
else
{
DirectoryEntry path = new DirectoryEntry(metabasePath);
path.RefreshCache();
object ipsecObj = path.Invoke("Get", new string[] { "IPSecurity" });
Type t = ipsecObj.GetType();
Array data = (Array)t.InvokeMember(member, BindingFlags.GetProperty, null, ipsecObj, null);
Console.WriteLine(" Old {0} =", member);
bool exists = false;
foreach (object dataItem in data)
{
Console.WriteLine(" {0}", dataItem.ToString());
if (dataItem.ToString().StartsWith(item))
{
exists = true;
}
}

if (exists)
{
Console.WriteLine(" {0} already exists in {1}", item, member);
}
else
{
object[] newData = new object[data.Length + 1];
data.CopyTo(newData, 0);
newData.SetValue(item, data.Length);

t.InvokeMember(member, BindingFlags.SetProperty, null, ipsecObj, new object[] { newData });

path.Invoke("Put", new object[] { "IPSecurity", ipsecObj });

path.CommitChanges();

path.RefreshCache();
ipsecObj = path.Invoke("Get", new string[] { "IPSecurity" });
data = (Array)t.InvokeMember(member, BindingFlags.GetProperty, null, ipsecObj, null);
Console.WriteLine(" New {0} =", member);
foreach (object dataItem in data)
Console.WriteLine(" {0}", dataItem.ToString());
Console.WriteLine(" Done.");
}
}
}
catch (Exception ex)
{
if ("HRESULT 0x80005006" == ex.Message)
Console.WriteLine(" Property IPSecurity does not exist at {0}", metabasePath);
else
Console.WriteLine("Failed in SetIPSecurityProperty with the following exception: \n{0}", ex.Message);
}
}

static void Main(string[] args)
{

// 获取目前服务器上有哪些站点
DirectoryEntry root = new DirectoryEntry("IIS://localhost/W3SVC");
foreach (DirectoryEntry dir in root.Children)
{
if (dir.SchemaClassName == "IIsWebServer")
{
string ww = dir.Properties["ServerComment"].Value.ToString();

Console.Write("IIS://localhost/W3SVC/{0}/ROOT/ {1}\r\n", dir.Name, ww);
}
}


// IPDeny();

SetIPSecurityProperty("IIS://localhost/w3svc/1/root", "IPDeny", "192.168.5.79");

Console.ReadLine();
}

 

参考资料:

Blocking IIS IP Addresses with ASP.NET
http://www.west-wind.com/WebLog/posts/59731.aspx

How to Programmatically add IP Addresses to IIS"s Deny Access List
http://www.codeproject.com/KB/security/iiswmi.aspx

HOWTO: 通过 IP 地址或域名称限制站点访问
http://support.microsoft.com/default.aspx/kb/324066

使用ADSI来操作IIS的路径
http://blog.joycode.com/ghj/archive/2004/06/08/24047.aspx

Setting IP Security Using System.DirectoryServices
http://www.cnblogs.com/drw/articles/17951.html

如何通过WEB方式,来控制iis的禁用IP名单。
http://blog.joycode.com/ghj/archive/2004/06/08/24075.aspx

Setting IP Security Using System.DirectoryServices
http://msdn.microsoft.com/en-us/library/ms524322(VS.85).aspx

how to automate adding denied IPs for IIS

http://www.nukeforums.com/forums/viewtopic.php?p=54746&highlight=&sid=1176c746e2037ed24acac86dd53ca747

IIS 7.0: Configure IPv4 Address and Domain Name Allow Rules
http://technet2.microsoft.com/windowsserver2008/en/library/d0de9475-0439-4ec1-8337-2bcedacd15c71033.mspx?mfr=true


>>Source Link
>>Blog: joycode
>>Publish Date: 5/8/2008 7:02:29 AM

Other Posts:
>>每个分类取最新的几条的SQL实现
>>在服务里面弹出一个窗口到用户的桌面上
>>OBA开发系列课程Video制作中...
>>4月28日链接篇: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Silverlight
>>Silverlight FlickR 示例
>>InfoQ 采访:框架设计工作室(Framework Design Studio)发布了
>>ASP.NET动态数据的更新发布了
>>在代码图库(Code Gallery)中访问热修复程序(Hotfix)
>>Mesh it Up!
>>我在奥兰多ASP.NET Connections大会上做的讲座的讲义
>>使用IronRuby定义asp.net mvc路由和视图
>>【编程游戏】划拳机器人比赛


Month Archives:

Top Tags:
Company & Product Profiles Google Internet Technology Search feature Business and Technology Web2.0 column analysis 服务介绍 application letter comment 业界信息 news Startups deal China2.0 Search Headlines 產業策進 未來趨勢 創投 Social Network widget 創業案例 news_in 业界动态 Google/SEO Web 2.0 News & Ideas SEW Experts


@2007 All rights Reserved