ASP.Net模块阻止DOS攻击

标签 asp.net security c#-4.0 denial-of-service

我想以编程方式保护我的 ASP.Net 4.0 网站免受有害的重复请求。如果我注意到某个 IP 的请求数量很高,那么我想将该 IP 阻止一段时间(例如,如果有人编写 FOR 循环并一遍又一遍地请求该网页)。我知道最好的防御措施是不要向未经身份验证的用户提供数据,但不幸的是,某些公共(public)页面数据量很大,我对此无能为力。

我今天查看了一些解决方案,但没有一个令我满意。我猜这是一个非常常见的问题,我不想从头开始实现这样的事情。

我看到了solution implemented as a module我想做同样的事情,但做得更好。我需要以下功能:

  • 检测到非人类模式后阻止 IP
  • 最好作为 HttpModule 实现
  • 允许抓取工具通过
  • 阻止应在一定时间间隔后过期
  • 轻量级:模块不应降低网站速度或访问数据库

最佳答案

解决上述问题有两种方法:

  1. 使用 IIS 动态 IP 限制模块
  2. 使用 Github 上的 HackerSpray 库

对于第一种方法,

The Dynamic IP Restrictions Extension for IIS provides IT Professionals and Hosters a configurable module that helps mitigate or block Denial of Service Attacks or cracking of passwords through Brute-force by temporarily blocking Internet Protocol (IP) addresses of HTTP clients who follow a pattern that could be conducive to one of such attacks. This module can be configured such that the analysis and blocking could be done at the Web Server or the Web Site level.


来源:https://www.iis.net/downloads/microsoft/dynamic-ip-restrictions :

对于第二种方法,

HackerSpray uses Redis to maintain high-performance counters for actions and origin IPs. You call Hacker.Defend(key, ip) to check if a certain key or IP has made too many hits. You can maintain blacklists for key, IP or IP Range. HackerSpray checks against too many hits on a key, too many hits on an IP, or IP falling within blacklists. It also allows blacklisting a certain key for a certain IP or blocking a certain key for all IPs on-the-fly. Handy when you want to block a user out of certain URLs.

它带有一个 HttpModule,可以保护您的整个网站。

调用示例:

var result = await Hacker.DefendAsync("/Account/LogOn", Request.UserHostAddress);

if (result == Hacker.Result.TooManyHitsFromOrigin) 
    await Hacker.BlacklistOriginAsync(Request.UserHostAddress, TimeSpan.FromMinutes(10)); 

else if (result == Hacker.Result.TooManyHitsOnKey) 
    await Hacker.BlacklistKeyAsync("/Account/LogOn", TimeSpan.FromMinutes(10));


 Hacker.DefendAsync("/Account/PasswordReset", Request.UserHostAddress, TimeSpan.FromMinutes(5), 100);
 Hacker.DefendAsync("Username" + username, Request.UserHostAddress);
 Hacker.DefendAsync("Comment", Request.UserHostAddress);

登录 Controller 示例:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
   return await Hacker.DefendAsync<ActionResult>(async (success, fail) =>
   {
       // This doesn't count login failures towards account lockout
       // To enable password failures to trigger account lockout, change to       shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            return await success(RedirectToLocal(returnUrl));
        case SignInStatus.LockedOut:
            return await fail(View("Lockout"));
        case SignInStatus.RequiresVerification:
            return await success(RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }));
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return await fail(View(model));
    }
},
blocked => new HttpStatusCodeResult(HttpStatusCode.Forbidden),
    "ValidLogin:" + model.Email, 3, TimeSpan.FromMinutes(5),
    "InvalidLogin:" + model.Email, 4, TimeSpan.FromMinutes(5),
    Request.GetClientIp()
); }

在 web.config 中,您需要使用 HttpModule 指定要保护的路径。

<HackerSprayConfig redis="localhost" prefix="AuthTest:">
<keys>
  <add name="/Account/LogOn/" post="true" maxAttempts="100" interval="00:10:00" mode="perkeyperorigin" />
  <add name="/Home/" post="false" maxAttempts="10000" interval="00:01:00" mode="perorigin" />
  <add name="/" post="false" maxAttempts="10000" interval="00:01:00" mode="perorigin" />
</keys> </HackerSprayConfig>
  • redis - 这是 Redis 服务器的连接字符串。
  • 前缀 - 在 redis 中创建的所有键都以此为前缀。
  • key - 您要保护的每个路径一个条目
  • name - 要匹配的路径
  • post - true = POST,false = GET
  • maxAttempts - 允许的最大点击次数
  • 间隔 - 点击多长时间?
  • 模式 - 如何计算点击次数并应用阻止
    • perkey - 对所有 IP 对此键的点击进行计数。例如,10 分钟内最多允许主页 1000000 次点击。
    • perorigin - 在检查对此键的命中时,如果源 IP 在任何键上产生的命中总数超过 maxAttempts,则阻止。例如,允许每个 IP 对任意键进行 1000 次点击,但在登录页面点击时执行此检查。
    • perkeyorigin - 每个 IP 对此键的点击次数。例如,登录页面上每个 IP 的点击次数为 1000 次。

鸣谢/来源:https://github.com/oazabir/HackerSpray

关于ASP.Net模块阻止DOS攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9160404/

相关文章:

c# - 如果两个交错数组相等,如何进行单元测试?

c# - 从 web.config 获取连接字符串以在 EF POCO 中使用?

mysql - 如果 "function.mysql-connect"出现在我的网站搜索数据中,人们在试图破解什么?

design-patterns - 观察者实现

ssl - 从 HTTPS 网站检索页面

security - 控制对 future 内容的访问

C#Linq按组选择多列并同时在值字段上应用求和(聚合函数)

c# - 从数据库填充 DropDownList 的正确方法是什么?

c# - ASP.NET MVC 4 跨字段或属性验证

c# - 如何使用 AJAX 将数据发布到 ASP.NET MVC Controller ?