从ApplicationBeginRequest等直接网站(在本例中为ASP.NET MVC)中检测DOS攻击和攻击者的最佳方法是什么。
我在这个网站上搜索过,发现了一个类似的问题,没有任何答案或例子。谷歌也没有找到任何结果。
Restrict IP's by code in Asp.net MVC
我知道IIS上的动态IP地址限制,但我希望该网站检测此类攻击并发送电子邮件警报。
很遗憾,我无法访问我的IIS日志,因为我的网站位于共享主机上。
答案 0 :(得分:2)
DDOS攻击是分布式拒绝服务。如果它是以一种聪明的方式完成的(使用semisyncronized僵尸网络,不会疯狂地发送垃圾邮件,但使用间歇性的请求泛滥),那么我不确定是否确实存在检测它的好方法。检测DDoS需要大量的统计分析,而攻击者知道正在分析的内容和方式,可以修补他的僵尸网络以防止漏洞。
好吧,如果每分钟有多个请求或类似的请求(MSDN,StackOverflow),您就可以检测到您的网站过载了。但是你会做什么 - 只是中止它们并在过载期间禁止IP?在没有附带损害的情况下,很难以可靠的方式分析和预防DDoS。
答案 1 :(得分:2)
随着我对你的问题的评论的警告(即,这实际上阻止了DDOS,因为DDOS可能发生在网络堆栈中的较低级别),这里是基于漏洞的速率限制器在过去的几年里,我的目的很好地实现了目标:
public class RateLimiter
{
private readonly double numItems;
private readonly double ratePerSecond;
private readonly ConcurrentDictionary<object, RateInfo> rateTable =
new ConcurrentDictionary<object, RateInfo>();
private readonly double timePeriod;
public RateLimiter(double numItems, double timePeriod)
{
this.timePeriod = timePeriod;
this.numItems = numItems;
ratePerSecond = numItems / timePeriod;
}
public double Count
{
get
{
return numItems;
}
}
public double Per
{
get
{
return timePeriod;
}
}
public bool IsPermitted(object key)
{
var permitted = true;
var now = DateTime.UtcNow;
rateTable.AddOrUpdate(
key,
k => new RateInfo(now, numItems - 1d),
(k, rateInfo) => {
var timePassedSeconds =
(now - rateInfo.LastCheckTime).TotalSeconds;
var newAllowance =
Math.Min(rateInfo.Allowance
+ timePassedSeconds
* ratePerSecond,
numItems);
if (newAllowance < 1d)
{
permitted = false;
}
else
{
newAllowance -= 1d;
}
return new RateInfo(now, newAllowance);
});
var expiredKeys = rateTable
.Where(kvp =>
(now - kvp.Value.LastCheckTime) >
TimeSpan.FromSeconds(timePeriod))
.Select(k => k.Key);
foreach (var expiredKey in expiredKeys)
{
Reset(expiredKey);
}
return permitted;
}
public void Reset(object key)
{
RateInfo rr;
rateTable.TryRemove(key,out rr);
}
internal struct RateInfo
{
private readonly double allowance;
private readonly DateTime lastCheckTime;
public RateInfo(DateTime lastCheckTime, double allowance)
{
this.lastCheckTime = lastCheckTime;
this.allowance = allowance;
}
public DateTime LastCheckTime
{
get
{
return lastCheckTime;
}
}
public double Allowance
{
get
{
return allowance;
}
}
}
}
确保您的密钥适合存储在哈希表中(例如,它们实现相等和.GetHashCode
)并像这样使用它:
void Main()
{
var limiter=new RateLimiter(5,1); //permit 5 items every 1 second
AddStuff(limiter);
Thread.Sleep(10000);
}
async Task AddStuff(RateLimiter limiter)
{
for(var i=0;i<10000;++i)
{
Console.WriteLine(limiter.IsPermitted("foo"));
await Task.Delay(10);
}
}