我们在应对网站的恶意请求时候,一个解决方法就是把有问题的请求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(); 
}
 
 
 
posted on 2010-12-17 10:47  Dacia  阅读(804)  评论(0)    收藏  举报