[英]IP Blacklist in PHP+MySQL
我一直在嘗試在PHP中實現某種IP黑名單,在其中將失敗的登錄嘗試存儲到具有以下架構的MySQL表中:
CREATE TABLE blacklist(
`ip_address` VARCHAR(35) NOT NULL,
`failures` INTEGER DEFAULT 0,
`release_time` BIGINT DEFAULT -1,
PRIMARY KEY(`ip_address`)
);
在進行登錄檢查時,我首先使用以下查詢刪除所有在當前時間(如果已經過了釋放時間)之前具有釋放時間的黑名單條目:
/* I pass in time() */
DELETE FROM failures WHERE release_time < ?;
然后執行以下命令:
/* I pass in $_SERVER['REMOTE_ADDR'] */
SELECT failures FROM blacklist WHERE ip_address=?
如果我沒有檢索到任何行,或者如果我獲得的$ row ['failures']超過5,則允許檢查用戶名和密碼。 否則,我將完全拒絕登錄。
對於每次失敗的登錄嘗試(無論是通過黑名單規則還是通過無效的用戶名/密碼),我都將執行:
/* IP address is $_SERVER['REMOTE_ADDR'],
release_time is current time + (new failures * 90 minutes) */
INSERT INTO BLACKLIST(ip_address, failures, release_time) VALUES(?,?,?)
ON DUPLICATE KEY UPDATE failures=failures+1, release_time=?;
不幸的是,我至少打了3次數據庫(清除黑名單,獲取IP地址,增加故障最少)。 有沒有更好的方法來維護動態黑名單,也許每分鍾寫入一次緩存?
我確實看到用php / mysql進行IP禁止與我的問題類似,但是我允許人們在一段時間內停止嘗試登錄的情況下將他們從黑名單中刪除。 這樣,那些簡單地忘記了自己的憑據的人所受到的影響要比那些試圖強行獲取憑據的人受到的影響要小。
以下查詢不需要定期運行,可以移至cron作業:
DELETE FROM failures WHERE release_time < ?;
如果此人被列入黑名單,則此“布爾”查詢將返回1,否則返回0:
SELECT
COUNT(ip_address) as blacklisted
FROM blacklist
WHERE
ip_address = ? AND
release_time > ? AND
failures > 5
由於您不使用PHP對行進行計數和比較數字,因此可能會加快速度:
if ($row['blacklisted']) { /* ... */ }
我認為您真的無法避免最后一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.