短時間に多くの要求を送ってくるクライアントに対して、IPアドレスベースでブロックするのが、Dynamic IP Address Restrictions になります。
Windows Azure では、すでに Web サイトで Web.Config に必要なセクションを追加することで Dynamic IP Address Restrictions モジュールが使えるようになっていますよね。
http://wabj.azurewebsites.net/?p=2341
今回、この Dynamic IP Address Restrictions をクラウドサービスで使えるようにして、簡単な実験をしてみようという内容になります。
1.Webロールを含んだプロジェクトを作って、ServiceDefitition.csdef を開いて管理者権限に設定します。
<Runtime executionContext="elevated"></Runtime>
2.ServiceConfiguration.Cloud(Local).cscfgファイルの osFamily が 3 に設定されていることを確認します。
3.参照設定に %windir%\system32\inetsrv にある Microsoft.Web.Administration を追加します。
4.WebRole.cs を下記のように編集します。
using System.Diagnostics; using Microsoft.Web.Administration; using Microsoft.WindowsAzure.ServiceRuntime; namespace MvcWebRole1 { public class WebRole : RoleEntryPoint { public override bool OnStart() { // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. ExecuteCommand("cmd.exe", "\" /c dism /online /enable-feature /featurename:IIS-IPSecurity\""); InitDynamicIpSecurity(); return base.OnStart(); } private void ExecuteCommand(string exe, string arguments) { using (var p = new Process()) { p.StartInfo.FileName = exe; p.StartInfo.Arguments = arguments; p.StartInfo.CreateNoWindow = true; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardError = true; p.StartInfo.Verb = "RunAs"; p.Start(); var results = p.StandardError.ReadToEnd(); p.WaitForExit(60000); p.Close(); } } private void InitDynamicIpSecurity() { using (var serverManager = new ServerManager()) { // セクションロック解除 var appHostConfig = serverManager.GetApplicationHostConfiguration(); var section = appHostConfig.RootSectionGroup.SectionGroups["system.webServer"].SectionGroups["security"].Sections["dynamicipsecurity"]; section.OverrideModeDefault = @"Allow"; serverManager.CommitChanges(); var site = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"]; var webConfig = serverManager.GetWebConfiguration(site.Name); // Dynamic IP Address Restrictions 設定 var dipsSection = webConfig.GetSection("system.webServer/security/dynamicIpSecurity"); dipsSection.SetAttributeValue("denyAction", "Forbidden"); var concurrentElement = dipsSection.GetChildElement("denyByConcurrentRequests"); concurrentElement.SetAttributeValue("enabled", false); var requestrateElement = dipsSection.GetChildElement("denyByRequestRate"); requestrateElement.SetAttributeValue("enabled", true); requestrateElement.SetAttributeValue("maxRequests", 5); requestrateElement.SetAttributeValue("requestIntervalInMilliseconds", 1000); serverManager.CommitChanges(); } } } }
今回の実験では、requestIntervalInMilliseconds を1秒、maxRequests を5に設定しているので、1秒以内に5を超える要求をしたクライアントには Forbidden を返すようにしています。
それではデプロイしてる間に、下記の様なサイトにアクセスする簡単な PowerShell を作っておき、デプロイが完了したら実行してみましょう。
1..10|% { $ie = new-object -com "InternetExplorer.Application"; $ie.navigate("クラウドサービスにURL"); $ie.visible = $true; }