2011-06-14 67 views

回答

3

這是一個廣泛的領域,所以如果你能具體談談您的應用程序,或者你想防止威脅的水平,我相信更多的人能夠幫你。但是,您可以結合使用緩存解決方案,如Squid:http://www.blyon.com/using-squid-proxy-to-fight-ddos/,Dynamic IP Restriction(動態IP限制)(如Jim所解釋的),並且如果您擁有基礎結構,則可以使用主動 - 被動故障轉移設置,其中您的被動機器提供的佔位符內容不會觸及您的數據庫/任何其他機器。這是最後的防守,讓您減少時間DDOS可能帶來整個站點離線。

1

可以肯定的硬件解決方案是爲了防止DOS攻擊是最好的選擇,但考慮到中,你必須要硬件配置或IIS設置沒有訪問權限的情況下,這絕對是爲什麼開發人員必須有一些方便阻止或至少減少攻擊效果。

邏輯的核心概念依賴於一個FIFO(先入先出)集合,如隊列,但因爲它有一定的侷限性,我決定創建自己的收藏。

沒有討論更多的細節,這是完整的代碼我使用:

public class AntiDosAttack 
{ 
    readonly static List<IpObject> items = new List<IpObject>(); 

    public static void Monitor(int Capacity, int Seconds2Keep, int AllowedCount) 
    { 
    string ip = HttpContext.Current.Request.UserHostAddress; 

    if (ip == "") 
    return; 

    // This part to exclude some useful requesters 
    if(HttpContext.Current.Request.UserAgent != null && HttpContext.Current.Request.UserAgent == "Some good bots") 
     return; 

    // to remove old requests from collection 
    int index = -1; 
    for (int i = 0; i < items.Count; i++) 
    { 

     if ((DateTime.Now - items[i].Date).TotalSeconds > Seconds2Keep) 
     { 
     index = i; 
     break; 
     } 
    } 

    if (index > -1) 
    { 
     items.RemoveRange(index, items.Count - index); 
    } 

    // Add new IP 
    items.Insert(0, new IpObject(ip)); 

    // Trim collection capacity to original size, I could not find a better reliable way 
    if (items.Count > Capacity) 
    { 
     items.RemoveAt(items.Count - 1); 
    } 

    // Count of currect IP in collection 
    int count = items.Count(t => t.IP == ip); 

    // Decide on block or bypass 
    if (count > AllowedCount) 
    { 
     // alert webmaster by email (optional) 
     ErrorReport.Report.ToWebmaster(new Exception("Blocked probable ongoing ddos attack"), "EvrinHost 24/7 Support - DDOS Block", ""); 

     // create a response code 429 or whatever needed and end response 
     HttpContext.Current.Response.StatusCode = 429; 
     HttpContext.Current.Response.StatusDescription = "Too Many Requests, Slow down Cowboy!"; 
     HttpContext.Current.Response.Write("Too Many Requests"); 
     HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client. 
     HttpContext.Current.Response.SuppressContent = true; // Gets or sets a value indicating whether to send HTTP content to the client. 
     HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event. 
    } 
    } 

    internal class IpObject 
    { 
    public IpObject(string ip) 
    { 
     IP = ip; 
     Date = DateTime.Now; 
    } 

    public string IP { get; set; } 
    public DateTime Date { get; set; } 
    } 
} 

內部類的設計,以保持請求的日期。

自然DOS攻擊請求,對每個請求創建新的會話,同時在網站上的人請求包括打包成一個會話的多個請求,因此該方法可以在session_start被調用。

用法:

protected void Session_Start(object sender, EventArgs e) 
{ 
    // numbers can be tuned for different purposes, this one is for a website with low requests 
    // this means: prevent a request if exceeds 10 out of total 30 in 2 seconds 
    AntiDosAttack.Monitor(30, 2, 10); 
} 

一個沉重的請求的網站你可能會改變秒,毫秒,但考慮到因該代碼的額外負擔。

我不知道是否有更好的解決方案,以阻止對網站蓄意攻擊,所以我很感謝任何意見和建議,以提高代碼。到那時我認爲這是防止DOS網站上的DOS攻擊的最佳實踐。