2009-02-01 430 views
7

阻止漫遊器,惡意用戶等執行php腳本的速度太快的最佳方法是什麼?如果我使用usleep()sleep()函數在短時間內執行「無」(恰好在所需的代碼執行之前),或者是簡單的愚蠢並且有更好的方法嗎?推遲執行PHP腳本

例子:

function login() { 
//enter login code here 
} 

function logout() { 
//enter logout code here 
} 

如果我只是把,比如說,usleep(3000000)登錄和註銷碼之前,是好的,還是有更好的,我達到想達到什麼樣的聰明的方式?

編輯:基於下面的建議,並然後usleepsleep僅使所述處理器從當前腳本脫離由當前用戶執行,或者它導致它從整個服務脫離?即,如果一個用戶+腳本調用sleep/usleep,所有併發用戶+腳本是否也會被延遲?

回答

8

的方式大多數Web服務器的工作(如Apache)是保持工作線程的集合。當執行一個PHP腳本,一個線程運行PHP腳本。

當你的腳本執行sleep(100),劇本需要100秒,執行..這意味着你的工作線程綁爲100秒。

的問題是,你有工人線程非常有限數量的 - 說你有10個線程和10人登錄 - 現在你的Web服務器不能提供任何進一步答覆..

以最好的方式限速登錄(或其他操作)是用某種快速內存存儲的東西(memcached非常適合這一點),但是這需要運行單獨的過程,是相當複雜的(如果你運行的東西,如Facebook,你可以這樣做..)。

簡單,你可以有存儲user_idip_addressfirst_failedfailure_counter數據庫表。

每當你得到一個登錄失敗,你(在僞代碼)會做:

if (first_failed in last hour) and (failure_counter > threshold): 
    return error_403("Too many authentication failures, please wait") 
elseif first_failed in last hour: 
    increment failure_counter 
else: 
    reset first_failed to current time 
    increment failure_counter 

也許不是最有效的,且有更好的方法,但應停止暴力破解很好。使用memcached是基本相同,但該數據庫被替換爲分佈式緩存(這是更快)

1

你的建議的方法將強制所有用戶在登錄前等待不必要的。

大多數LAMP服務器(以及大多數路由器/交換機,其實)已經配置以防止拒絕服務攻擊。他們通過拒絕來自同一IP地址的多個連續請求來做到這一點。

1

你不想睡在你的PHP。這樣做會大大減少您的服務器可以處理的併發請求的數量,因爲您將有連接等待。

大多數HTTP服務器都具有可以啓用以避免DoS攻擊的功能,但是如果失敗,您應該只跟蹤最近看到過多次的IP地址,並向他們發送403 Forbidden消息,要求他們等一秒鐘。

如果因爲某些原因你不能指望REMOTE_ADDR是用戶特定的(每個人都在同一個防火牆之後等),你可以在登錄表單中證明一個挑戰,並讓遠程瀏覽器對它進行擴展計算(比如說,一個數字的因子),你可以快速檢查服務器端(快速乘法)。

2

阻止機器人,惡意用戶等 執行php腳本太快?

我會先問你真的想阻止什麼?如果它是拒絕服務攻擊,那麼我不得不說,如果受限於可以添加到PHP腳本中的內容,您就無能爲力。現有技術的水平遠遠超出了我們程序員所能防範的範圍。開始尋找專爲此目的而設計的系統管理員工具。

還是你想限制你的服務,讓真正的人可以訪問它,但機器人不能?如果是這樣,我會看看一些「驗證碼」技術。

或者你是否試圖阻止用戶每秒鐘輪詢你的網站尋找新的內容?如果是這樣,我會調查提供一個RSS提要或其他方式通知他們,所以他們不會吃掉你的帶寬。

還是別的東西?一般來說,我會說sleep()和usleep()都不是好方法。

-
BMB