先說背景:機器不斷的發送請求或者惡意提交,會給服務器形成很大壓力;針對這種攻擊
最優的策略是判斷提交次數,產生動態驗證碼
,即判斷ip規定時間內重複發送達到N次彈出驗證碼
。下面是小拽在實踐過程當中一個簡單的識別ip,利用session記錄和防護的過程。html
過程以下;服務器
識別ipsession
ip屬於白名單直接經過[白名單策略:內網ip+指定ip表]post
利用session存儲ip的請求時間戳ui
校驗規定時間內ip的請求次數this
採起相應的措施.net
/** * 獲取和校驗ip;同時防止短期內屢次提交 * * @notice :彈出驗證碼,須要替換掉echo $echo_str 便可。 * @return string :返回校驗成功的ip */ protected function getAndCheckIP() { // 獲取環境ip if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) $ip = getenv("HTTP_CLIENT_IP"); else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) $ip = getenv("HTTP_X_FORWARDED_FOR"); else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) $ip = getenv("REMOTE_ADDR"); else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) $ip = $_SERVER['REMOTE_ADDR']; else $ip = "unknown"; // check 環境ip if (!$this->isWhiteList($ip)) { $echo_str = "提交過於頻繁,請稍後再試!"; // 構建ip的時間棧數據 if (!is_array($_SESSION[$ip])) { $_SESSION[$ip] = array(); } if (isset($_SESSION[$ip][0])) { $_SESSION[$ip][] = time(); // session 保存時間爲6小時。清理session $post_interval_first = time() - $_SESSION[$ip][0]; if ($post_interval_first > 21600) { $_SESSION[$ip] = array(); } // 兩次提交小於1s,禁止提交 $post_interval_pre = time() - $_SESSION[$ip][count($_SESSION[$ip]) - 3]; if ($post_interval_pre < 1) { echo $echo_str; exit; }; // 您在10s內已經提交了3請求,禁止提交 $post_interval_third = time() - $_SESSION[$ip][count($_SESSION[$ip]) - 3]; if (isset($_SESSION[$ip][3]) && ($post_interval_third < 10)) { echo $echo_str; exit; } // 您在1分鐘期間已經提交了5請求,禁止提交 $post_interval_fifth = time() - $_SESSION[$ip][count($_SESSION[$ip]) - 3]; if (isset($_SESSION[$ip][5]) && ($post_interval_fifth < 60)) { echo $echo_str; exit; } // 6小時內提交10次,禁止提交 if (isset($_SESSION[$ip][10])) { echo $echo_str; exit; } } else { $_SESSION[$ip][] = time(); } } return ($ip); }
白名單策略採用:內網ip放行和特定ip放行code
/** * 檢驗是否存在於白名單中 * * @param $ip :校驗的ip * @return bool :校驗結果 */ function isWhiteList($ip){ /** * 內網ip默認所有存在於白名單中 */ if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)){ return true; } // 是否在寫死的whitelist 裏面 return in_array($ip,$this->_WHTTE_LIST); }
小拽採用的比較簡單的策略,如上面代碼,實際過程當中能夠結合業務需求。htm
1s內禁止重複提交ip
5s內提交上限3次
60s內提交上限5次
6小時內提交上限10次
【轉載請註明:機器屢次惡意提交攻擊簡單防範 | 靠譜崔小拽 】