我正在考慮爲Google App Engine開發應用程序,該應用程序不應該獲得太多流量。我真的不想支付超過免費配額。但是,通過重載應用程序並超過配額,似乎很容易導致拒絕服務攻擊。是否有任何方法可以防止或使其難以超過免費配額?例如,我知道我可以限制來自IP的請求數量(使其難以超過CPU配額),但是有什麼方法可以使難以超出請求或帶寬配額嗎?是否可以防止Google App Engine上的DoSing?
回答
沒有防止DoS的內置工具。如果您使用java編寫Google Apps,則可以使用service.FloodFilter
篩選器。以下代碼將在您的任何Servlet執行之前執行。
package service;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
*
* This filter can protect web server from simple DoS attacks
* via request flooding.
*
* It can limit a number of simultaneously processing requests
* from one ip and requests to one page.
*
* To use filter add this lines to your web.xml file in a <web-app> section.
*
<filter>
<filter-name>FloodFilter</filter-name>
<filter-class>service.FloodFilter</filter-class>
<init-param>
<param-name>maxPageRequests</param-name>
<param-value>50</param-value>
</init-param>
<init-param>
<param-name>maxClientRequests</param-name>
<param-value>5</param-value>
</init-param>
<init-param>
<param-name>busyPage</param-name>
<param-value>/busy.html</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>JSP flood filter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
*
* PARAMETERS
*
* maxPageRequests: limits simultaneous requests to every page
* maxClientRequests: limits simultaneous requests from one client (ip)
* busyPage: busy page to send to client if the limit is exceeded
* this page MUST NOT be intercepted by this filter
*
*/
public class FloodFilter implements Filter
{
private Map <String, Integer> pageRequests;
private Map <String, Integer> clientRequests;
private ServletContext context;
private int maxPageRequests = 50;
private int maxClientRequests = 10;
private String busyPage = "/busy.html";
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
String page = null;
String ip = null;
try {
if (request instanceof HttpServletRequest) {
// obtaining client ip and page URI without parameters & jsessionid
HttpServletRequest req = (HttpServletRequest) request;
page = req.getRequestURI();
if (page.indexOf(';') >= 0)
page = page.substring(0, page.indexOf(';'));
ip = req.getRemoteAddr();
// trying & registering request
if (!tryRequest(page, ip)) {
// too many requests in process (from one client or for this page)
context.log("Flood denied from "+ip+" on page "+page);
page = null;
// forwarding to busy page
context.getRequestDispatcher(busyPage).forward(request, response);
return;
}
}
// requesting next filter or servlet
chain.doFilter(request, response);
} finally {
if (page != null)
// unregistering the request
releaseRequest(page, ip);
}
}
private synchronized boolean tryRequest(String page, String ip)
{
// checking page requests
Integer pNum = pageRequests.get(page);
if (pNum == null)
pNum = 1;
else {
if (pNum > maxPageRequests)
return false;
pNum = pNum + 1;
}
// checking client requests
Integer cNum = clientRequests.get(ip);
if (cNum == null)
cNum = 1;
else {
if (cNum > maxClientRequests)
return false;
cNum = cNum + 1;
}
pageRequests.put(page, pNum);
clientRequests.put(ip, cNum);
return true;
}
private synchronized void releaseRequest(String page, String ip)
{
// removing page request
Integer pNum = pageRequests.get(page);
if (pNum == null) return;
if (pNum <= 1)
pageRequests.remove(page);
else
pageRequests.put(page, pNum-1);
// removing client request
Integer cNum = clientRequests.get(ip);
if (cNum == null) return;
if (cNum <= 1)
clientRequests.remove(ip);
else
clientRequests.put(ip, cNum-1);
}
public synchronized void init(FilterConfig config) throws ServletException
{
// configuring filter
this.context = config.getServletContext();
pageRequests = new HashMap <String,Integer>();
clientRequests = new HashMap <String,Integer>();
String s = config.getInitParameter("maxPageRequests");
if (s != null)
maxPageRequests = Integer.parseInt(s);
s = config.getInitParameter("maxClientRequests");
if (s != null)
maxClientRequests = Integer.parseInt(s);
s = config.getInitParameter("busyPage");
if (s != null)
busyPage = s;
}
public synchronized void destroy()
{
pageRequests.clear();
clientRequests.clear();
}
}
如果您正在使用python,那麼你可能推出自己的過濾器。
我不確定是否有可能,但App Engine FAQs表示如果您能顯示它是DOS攻擊,那麼他們將退還與此次攻擊相關的任何費用。
看來他們現在有一個基於IP地址的過濾器可用於Python和Java(我知道這是一箇舊線程,但它仍然在Google搜索中顯示很高)。
https://developers.google.com/appengine/docs/python/config/dos
它總是可以使用,在App Engine應用程序的前面提供的服務保護功能,拒絕服務。例如,Cloudflare提供備受推崇的服務https://www.cloudflare.com/waf/,還有其他的。這是我的理解(免責聲明:我沒有親自使用過這些服務)這些功能在免費計劃中提供。
在應用程序本身中構建基於memcache的速率限制實現也相當容易。這是我從谷歌搜索這種方法獲得的第一個熱門影片:http://blog.simonwillison.net/post/57956846132/ratelimitcache。這種機制是健全的,並且可以具有成本效益,因爲共享內存緩存使用可能已足夠並且是免費的。此外,走這條路可以讓你控制旋鈕。缺點是應用程序本身必須處理HTTP請求並決定允許或拒絕它,所以可能會有成本(或[免費]配額耗盡)來處理。
完全披露:我在Google上的App Engine上工作,與Cloudflare或Simon Willison沒有任何關係。
最近發佈了GAE firewall,意在取代之前的,相當有限的DoS Protection Service。
它支持通過(REST)管理API編程更新防火牆規則:apps.firewall.ingressRules可以與其他答案中描述的應用內DoS檢測邏輯相結合。不同之處在於,一旦部署規則,違規請求將不再產生費用,因爲它們不會再到達應用程序,因此不需要應用程序內過濾。
- 1. 是否可以在Google App Engine上運行Google Omaha?
- 2. 是否可以在Google App Engine for Java上部署ColdFusion代碼?
- 3. 是否可以在Google App Engine上使用Django 1.2?
- 4. 是否可以在Google App Engine上託管Drupal
- 5. 是否可以在Google App Engine上運行scikit-learn?
- 6. Ajax在Google App Engine上爬行 - HtmlUnit是否可以工作?
- 7. 是否可以在Google App Engine上使用Ruby/jRuby/Java?
- 8. Google App Engine應用可否被禁止訪問Google Docs API
- 9. 是否可以在Google App Engine中編寫協議?
- 10. 是否可以在Python 2.5(Google App Engine)中使用wsgiservice?
- 11. 是否可以在Google App Engine中使用PyMongo?
- 12. 是否可以在Google App Engine中創建參考?
- 13. 是否可以從shell運行Google App Engine SDK?
- 14. Google App-Engine Objectify實體是否可以有多個@Id字段?
- 15. 是否可以在Google App Engine中使用Go供應商庫?
- 16. 是否可以將數據流式傳輸到Google App Engine?
- 17. 是否可以在Google App Engine中保留標準化模型?
- 18. 是否可以在Google App Engine中連接MongoHq?
- 19. 雲終端是否可以使用Google App Engine Standard?
- 20. Google App域上的Google App Engine
- 21. 是否仍有可能在Google App Engine上使用django-mediagenerator
- 22. 是否可以在沒有Google API的情況下從Android訪問Google App Engine?
- 23. 是否可以在Google App Engine上查看部署歷史日誌?
- 24. 是否可以在Google App Engine上運行比特幣?/備擇方案?
- 25. 是否可以在Google App Engine上使用混合PHP + Java Web應用程序?
- 26. Google App Engine是否與Python translate()兼容?
- 27. Google App Engine是否簡單易行?
- 28. Bokeh是否與Google App Engine兼容?
- 29. Google App Engine是否支持PHP?
- 30. Google App Engine是否支持ftp?
謝謝......如果我付錢,那會讓我對這個問題感覺好多了。 – Zifre 2009-05-04 22:04:20
除非您啓用結算功能,否則超出免費配額只會讓您的網站在短時間內離線(遠遠少於一整天)。如果您已明確啓用該功能,它只會向您收費,您可以設置自己的結算上限。 – 2009-05-05 07:36:26
我曾經從一個IP地址下載靜態文件下載(類似於20MB×2小時的東西)的DOS攻擊,我要求退款,他們拒絕,說這不被視爲DOS攻擊。他們說,如果服務因達到您設定的每日預算而停止,這不會被視爲「拒絕」。 我想說我們現在可以更好地發明我們自己的方式來保護DOS攻擊,直到Google解決他們的問題。 – 2013-11-11 09:57:31