针对上述问题有两种方法:
- 使用 IIS 动态 IP 限制模块
- 在 Github 上使用 HackerSpray 库
对于第一种方法,
IIS 的动态 IP 限制扩展为 IT 专业人员和主机提供了一个可配置的模块,该模块通过临时阻止遵循以下模式的 HTTP 客户端的 Internet 协议 (IP) 地址来帮助减轻或阻止拒绝服务攻击或通过暴力破解密码有利于其中一种攻击。可以配置此模块,以便可以在 Web 服务器或网站级别进行分析和阻止。
来源:https ://www.iis.net/downloads/microsoft/dynamic-ip-restrictions :
对于第二种方法,
HackerSpray 使用 Redis 为操作和源 IP 维护高性能计数器。你调用 Hacker.Defend(key, ip) 来检查某个键或 IP 是否有太多的点击。您可以维护密钥、IP 或 IP 范围的黑名单。HackerSpray 会检查是否有过多的按键点击、过多的 IP 点击或 IP 落入黑名单。它还允许将某个 IP 的某个密钥列入黑名单或即时阻止所有 IP 的某个密钥。当您想阻止用户访问某些 URL 时很方便。
它带有一个 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);
登录控制器示例:
[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 服务器的连接字符串。
- prefix - 在 redis 中创建的所有键都以此为前缀。
- 密钥 - 您要保护的每个路径一个条目
- name - 要匹配的路径
- 发布 - 真 = 发布,假 = 获取
- maxAttempts - 允许的最大命中数
- 间隔 - 点击多长时间?
- mode - 如何计算命中数并应用阻塞
- perkey - 计算从所有 IP 到此键的点击次数。例如,在 10 分钟内允许最多 1000000 次主页点击。
- perorigin - 在检查此键的命中时,如果源 IP 产生的任何键的总命中次数超过了 maxAttempts,则阻止。例如,对于任何键,每个 IP 允许 1000 次点击,但在登录页面点击时执行此检查。
- perkeyorigin - 按 IP 计算对该键的点击次数。例如,登录页面上每个 IP 有 1000 次点击。
学分/来源:https ://github.com/oazabir/HackerSpray